- integrate most recent changes from vendor branch and upgrade to firmware revision 4.5.5

- add filter support
	- further improvements for T304
- recover gracefully from spurious immediate packets

Approved by: re(blanket)
Supported by: Chelsio
MFC after: 3 days
This commit is contained in:
Kip Macy 2007-07-17 06:50:35 +00:00
parent 8870f0e16b
commit ac3a6d9cef
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=171471
20 changed files with 1497 additions and 697 deletions

View File

@ -38,8 +38,6 @@ $FreeBSD$
#endif
enum {
MAX_NPORTS = 4,
TP_TMR_RES = 200, /* TP timer resolution in usec */
MAX_FRAME_SIZE = 10240, /* max MAC frame size, includes header + FCS */
EEPROMSIZE = 8192, /* Serial EEPROM size */
RSS_TABLE_SIZE = 64, /* size of RSS lookup and mapping tables */
@ -48,6 +46,10 @@ enum {
NCCTRL_WIN = 32, /* # of congestion control windows */
NTX_SCHED = 8, /* # of HW Tx scheduling queues */
PROTO_SRAM_LINES = 128, /* size of protocol sram */
MAX_NPORTS = 4,
TP_TMR_RES = 200,
TP_SRAM_OFFSET = 4096, /* TP SRAM content offset in eeprom */
TP_SRAM_LEN = 2112, /* TP SRAM content offset in eeprom */
};
#define MAX_RX_COALESCING_LEN 12288U
@ -72,8 +74,8 @@ enum { /* adapter interrupt-maintained statistics */
enum {
TP_VERSION_MAJOR = 1,
TP_VERSION_MINOR = 0,
TP_VERSION_MICRO = 44
TP_VERSION_MINOR = 1,
TP_VERSION_MICRO = 0
};
#define S_TP_VERSION_MAJOR 16
@ -96,7 +98,7 @@ enum {
enum {
FW_VERSION_MAJOR = 4,
FW_VERSION_MINOR = 1,
FW_VERSION_MINOR = 5,
FW_VERSION_MICRO = 0
};
@ -393,6 +395,7 @@ enum { /* chip revisions */
T3_REV_A = 0,
T3_REV_B = 2,
T3_REV_B2 = 3,
T3_REV_C = 4,
};
struct trace_params {
@ -467,6 +470,7 @@ struct cmac {
unsigned int tx_xcnt;
u64 tx_mcnt;
unsigned int rx_xcnt;
unsigned int rx_ocnt;
u64 rx_mcnt;
unsigned int toggle_cnt;
unsigned int txen;
@ -562,6 +566,9 @@ static inline void cphy_init(struct cphy *phy, adapter_t *adapter,
/* Accumulate MAC statistics every 180 seconds. For 1G we multiply by 10. */
#define MAC_STATS_ACCUM_SECS 180
/* The external MAC needs accumulation every 30 seconds */
#define VSC_STATS_ACCUM_SECS 30
#define XGM_REG(reg_addr, idx) \
((reg_addr) + (idx) * (XGMAC0_1_BASE_ADDR - XGMAC0_0_BASE_ADDR))
@ -656,9 +663,10 @@ int t3_seeprom_write(adapter_t *adapter, u32 addr, u32 data);
int t3_seeprom_wp(adapter_t *adapter, int enable);
int t3_read_flash(adapter_t *adapter, unsigned int addr, unsigned int nwords,
u32 *data, int byte_oriented);
int t3_get_tp_version(adapter_t *adapter, u32 *vers);
int t3_check_tpsram_version(adapter_t *adapter);
int t3_check_tpsram(adapter_t *adapter, u8 *tp_ram, unsigned int size);
int t3_load_fw(adapter_t *adapter, const u8 *fw_data, unsigned int size);
int t3_check_tpsram(adapter_t *adapter, const u8 *tp_ram, unsigned int size);
int t3_load_fw(adapter_t *adapter, const const u8 *fw_data, unsigned int size);
int t3_get_fw_version(adapter_t *adapter, u32 *vers);
int t3_check_fw_version(adapter_t *adapter);
int t3_init_hw(adapter_t *adapter, u32 fw_params);
@ -668,10 +676,11 @@ int t3_prep_adapter(adapter_t *adapter, const struct adapter_info *ai, int reset
void t3_led_ready(adapter_t *adapter);
void t3_fatal_err(adapter_t *adapter);
void t3_set_vlan_accel(adapter_t *adapter, unsigned int ports, int on);
void t3_enable_filters(adapter_t *adap);
void t3_config_rss(adapter_t *adapter, unsigned int rss_config, const u8 *cpus,
const u16 *rspq);
int t3_read_rss(adapter_t *adapter, u8 *lkup, u16 *map);
int t3_set_proto_sram(adapter_t *adap, u8 *data);
int t3_set_proto_sram(adapter_t *adap, const u8 *data);
int t3_mps_set_active_ports(adapter_t *adap, unsigned int port_mask);
void t3_port_failover(adapter_t *adapter, int port);
void t3_failover_done(adapter_t *adapter, int port);
@ -753,8 +762,8 @@ int t3_elmr_blk_write(adapter_t *adap, int start, const u32 *vals, int n);
int t3_elmr_blk_read(adapter_t *adap, int start, u32 *vals, int n);
int t3_vsc7323_init(adapter_t *adap, int nports);
int t3_vsc7323_set_speed_fc(adapter_t *adap, int speed, int fc, int port);
int t3_vsc7323_set_addr(adapter_t *adap, u8 addr[6], int port);
int t3_vsc7323_set_mtu(adapter_t *adap, unsigned int mtu, int port);
int t3_vsc7323_set_addr(adapter_t *adap, u8 addr[6], int port);
int t3_vsc7323_enable(adapter_t *adap, int port, int which);
int t3_vsc7323_disable(adapter_t *adap, int port, int which);
const struct mac_stats *t3_vsc7323_update_stats(struct cmac *mac);

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2007 Chelsio Communications. All rights reserved.
* Copyright (C) 2003-2006 Chelsio Communications. All rights reserved.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
@ -12,7 +12,6 @@
#ifndef _CXGB3_OFFLOAD_CTL_DEFS_H
#define _CXGB3_OFFLOAD_CTL_DEFS_H
enum {
GET_MAX_OUTSTANDING_WR,
GET_TX_MAX_CHUNK,
@ -25,9 +24,6 @@ enum {
GET_IFF_FROM_MAC,
GET_DDP_PARAMS,
GET_PORTS,
FAILOVER,
FAILOVER_DONE,
FAILOVER_CLEAR,
ULP_ISCSI_GET_PARAMS,
ULP_ISCSI_SET_PARAMS,
@ -38,6 +34,14 @@ enum {
RDMA_CQ_DISABLE,
RDMA_CTRL_QP_SETUP,
RDMA_GET_MEM,
FAILOVER,
FAILOVER_DONE,
FAILOVER_CLEAR,
GET_CPUIDX_OF_QSET,
GET_RX_PAGE_INFO,
};
/*
@ -81,7 +85,7 @@ struct ddp_params {
struct adap_ports {
unsigned int nports; /* number of ports on this adapter */
struct ifnet *lldevs[4];
struct net_device *lldevs[2];
};
/*
@ -101,6 +105,14 @@ struct ulp_iscsi_info {
struct pci_dev *pdev;
};
/*
* Offload TX/RX page information.
*/
struct ofld_page_info {
unsigned int page_size; /* Page size, should be a power of 2 */
unsigned int num; /* Number of pages */
};
/*
* Structure used to return information to the RDMA layer.
*/

View File

@ -165,16 +165,26 @@ static int init_mask_data_array(struct mc5 *mc5, u32 mask_array_base,
return -1;
/* Initialize the mask array. */
dbgi_wr_data3(adap, 0xffffffff, 0xffffffff, 0xff);
for (i = 0; i < size72; i++) {
if (i == server_base) /* entering server or routing region */
t3_write_reg(adap, A_MC5_DB_DBGI_REQ_DATA0,
mc5->mode == MC5_MODE_144_BIT ?
0xfffffff9 : 0xfffffffd);
for (i = 0; i < server_base; i++) {
dbgi_wr_data3(adap, 0x3fffffff, 0xfff80000, 0xff);
if (mc5_write(adap, mask_array_base + (i << addr_shift),
write_cmd))
return -1;
i++;
dbgi_wr_data3(adap, 0xffffffff, 0xffffffff, 0xff);
if (mc5_write(adap, mask_array_base + (i << addr_shift),
write_cmd))
return -1;
}
dbgi_wr_data3(adap,
mc5->mode == MC5_MODE_144_BIT ? 0xfffffff9 : 0xfffffffd,
0xffffffff, 0xff);
for (; i < size72; i++)
if (mc5_write(adap, mask_array_base + (i << addr_shift),
write_cmd))
return -1;
return 0;
}
@ -305,17 +315,15 @@ static int init_idt43102(struct mc5 *mc5)
/* Put MC5 in DBGI mode. */
static inline void mc5_dbgi_mode_enable(const struct mc5 *mc5)
{
t3_write_reg(mc5->adapter, A_MC5_DB_CONFIG,
V_TMMODE(mc5->mode == MC5_MODE_72_BIT) | F_DBGIEN);
t3_set_reg_field(mc5->adapter, A_MC5_DB_CONFIG, F_PRTYEN | F_MBUSEN,
F_DBGIEN);
}
/* Put MC5 in M-Bus mode. */
static void mc5_dbgi_mode_disable(const struct mc5 *mc5)
{
t3_write_reg(mc5->adapter, A_MC5_DB_CONFIG,
V_TMMODE(mc5->mode == MC5_MODE_72_BIT) |
V_COMPEN(mc5->mode == MC5_MODE_72_BIT) |
V_PRTYEN(mc5->parity_enabled) | F_MBUSEN);
t3_set_reg_field(mc5->adapter, A_MC5_DB_CONFIG, F_DBGIEN,
V_PRTYEN(mc5->parity_enabled) | F_MBUSEN);
}
/*
@ -325,9 +333,9 @@ static void mc5_dbgi_mode_disable(const struct mc5 *mc5)
int t3_mc5_init(struct mc5 *mc5, unsigned int nservers, unsigned int nfilters,
unsigned int nroutes)
{
u32 cfg;
int err;
unsigned int tcam_size = mc5->tcam_size;
unsigned int mode72 = mc5->mode == MC5_MODE_72_BIT;
adapter_t *adap = mc5->adapter;
if (!tcam_size)
@ -336,10 +344,12 @@ int t3_mc5_init(struct mc5 *mc5, unsigned int nservers, unsigned int nfilters,
if (nroutes > MAX_ROUTES || nroutes + nservers + nfilters > tcam_size)
return -EINVAL;
if (nfilters && adap->params.rev < T3_REV_C)
mc5->parity_enabled = 0;
/* Reset the TCAM */
cfg = t3_read_reg(adap, A_MC5_DB_CONFIG) & ~F_TMMODE;
cfg |= V_TMMODE(mc5->mode == MC5_MODE_72_BIT) | F_TMRST;
t3_write_reg(adap, A_MC5_DB_CONFIG, cfg);
t3_set_reg_field(adap, A_MC5_DB_CONFIG, F_TMMODE | F_COMPEN,
V_COMPEN(mode72) | V_TMMODE(mode72) | F_TMRST);
if (t3_wait_op_done(adap, A_MC5_DB_CONFIG, F_TMRDY, 1, 500, 0)) {
CH_ERR(adap, "TCAM reset timed out\n");
return -1;
@ -351,8 +361,6 @@ int t3_mc5_init(struct mc5 *mc5, unsigned int nservers, unsigned int nfilters,
t3_write_reg(adap, A_MC5_DB_SERVER_INDEX,
tcam_size - nroutes - nfilters - nservers);
mc5->parity_enabled = 1;
/* All the TCAM addresses we access have only the low 32 bits non 0 */
t3_write_reg(adap, A_MC5_DB_DBGI_REQ_ADDR1, 0);
t3_write_reg(adap, A_MC5_DB_DBGI_REQ_ADDR2, 0);
@ -467,6 +475,7 @@ void __devinit t3_mc5_prep(adapter_t *adapter, struct mc5 *mc5, int mode)
u32 cfg = t3_read_reg(adapter, A_MC5_DB_CONFIG);
mc5->adapter = adapter;
mc5->parity_enabled = 1;
mc5->mode = (unsigned char) mode;
mc5->part_type = (unsigned char) G_TMTYPE(cfg);
if (cfg & F_TMTYPEHI)

View File

@ -31,10 +31,6 @@ $FreeBSD$
#ifndef T3_CPL_H
#define T3_CPL_H
#if !defined(__LITTLE_ENDIAN_BITFIELD) && !defined(__BIG_ENDIAN_BITFIELD)
# include <asm/byteorder.h>
#endif
enum CPL_opcode {
CPL_PASS_OPEN_REQ = 0x1,
CPL_PASS_ACCEPT_RPL = 0x2,
@ -133,6 +129,7 @@ enum CPL_error {
enum {
CPL_CONN_POLICY_AUTO = 0,
CPL_CONN_POLICY_ASK = 1,
CPL_CONN_POLICY_FILTER = 2,
CPL_CONN_POLICY_DENY = 3
};
@ -259,16 +256,16 @@ struct work_request_hdr {
/* Applicable to BYPASS WRs only: the uP will added a CPL_BARRIER before
* and after the BYPASS WR if the ATOMIC bit is set.
*/
#define S_WR_ATOMIC 16
#define V_WR_ATOMIC(x) ((x) << S_WR_ATOMIC)
#define F_WR_ATOMIC V_WR_ATOMIC(1U)
#define S_WR_ATOMIC 16
#define V_WR_ATOMIC(x) ((x) << S_WR_ATOMIC)
#define F_WR_ATOMIC V_WR_ATOMIC(1U)
/* Applicable to BYPASS WRs only: the uP will flush buffered non abort
* related WRs.
*/
#define S_WR_FLUSH 17
#define V_WR_FLUSH(x) ((x) << S_WR_FLUSH)
#define F_WR_FLUSH V_WR_FLUSH(1U)
#define S_WR_FLUSH 17
#define V_WR_FLUSH(x) ((x) << S_WR_FLUSH)
#define F_WR_FLUSH V_WR_FLUSH(1U)
#define S_WR_DATATYPE 20
#define V_WR_DATATYPE(x) ((x) << S_WR_DATATYPE)
@ -415,6 +412,11 @@ struct work_request_hdr {
#define V_CPU_IDX(x) ((x) << S_CPU_IDX)
#define G_CPU_IDX(x) (((x) >> S_CPU_IDX) & M_CPU_IDX)
#define S_OPT1_VLAN 6
#define M_OPT1_VLAN 0xFFF
#define V_OPT1_VLAN(x) ((x) << S_OPT1_VLAN)
#define G_OPT1_VLAN(x) (((x) >> S_OPT1_VLAN) & M_OPT1_VLAN)
#define S_MAC_MATCH_VALID 18
#define V_MAC_MATCH_VALID(x) ((x) << S_MAC_MATCH_VALID)
#define F_MAC_MATCH_VALID V_MAC_MATCH_VALID(1U)
@ -808,6 +810,12 @@ struct tx_data_wr {
__be32 param;
};
/* tx_data_wr.flags fields */
#define S_TX_ACK_PAGES 21
#define M_TX_ACK_PAGES 0x7
#define V_TX_ACK_PAGES(x) ((x) << S_TX_ACK_PAGES)
#define G_TX_ACK_PAGES(x) (((x) >> S_TX_ACK_PAGES) & M_TX_ACK_PAGES)
/* tx_data_wr.param fields */
#define S_TX_PORT 0
#define M_TX_PORT 0x7
@ -1009,7 +1017,7 @@ struct cpl_rx_data_ddp {
union {
__be32 nxt_seq;
__be32 ddp_report;
} __U;
} u;
__be32 ulp_crc;
__be32 ddpvld_status;
};
@ -1515,7 +1523,7 @@ struct ulp_mem_io {
__be32 len;
};
/* ulp_mem_io.cmd_lock_addr fields */
/* ulp_mem_io.cmd_lock_addr fields */
#define S_ULP_MEMIO_ADDR 0
#define M_ULP_MEMIO_ADDR 0x7FFFFFF
#define V_ULP_MEMIO_ADDR(x) ((x) << S_ULP_MEMIO_ADDR)
@ -1524,7 +1532,7 @@ struct ulp_mem_io {
#define V_ULP_MEMIO_LOCK(x) ((x) << S_ULP_MEMIO_LOCK)
#define F_ULP_MEMIO_LOCK V_ULP_MEMIO_LOCK(1U)
/* ulp_mem_io.len fields */
/* ulp_mem_io.len fields */
#define S_ULP_MEMIO_DATA_LEN 28
#define M_ULP_MEMIO_DATA_LEN 0xF
#define V_ULP_MEMIO_DATA_LEN(x) ((x) << S_ULP_MEMIO_DATA_LEN)
@ -1534,7 +1542,7 @@ struct ulp_txpkt {
__be32 len;
};
/* ulp_txpkt.cmd_dest fields */
/* ulp_txpkt.cmd_dest fields */
#define S_ULP_TXPKT_DEST 24
#define M_ULP_TXPKT_DEST 0xF
#define V_ULP_TXPKT_DEST(x) ((x) << S_ULP_TXPKT_DEST)

View File

@ -37,8 +37,8 @@ __FBSDID("$FreeBSD$");
#include <dev/cxgb/cxgb_include.h>
#endif
#define DENTER() printf("entered %s\n", __FUNCTION__);
#define DEXIT() printf("exiting %s\n", __FUNCTION__);
#undef msleep
#define msleep t3_os_sleep
/**
@ -355,7 +355,7 @@ int t3_phy_reset(struct cphy *phy, int mmd, int wait)
return err;
ctl &= BMCR_RESET;
if (ctl)
t3_os_sleep(1);
msleep(1);
} while (ctl && --wait);
return ctl ? -1 : 0;
@ -482,7 +482,7 @@ const struct adapter_info *t3_get_adapter_info(unsigned int id)
#define CAPS_10G (SUPPORTED_10000baseT_Full | SUPPORTED_AUI)
static struct port_type_info port_types[] = {
{ NULL, 0, NULL },
{ NULL },
{ t3_ael1002_phy_prep, CAPS_10G | SUPPORTED_FIBRE,
"10GBASE-XR" },
{ t3_vsc8211_phy_prep, CAPS_1G | SUPPORTED_TP | SUPPORTED_IRQ,
@ -594,7 +594,7 @@ int t3_seeprom_write(adapter_t *adapter, u32 addr, u32 data)
t3_os_pci_write_config_2(adapter, base + PCI_VPD_ADDR,
(u16)addr | PCI_VPD_ADDR_F);
do {
t3_os_sleep(1);
msleep(1);
t3_os_pci_read_config_2(adapter, base + PCI_VPD_ADDR, &val);
} while ((val & PCI_VPD_ADDR_F) && --attempts);
@ -770,7 +770,7 @@ static int flash_wait_op(adapter_t *adapter, int attempts, int delay)
if (--attempts == 0)
return -EAGAIN;
if (delay)
t3_os_sleep(delay);
msleep(delay);
}
}
@ -859,11 +859,33 @@ static int t3_write_flash(adapter_t *adapter, unsigned int addr,
return 0;
}
/**
* t3_get_tp_version - read the tp sram version
* @adapter: the adapter
* @vers: where to place the version
*
* Reads the protocol sram version from sram.
*/
int t3_get_tp_version(adapter_t *adapter, u32 *vers)
{
int ret;
/* Get version loaded in SRAM */
t3_write_reg(adapter, A_TP_EMBED_OP_FIELD0, 0);
ret = t3_wait_op_done(adapter, A_TP_EMBED_OP_FIELD0,
1, 1, 5, 1);
if (ret)
return ret;
*vers = t3_read_reg(adapter, A_TP_EMBED_OP_FIELD1);
return 0;
}
/**
* t3_check_tpsram_version - read the tp sram version
* @adapter: the adapter
*
* Reads the protocol sram version from serial eeprom.
*/
int t3_check_tpsram_version(adapter_t *adapter)
{
@ -886,6 +908,9 @@ int t3_check_tpsram_version(adapter_t *adapter)
if (major == TP_VERSION_MAJOR && minor == TP_VERSION_MINOR)
return 0;
CH_ERR(adapter, "found wrong TP version (%u.%u), "
"driver needs version %d.%d\n", major, minor,
TP_VERSION_MAJOR, TP_VERSION_MINOR);
return -EINVAL;
}
@ -899,7 +924,7 @@ int t3_check_tpsram_version(adapter_t *adapter)
* Checks if an adapter's tp sram is compatible with the driver.
* Returns 0 if the versions are compatible, a negative error otherwise.
*/
int t3_check_tpsram(adapter_t *adapter, u8 *tp_sram, unsigned int size)
int t3_check_tpsram(adapter_t *adapter, const u8 *tp_sram, unsigned int size)
{
u32 csum;
unsigned int i;
@ -960,8 +985,8 @@ int t3_check_fw_version(adapter_t *adapter)
return 0;
CH_ERR(adapter, "found wrong FW version (%u.%u), "
"driver needs version %d.%d\n", major, minor,
FW_VERSION_MAJOR, FW_VERSION_MINOR);
"driver needs version %d.%d\n", major, minor,
FW_VERSION_MAJOR, FW_VERSION_MINOR);
return -EINVAL;
}
@ -2329,6 +2354,28 @@ void t3_tp_set_offload_mode(adapter_t *adap, int enable)
V_NICMODE(!enable));
}
static void tp_wr_bits_indirect(adapter_t *adap, unsigned int addr,
unsigned int mask, unsigned int val)
{
t3_write_reg(adap, A_TP_PIO_ADDR, addr);
val |= t3_read_reg(adap, A_TP_PIO_DATA) & ~mask;
t3_write_reg(adap, A_TP_PIO_DATA, val);
}
/**
* t3_enable_filters - enable the HW filters
* @adap: the adapter
*
* Enables the HW filters for NIC traffic.
*/
void t3_enable_filters(adapter_t *adap)
{
t3_set_reg_field(adap, A_TP_IN_CONFIG, F_NICMODE, 0);
t3_set_reg_field(adap, A_MC5_DB_CONFIG, 0, F_FILTEREN);
t3_set_reg_field(adap, A_TP_GLOBAL_CONFIG, 0, V_FIVETUPLELOOKUP(3));
tp_wr_bits_indirect(adap, A_TP_INGRESS_CONFIG, 0, F_LOOKUPEVERYPKT);
}
/**
* pm_num_pages - calculate the number of pages of the payload memory
* @mem_size: the size of the payload memory
@ -2422,14 +2469,6 @@ static inline void tp_wr_indirect(adapter_t *adap, unsigned int addr, u32 val)
t3_write_reg(adap, A_TP_PIO_DATA, val);
}
static void tp_wr_bits_indirect(adapter_t *adap, unsigned int addr,
unsigned int mask, unsigned int val)
{
t3_write_reg(adap, A_TP_PIO_ADDR, addr);
val |= t3_read_reg(adap, A_TP_PIO_DATA) & ~mask;
t3_write_reg(adap, A_TP_PIO_DATA, val);
}
static void tp_config(adapter_t *adap, const struct tp_params *p)
{
t3_write_reg(adap, A_TP_GLOBAL_CONFIG, F_TXPACINGENABLE | F_PATHMTU |
@ -2459,10 +2498,12 @@ static void tp_config(adapter_t *adap, const struct tp_params *p)
if (adap->params.rev > 0) {
tp_wr_indirect(adap, A_TP_EGRESS_CONFIG, F_REWRITEFORCETOSIZE);
t3_set_reg_field(adap, A_TP_PARA_REG3, F_TXPACEAUTO,
F_TXPACEAUTO);
t3_set_reg_field(adap, A_TP_PARA_REG3, 0,
F_TXPACEAUTO | F_TXPACEAUTOSTRICT);
t3_set_reg_field(adap, A_TP_PC_CONFIG, F_LOCKTID, F_LOCKTID);
t3_set_reg_field(adap, A_TP_PARA_REG3, 0, F_TXPACEAUTOSTRICT);
tp_wr_indirect(adap, A_TP_VLAN_PRI_MAP, 0xfa50);
tp_wr_indirect(adap, A_TP_MAC_MATCH_MAP0, 0xfac688);
tp_wr_indirect(adap, A_TP_MAC_MATCH_MAP1, 0xfac688);
} else
t3_set_reg_field(adap, A_TP_PARA_REG3, 0, F_TXPACEFIXED);
@ -2816,17 +2857,17 @@ static void ulp_config(adapter_t *adap, const struct tp_params *p)
*
* Write the contents of the protocol SRAM.
*/
int t3_set_proto_sram(adapter_t *adap, u8 *data)
int t3_set_proto_sram(adapter_t *adap, const u8 *data)
{
int i;
u32 *buf = (u32 *)data;
u32 *buf = (u32 *)(uintptr_t)data;
for (i = 0; i < PROTO_SRAM_LINES; i++) {
t3_write_reg(adap, A_TP_EMBED_OP_FIELD5, htobe32(*buf++));
t3_write_reg(adap, A_TP_EMBED_OP_FIELD4, htobe32(*buf++));
t3_write_reg(adap, A_TP_EMBED_OP_FIELD3, htobe32(*buf++));
t3_write_reg(adap, A_TP_EMBED_OP_FIELD2, htobe32(*buf++));
t3_write_reg(adap, A_TP_EMBED_OP_FIELD1, htobe32(*buf++));
t3_write_reg(adap, A_TP_EMBED_OP_FIELD5, cpu_to_be32(*buf++));
t3_write_reg(adap, A_TP_EMBED_OP_FIELD4, cpu_to_be32(*buf++));
t3_write_reg(adap, A_TP_EMBED_OP_FIELD3, cpu_to_be32(*buf++));
t3_write_reg(adap, A_TP_EMBED_OP_FIELD2, cpu_to_be32(*buf++));
t3_write_reg(adap, A_TP_EMBED_OP_FIELD1, cpu_to_be32(*buf++));
t3_write_reg(adap, A_TP_EMBED_OP_FIELD0, i << 1 | 1 << 31);
if (t3_wait_op_done(adap, A_TP_EMBED_OP_FIELD0, 1, 1, 5, 1))
@ -3053,7 +3094,7 @@ static int calibrate_xgm(adapter_t *adapter)
for (i = 0; i < 5; ++i) {
t3_write_reg(adapter, A_XGM_XAUI_IMP, 0);
(void) t3_read_reg(adapter, A_XGM_XAUI_IMP);
t3_os_sleep(1);
msleep(1);
v = t3_read_reg(adapter, A_XGM_XAUI_IMP);
if (!(v & (F_XGM_CALFAULT | F_CALBUSY))) {
t3_write_reg(adapter, A_XGM_XAUI_IMP,
@ -3140,12 +3181,12 @@ static int mc7_init(struct mc7 *mc7, unsigned int mc7_clock, int mem_type)
t3_write_reg(adapter, mc7->offset + A_MC7_CFG, val | F_IFEN);
val = t3_read_reg(adapter, mc7->offset + A_MC7_CFG); /* flush */
t3_os_sleep(1);
msleep(1);
if (!slow) {
t3_write_reg(adapter, mc7->offset + A_MC7_CAL, F_SGL_CAL_EN);
(void) t3_read_reg(adapter, mc7->offset + A_MC7_CAL);
t3_os_sleep(1);
msleep(1);
if (t3_read_reg(adapter, mc7->offset + A_MC7_CAL) &
(F_BUSY | F_SGL_CAL_EN | F_CAL_FAULT)) {
CH_ERR(adapter, "%s MC7 calibration timed out\n",
@ -3211,7 +3252,7 @@ static int mc7_init(struct mc7 *mc7, unsigned int mc7_clock, int mem_type)
attempts = 50;
do {
t3_os_sleep(250);
msleep(250);
val = t3_read_reg(adapter, mc7->offset + A_MC7_BIST_OP);
} while ((val & F_BUSY) && --attempts);
if (val & F_BUSY) {
@ -3297,11 +3338,8 @@ int t3_init_hw(adapter_t *adapter, u32 fw_params)
else if (calibrate_xgm(adapter))
goto out_err;
if (adapter->params.nports > 2) {
if (adapter->params.nports > 2)
t3_mac_reset(&adap2pinfo(adapter, 0)->mac);
if ((err = t3_vsc7323_init(adapter, adapter->params.nports)))
goto out_err;
}
if (vpd->mclk) {
partition_mem(adapter, &adapter->params.tp);
@ -3341,7 +3379,7 @@ int t3_init_hw(adapter_t *adapter, u32 fw_params)
(void) t3_read_reg(adapter, A_CIM_BOOT_CFG); /* flush */
do { /* wait for uP to initialize */
t3_os_sleep(20);
msleep(20);
} while (t3_read_reg(adapter, A_CIM_HOST_ACC_DATA) && --attempts);
if (!attempts) {
CH_ERR(adapter, "uP initialization timed out\n");
@ -3453,7 +3491,6 @@ void mac_prep(struct cmac *mac, adapter_t *adapter, int index)
{
mac->adapter = adapter;
mac->multiport = adapter->params.nports > 2;
if (mac->multiport) {
mac->ext_port = (unsigned char)index;
mac->nucast = 8;
@ -3516,7 +3553,7 @@ static int t3_reset_adapter(adapter_t *adapter)
* XXX The delay time should be modified.
*/
for (i = 0; i < 10; i++) {
t3_os_sleep(50);
msleep(50);
t3_os_pci_read_config_2(adapter, 0x00, &devid);
if (devid == 0x1425)
break;
@ -3548,16 +3585,18 @@ int __devinit t3_prep_adapter(adapter_t *adapter,
adapter->params.chan_map = !!ai->nports0 | (!!ai->nports1 << 1);
adapter->params.rev = t3_read_reg(adapter, A_PL_REV);
adapter->params.linkpoll_period = 0;
adapter->params.stats_update_period = is_10G(adapter) ?
MAC_STATS_ACCUM_SECS : (MAC_STATS_ACCUM_SECS * 10);
if (adapter->params.nports > 2)
adapter->params.stats_update_period = VSC_STATS_ACCUM_SECS;
else
adapter->params.stats_update_period = is_10G(adapter) ?
MAC_STATS_ACCUM_SECS : (MAC_STATS_ACCUM_SECS * 10);
adapter->params.pci.vpd_cap_addr =
t3_os_find_pci_capability(adapter, PCI_CAP_ID_VPD);
ret = get_vpd_params(adapter, &adapter->params.vpd);
if (ret < 0) {
printf("failed to get VPD params\n");
if (ret < 0)
return ret;
}
if (reset && t3_reset_adapter(adapter))
return -1;
@ -3606,24 +3645,18 @@ int __devinit t3_prep_adapter(adapter_t *adapter,
early_hw_init(adapter, ai);
if (adapter->params.nports > 2 &&
(ret = t3_vsc7323_init(adapter, adapter->params.nports)))
return ret;
for_each_port(adapter, i) {
u8 hw_addr[6];
struct port_info *p = adap2pinfo(adapter, i);
while (adapter->params.vpd.port_type[j] == 0) {
while (!adapter->params.vpd.port_type[j])
++j;
}
if (adapter->params.vpd.port_type[j] > sizeof(port_types)/sizeof(port_types[0])) {
printf("bad port type idx=%d\n", adapter->params.vpd.port_type[j]);
printf("port types: ");
for (i = 0; i < j; i++)
printf("port[%d]=%d ", i, adapter->params.vpd.port_type[i]);
printf("\n");
return -1;
}
p->port_type = &port_types[adapter->params.vpd.port_type[j]];
p->port_type = &port_types[adapter->params.vpd.port_type[j]];
p->port_type->phy_prep(&p->phy, adapter, ai->phy_base_addr + j,
ai->mdio_ops);
mac_prep(&p->mac, adapter, j);

View File

@ -115,13 +115,16 @@ int t3_vsc7323_init(adapter_t *adap, int nports)
{ VSC_REG(2, 0, 0x2f), 0 },
{ VSC_REG(2, 0, 0xf), 0xa0010291 },
{ VSC_REG(2, 1, 0x2f), 1 },
{ VSC_REG(2, 1, 0xf), 0xa0026301 }
{ VSC_REG(2, 1, 0xf), 0xa026301 }
};
static struct addr_val_pair xg_avp[] = {
{ VSC_REG(1, 10, 0), 0x600b },
{ VSC_REG(1, 10, 2), 0x4000 },
{ VSC_REG(1, 10, 1), 0x70600 }, //QUANTA = 96*1024*8/512
{ VSC_REG(1, 10, 2), 0x2710 },
{ VSC_REG(1, 10, 5), 0x65 },
{ VSC_REG(1, 10, 7), 3 },
{ VSC_REG(1, 10, 7), 0x23 },
{ VSC_REG(1, 10, 0x23), 0x800007bf },
{ VSC_REG(1, 10, 0x23), 0x000007bf },
{ VSC_REG(1, 10, 0x23), 0x800007bf },
{ VSC_REG(1, 10, 0x24), 4 }
};
@ -130,10 +133,9 @@ int t3_vsc7323_init(adapter_t *adap, int nports)
for (i = 0; i < ARRAY_SIZE(sys_avp); i++)
if ((ret = t3_elmr_blk_write(adap, sys_avp[i].reg_addr,
&sys_avp[i].val, 1)))
&sys_avp[i].val, 1)))
return ret;
ing_step = 0xc0 / nports;
egr_step = 0x40 / nports;
ing_bot = egr_bot = 0;
@ -141,22 +143,27 @@ int t3_vsc7323_init(adapter_t *adap, int nports)
// egr_wm = egr_step * 64;
/* {ING,EGR}_CONTROL.CLR = 1 here */
for (i = 0; i < nports; i++)
if ((ret = elmr_write(adap, VSC_REG(2, 0, 0x10 + i),
for (i = 0; i < nports; i++) {
if (
(ret = elmr_write(adap, VSC_REG(2, 0, 0x10 + i),
((ing_bot + ing_step) << 16) | ing_bot)) ||
(ret = elmr_write(adap, VSC_REG(2, 0, 0x50 + i), 0)) ||
(ret = elmr_write(adap, VSC_REG(2, 0, 0x40 + i),
0x6000a00)) ||
(ret = elmr_write(adap, VSC_REG(2, 0, 0x50 + i), 1)) ||
(ret = elmr_write(adap, VSC_REG(2, 1, 0x10 + i),
((egr_bot + egr_step) << 16) | egr_bot)) ||
(ret = elmr_write(adap, VSC_REG(2, 1, 0x40 + i),
0x2000280)) ||
(ret = elmr_write(adap, VSC_REG(2, 1, 0x50 + i), 0)))
return ret;
ing_bot += ing_step;
egr_bot += egr_step;
}
for (i = 0; i < ARRAY_SIZE(fifo_avp); i++)
if ((ret = t3_elmr_blk_write(adap, fifo_avp[i].reg_addr,
&fifo_avp[i].val, 1)))
return ret;
&fifo_avp[i].val, 1)))
return ret;
for (i = 0; i < ARRAY_SIZE(xg_avp); i++)
if ((ret = t3_elmr_blk_write(adap, xg_avp[i].reg_addr,
@ -198,7 +205,7 @@ int t3_vsc7323_set_speed_fc(adapter_t *adap, int speed, int fc, int port)
return r;
}
r = (fc & PAUSE_RX) ? 0x6ffff : 0x2ffff;
r = (fc & PAUSE_RX) ? 0x60200 : 0x20200; //QUANTA = 32*1024*8/512
if (fc & PAUSE_TX)
r |= (1 << 19);
return elmr_write(adap, VSC_REG(1, port, 1), r);
@ -212,12 +219,12 @@ int t3_vsc7323_set_mtu(adapter_t *adap, unsigned int mtu, int port)
int t3_vsc7323_set_addr(adapter_t *adap, u8 addr[6], int port)
{
int ret;
ret = elmr_write(adap, VSC_REG(1, port, 3),
(addr[0] << 16) | (addr[1] << 8) | addr[2]);
(addr[0] << 16) | (addr[1] << 8) | addr[2]);
if (!ret)
ret = elmr_write(adap, VSC_REG(1, port, 4),
(addr[3] << 16) | (addr[4] << 8) | addr[5]);
(addr[3] << 16) | (addr[4] << 8) | addr[5]);
return ret;
}

View File

@ -37,6 +37,9 @@ __FBSDID("$FreeBSD$");
#include <dev/cxgb/cxgb_include.h>
#endif
#undef msleep
#define msleep t3_os_sleep
/*
* # of exact address filters. The first one is used for the station address,
* the rest are available for multicast addresses.
@ -154,7 +157,7 @@ int t3_mac_reset(struct cmac *mac)
t3_write_reg(adap, A_XGM_RESET_CTRL + oft, val);
(void) t3_read_reg(adap, A_XGM_RESET_CTRL + oft); /* flush */
if ((val & F_PCS_RESET_) && adap->params.rev) {
t3_os_sleep(1);
msleep(1);
t3b_pcs_reset(mac);
}
@ -179,7 +182,7 @@ static int t3b2_mac_reset(struct cmac *mac)
t3_write_reg(adap, A_XGM_RESET_CTRL + oft, F_MAC_RESET_);
(void) t3_read_reg(adap, A_XGM_RESET_CTRL + oft); /* flush */
t3_os_sleep(10);
msleep(10);
/* Check for xgm Rx fifo empty */
if (t3_wait_op_done(adap, A_XGM_RX_MAX_PKT_SIZE_ERR_CNT + oft,
@ -202,7 +205,7 @@ static int t3b2_mac_reset(struct cmac *mac)
t3_write_reg(adap, A_XGM_RESET_CTRL + oft, val);
(void) t3_read_reg(adap, A_XGM_RESET_CTRL + oft); /* flush */
if ((val & F_PCS_RESET_) && adap->params.rev) {
t3_os_sleep(1);
msleep(1);
t3b_pcs_reset(mac);
}
t3_write_reg(adap, A_XGM_RX_CFG + oft,
@ -243,7 +246,6 @@ int t3_mac_set_address(struct cmac *mac, unsigned int idx, u8 addr[6])
set_addr_filter(mac, idx, addr);
if (mac->multiport && idx < mac->adapter->params.nports)
t3_vsc7323_set_addr(mac->adapter, addr, idx);
return 0;
}
@ -425,8 +427,17 @@ int t3_mac_set_speed_duplex_fc(struct cmac *mac, int speed, int duplex, int fc)
if (duplex >= 0 && duplex != DUPLEX_FULL)
return -EINVAL;
if (mac->multiport)
if (mac->multiport) {
val = t3_read_reg(adap, A_XGM_RXFIFO_CFG + oft);
val &= ~V_RXFIFOPAUSEHWM(M_RXFIFOPAUSEHWM);
val |= V_RXFIFOPAUSEHWM(rx_fifo_hwm(t3_read_reg(adap,
A_XGM_RX_MAX_PKT_SIZE + oft)) / 8);
t3_write_reg(adap, A_XGM_RXFIFO_CFG + oft, val);
t3_set_reg_field(adap, A_XGM_TX_CFG + oft, F_TXPAUSEEN,
F_TXPAUSEEN);
return t3_vsc7323_set_speed_fc(adap, speed, fc, mac->ext_port);
}
if (speed >= 0) {
if (speed == SPEED_10)
val = V_PORTSPEED(0);
@ -451,7 +462,7 @@ int t3_mac_set_speed_duplex_fc(struct cmac *mac, int speed, int duplex, int fc)
t3_write_reg(adap, A_XGM_RXFIFO_CFG + oft, val);
t3_set_reg_field(adap, A_XGM_TX_CFG + oft, F_TXPAUSEEN,
(fc & PAUSE_RX) ? F_TXPAUSEEN : 0);
(fc & PAUSE_RX) ? F_TXPAUSEEN : 0);
return 0;
}
@ -466,12 +477,13 @@ int t3_mac_enable(struct cmac *mac, int which)
return t3_vsc7323_enable(adap, mac->ext_port, which);
if (which & MAC_DIRECTION_TX) {
t3_write_reg(adap, A_XGM_TX_CTRL + oft, F_TXEN);
t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx);
t3_write_reg(adap, A_TP_PIO_DATA, 0xc0ede401);
t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_MODE);
t3_set_reg_field(adap, A_TP_PIO_DATA, 1 << idx, 1 << idx);
t3_write_reg(adap, A_XGM_TX_CTRL + oft, F_TXEN);
t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CNT_CH0 + idx);
mac->tx_mcnt = s->tx_frames;
mac->tx_tcnt = (G_TXDROPCNTCH0RCVD(t3_read_reg(adap,
@ -493,7 +505,6 @@ int t3_mac_enable(struct cmac *mac, int which)
int t3_mac_disable(struct cmac *mac, int which)
{
int idx = macidx(mac);
adapter_t *adap = mac->adapter;
int val;
@ -501,17 +512,14 @@ int t3_mac_disable(struct cmac *mac, int which)
return t3_vsc7323_disable(adap, mac->ext_port, which);
if (which & MAC_DIRECTION_TX) {
val = t3_read_reg(adap, A_MPS_CFG);
t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset, 0);
t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx);
t3_write_reg(adap, A_TP_PIO_DATA, 0xc000001f);
t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_MODE);
t3_set_reg_field(adap, A_TP_PIO_DATA, 1 << idx, 1 << idx);
mac->txen = 0;
}
if (which & MAC_DIRECTION_RX) {
t3_set_reg_field(mac->adapter, A_XGM_RESET_CTRL + mac->offset,
F_PCS_RESET_, 0);
t3_os_sleep(100);
msleep(100);
t3_write_reg(adap, A_XGM_RX_CTRL + mac->offset, 0);
val = F_MAC_RESET_;
if (is_10G(adap))
@ -535,6 +543,13 @@ int t3b2_mac_watchdog_task(struct cmac *mac)
unsigned int rx_mcnt = (unsigned int)s->rx_frames;
unsigned int rx_xcnt;
if (mac->multiport) {
tx_mcnt = t3_read_reg(adap, A_XGM_STAT_TX_FRAME_LOW);
rx_mcnt = t3_read_reg(adap, A_XGM_STAT_RX_FRAMES_LOW);
} else {
tx_mcnt = (unsigned int)s->tx_frames;
rx_mcnt = (unsigned int)s->rx_frames;
}
status = 0;
tx_xcnt = 1; /* By default tx_xcnt is making progress*/
tx_tcnt = mac->tx_tcnt; /* If tx_mcnt is progressing ignore tx_tcnt*/
@ -573,15 +588,18 @@ int t3b2_mac_watchdog_task(struct cmac *mac)
}
rxcheck:
if (rx_mcnt != mac->rx_mcnt)
if (rx_mcnt != mac->rx_mcnt) {
rx_xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap,
A_XGM_RX_SPI4_SOP_EOP_CNT +
mac->offset)));
else
mac->offset))) +
(s->rx_fifo_ovfl - mac->rx_ocnt);
mac->rx_ocnt = s->rx_fifo_ovfl;
} else
goto out;
if (mac->rx_mcnt != s->rx_frames && rx_xcnt == 0 && mac->rx_xcnt == 0) {
status = 2;
if (!mac->multiport)
status = 2;
goto out;
}
@ -622,6 +640,9 @@ const struct mac_stats *t3_mac_update_stats(struct cmac *mac)
u32 v, lo;
if (mac->multiport)
return t3_vsc7323_update_stats(mac);
RMON_UPDATE64(mac, rx_octets, RX_BYTES_LOW, RX_BYTES_HIGH);
RMON_UPDATE64(mac, rx_frames, RX_FRAMES_LOW, RX_FRAMES_HIGH);
RMON_UPDATE(mac, rx_mcast_frames, RX_MCAST_FRAMES);

View File

@ -138,6 +138,7 @@ enum { /* adapter flags */
USING_MSIX = (1 << 2),
QUEUES_BOUND = (1 << 3),
FW_UPTODATE = (1 << 4),
TPS_UPTODATE = (1 << 5),
};
@ -239,7 +240,7 @@ struct sge_fl {
struct tx_desc;
struct tx_sw_desc;
#define TXQ_TRANSMITTING 0x1
#define TXQ_TRANSMITTING 0x1
struct sge_txq {
uint64_t flags;
@ -301,6 +302,8 @@ struct sge {
struct mtx reg_lock;
};
struct filter_info;
struct adapter {
device_t dev;
int flags;
@ -331,7 +334,11 @@ struct adapter {
struct resource *msix_irq_res[SGE_QSETS];
int msix_irq_rid[SGE_QSETS];
void *msix_intr_tag[SGE_QSETS];
uint8_t rxpkt_map[8]; /* maps RX_PKT interface values to port ids */
uint8_t rrss_map[SGE_QSETS]; /* revers RSS map table */
struct filter_info *filters;
/* Tasks */
struct task ext_intr_task;
struct task slow_intr_task;

View File

@ -66,6 +66,7 @@ enum {
CH_SETMIIREGS,
CH_SET_FILTER,
CH_SET_HW_SCHED,
CH_DEL_FILTER,
};
struct ch_reg {
@ -130,6 +131,30 @@ struct ch_hw_sched {
int32_t flow_ipg; /* usec */
};
struct ch_filter_tuple {
uint32_t sip;
uint32_t dip;
uint16_t sport;
uint16_t dport;
uint16_t vlan:12;
uint16_t vlan_prio:3;
};
struct ch_filter {
uint32_t cmd;
uint32_t filter_id;
struct ch_filter_tuple val;
struct ch_filter_tuple mask;
uint16_t mac_addr_idx;
uint8_t mac_hit:1;
uint8_t proto:2;
uint8_t want_filter_id:1; /* report filter TID instead of RSS hash */
uint8_t pass:1; /* whether to pass or drop packets */
uint8_t rss:1; /* use RSS or specified qset */
uint8_t qset;
};
#ifndef TCB_SIZE
# define TCB_SIZE 128
#endif
@ -232,5 +257,7 @@ struct mii_data {
#define SIOCGMIIREG _IOWR('f', CH_GETMIIREGS, struct mii_data)
#define SIOCSMIIREG _IOWR('f', CH_SETMIIREGS, struct mii_data)
#define CHELSIO_SET_HW_SCHED _IOWR('f', CH_SET_HW_SCHED, struct ch_hw_sched)
#define CHELSIO_SET_FILTER _IOW('f', CH_SET_FILTER, struct ch_filter)
#define CHELSIO_DEL_FILTER _IOW('f', CH_DEL_FILTER, struct ch_filter)
#define CHELSIO_DEVUP _IO('f', CH_DEVUP)
#endif

View File

@ -225,6 +225,28 @@ enum {
MIN_FL_ENTRIES = 32
};
struct filter_info {
u32 sip;
u32 sip_mask;
u32 dip;
u16 sport;
u16 dport;
u32 vlan:12;
u32 vlan_prio:3;
u32 mac_hit:1;
u32 mac_idx:4;
u32 mac_vld:1;
u32 pkt_type:2;
u32 report_filter_id:1;
u32 pass:1;
u32 rss:1;
u32 qset:3;
u32 locked:1;
u32 valid:1;
};
enum { FILTER_NO_VLAN_PRI = 7 };
#define PORT_MASK ((1 << MAX_NPORTS) - 1)
/* Table for probing the cards. The desc field isn't actually used */
@ -248,6 +270,29 @@ struct cxgb_ident {
{0, 0, 0, NULL}
};
static int set_eeprom(struct port_info *pi, const uint8_t *data, int len, int offset);
static inline char
t3rev2char(struct adapter *adapter)
{
char rev = 'z';
switch(adapter->params.rev) {
case T3_REV_A:
rev = 'a';
break;
case T3_REV_B:
case T3_REV_B2:
rev = 'b';
break;
case T3_REV_C:
rev = 'c';
break;
}
return rev;
}
static struct cxgb_ident *
cxgb_get_ident(device_t dev)
{
@ -299,6 +344,10 @@ cxgb_controller_probe(device_t dev)
return (BUS_PROBE_DEFAULT);
}
#define FW_FNAME "t3fw%d%d%d"
#define TPEEPROM_NAME "t3%ctpe%d%d%d"
#define TPSRAM_NAME "t3%cps%d%d%d"
static int
upgrade_fw(adapter_t *sc)
{
@ -310,7 +359,7 @@ upgrade_fw(adapter_t *sc)
#endif
int status;
snprintf(&buf[0], sizeof(buf), "t3fw%d%d%d", FW_VERSION_MAJOR,
snprintf(&buf[0], sizeof(buf), FW_FNAME, FW_VERSION_MAJOR,
FW_VERSION_MINOR, FW_VERSION_MICRO);
fw = firmware_get(buf);
@ -318,9 +367,12 @@ upgrade_fw(adapter_t *sc)
if (fw == NULL) {
device_printf(sc->dev, "Could not find firmware image %s\n", buf);
return (ENOENT);
}
} else
device_printf(sc->dev, "updating firmware on card with %s\n", buf);
status = t3_load_fw(sc, (const uint8_t *)fw->data, fw->datasize);
device_printf(sc->dev, "firmware update returned %s %d\n", (status == 0) ? "success" : "fail", status);
firmware_put(fw, FIRMWARE_UNLOAD);
return (status);
@ -350,7 +402,10 @@ cxgb_controller_attach(device_t dev)
pectl = (pectl & ~0x7000) | (5 << 12);
pci_write_config(dev, reg + 0x8, pectl, 2);
}
if (sc->link_width != 0 && sc->link_width <= 4) {
ai = cxgb_get_adapter_info(dev);
if (sc->link_width != 0 && sc->link_width <= 4 &&
(ai->nports0 + ai->nports1) <= 2) {
device_printf(sc->dev,
"PCIe x%d Link, expect reduced performance\n",
sc->link_width);
@ -387,7 +442,6 @@ cxgb_controller_attach(device_t dev)
sc->bh = rman_get_bushandle(sc->regs_res);
sc->mmio_len = rman_get_size(sc->regs_res);
ai = cxgb_get_adapter_info(dev);
if (t3_prep_adapter(sc, ai, 1) < 0) {
printf("prep adapter failed\n");
error = ENODEV;
@ -475,6 +529,17 @@ cxgb_controller_attach(device_t dev)
} else {
sc->flags |= FW_UPTODATE;
}
if (t3_check_tpsram_version(sc) != 0) {
/*
* Warn user that a firmware update will be attempted in init.
*/
device_printf(dev, "SRAM needs to be updated to version %c-%d.%d.%d\n",
t3rev2char(sc), TP_VERSION_MAJOR, TP_VERSION_MINOR, TP_VERSION_MICRO);
sc->flags &= ~TPS_UPTODATE;
} else {
sc->flags |= TPS_UPTODATE;
}
if ((sc->flags & USING_MSIX) && !singleq)
port_qsets = min((SGE_QSETS/(sc)->params.nports), mp_ncpus);
@ -489,11 +554,11 @@ cxgb_controller_attach(device_t dev)
error = EINVAL;
goto out;
}
sc->portdev[i] = child;
sc->port[i].adapter = sc;
sc->port[i].nqsets = port_qsets;
sc->port[i].first_qset = i*port_qsets;
sc->port[i].port = i;
sc->portdev[i] = child;
device_set_softc(child, &sc->port[i]);
}
if ((error = bus_generic_attach(dev)) != 0)
@ -590,6 +655,7 @@ cxgb_free(struct adapter *sc)
}
#endif
t3_free_sge_resources(sc);
free(sc->filters, M_DEVBUF);
t3_sge_free(sc);
cxgb_offload_exit();
@ -606,6 +672,113 @@ cxgb_free(struct adapter *sc)
return;
}
static int
alloc_filters(struct adapter *adap)
{
struct filter_info *p;
int nfilters;
if ((nfilters = adap->params.mc5.nfilters) == 0)
return (0);
adap->filters = malloc(nfilters*sizeof(struct filter_info),
M_DEVBUF, M_ZERO|M_WAITOK);
if (adap->filters == NULL)
return (ENOMEM);
/* Set the default filters, only need to set non-0 fields here. */
p = &adap->filters[nfilters - 1];
p->vlan = 0xfff;
p->vlan_prio = FILTER_NO_VLAN_PRI;
p->pass = p->rss = p->valid = p->locked = 1;
return (0);
}
static inline void
set_tcb_field_ulp(struct cpl_set_tcb_field *req,
unsigned int tid, unsigned int word,
uint64_t mask, uint64_t val)
{
struct ulp_txpkt *txpkt = (struct ulp_txpkt *)req;
txpkt->cmd_dest = htonl(V_ULPTX_CMD(ULP_TXPKT));
txpkt->len = htonl(V_ULPTX_NFLITS(sizeof(*req) / 8));
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SET_TCB_FIELD, tid));
req->reply = V_NO_REPLY(1);
req->cpu_idx = 0;
req->word = htons(word);
req->mask = htobe64(mask);
req->val = htobe64(val);
}
static int
set_filter(struct adapter *adap, int id, const struct filter_info *f)
{
int len;
struct mbuf *m;
struct ulp_txpkt *txpkt;
struct work_request_hdr *wr;
struct cpl_pass_open_req *oreq;
struct cpl_set_tcb_field *sreq;
len = sizeof(*wr) + sizeof(*oreq) + 2 * sizeof(*sreq);
id += t3_mc5_size(&adap->mc5) - adap->params.mc5.nroutes -
adap->params.mc5.nfilters;
m = m_gethdr(M_TRYWAIT, MT_DATA);
wr = mtod(m, struct work_request_hdr *);
wr->wr_hi = htonl(V_WR_OP(FW_WROPCODE_BYPASS) | F_WR_ATOMIC);
m->m_len = m->m_pkthdr.len = len;
oreq = (struct cpl_pass_open_req *)(wr + 1);
txpkt = (struct ulp_txpkt *)oreq;
txpkt->cmd_dest = htonl(V_ULPTX_CMD(ULP_TXPKT));
txpkt->len = htonl(V_ULPTX_NFLITS(sizeof(*oreq) / 8));
OPCODE_TID(oreq) = htonl(MK_OPCODE_TID(CPL_PASS_OPEN_REQ, id));
oreq->local_port = htons(f->dport);
oreq->peer_port = htons(f->sport);
oreq->local_ip = htonl(f->dip);
oreq->peer_ip = htonl(f->sip);
oreq->peer_netmask = htonl(f->sip_mask);
oreq->opt0h = 0;
oreq->opt0l = htonl(F_NO_OFFLOAD);
oreq->opt1 = htonl(V_MAC_MATCH_VALID(f->mac_vld) |
V_CONN_POLICY(CPL_CONN_POLICY_FILTER) |
V_VLAN_PRI(f->vlan_prio >> 1) |
V_VLAN_PRI_VALID(f->vlan_prio != FILTER_NO_VLAN_PRI) |
V_PKT_TYPE(f->pkt_type) | V_OPT1_VLAN(f->vlan) |
V_MAC_MATCH(f->mac_idx | (f->mac_hit << 4)));
sreq = (struct cpl_set_tcb_field *)(oreq + 1);
set_tcb_field_ulp(sreq, id, 1, 0x1800808000ULL,
(f->report_filter_id << 15) | (1 << 23) |
((u64)f->pass << 35) | ((u64)!f->rss << 36));
set_tcb_field_ulp(sreq + 1, id, 25, 0x3f80000,
(u64)adap->rrss_map[f->qset] << 19);
t3_mgmt_tx(adap, m);
return 0;
}
static int
setup_hw_filters(struct adapter *adap)
{
int i, err;
if (adap->filters == NULL)
return 0;
t3_enable_filters(adap);
for (i = err = 0; i < adap->params.mc5.nfilters && !err; i++)
if (adap->filters[i].locked)
err = set_filter(adap, i, &adap->filters[i]);
return err;
}
/**
* setup_sge_qsets - configure SGE Tx/Rx/response queues
* @sc: the controller softc
@ -807,11 +980,21 @@ cxgb_port_attach(device_t dev)
ifp->if_capabilities |= CXGB_CAP;
ifp->if_capenable |= CXGB_CAP_ENABLE;
ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP | CSUM_IP | CSUM_TSO);
/*
* disable TSO on 4-port - it isn't supported by the firmware yet
*/
if (p->adapter->params.nports > 2) {
ifp->if_capabilities &= ~(IFCAP_TSO4 | IFCAP_TSO6);
ifp->if_capenable &= ~(IFCAP_TSO4 | IFCAP_TSO6);
ifp->if_hwassist &= ~CSUM_TSO;
}
ether_ifattach(ifp, p->hw_addr);
#ifdef DEFAULT_JUMBO
ifp->if_mtu = 9000;
#endif
/*
* Only default to jumbo frames on 10GigE
*/
if (p->adapter->params.nports <= 2)
ifp->if_mtu = 9000;
if ((err = cxgb_makedev(p)) != 0) {
printf("makedev failed %d\n", err);
return (err);
@ -1089,23 +1272,30 @@ static void
setup_rss(adapter_t *adap)
{
int i;
u_int nq0 = adap->port[0].nqsets;
u_int nq1 = max((u_int)adap->port[1].nqsets, 1U);
u_int nq[2];
uint8_t cpus[SGE_QSETS + 1];
uint16_t rspq_map[RSS_TABLE_SIZE];
nq[0] = adap->port[0].nqsets;
nq[1] = max((u_int)adap->port[1].nqsets, 1U);
for (i = 0; i < SGE_QSETS; ++i)
cpus[i] = i;
cpus[SGE_QSETS] = 0xff;
for (i = 0; i < RSS_TABLE_SIZE / 2; ++i) {
rspq_map[i] = i % nq0;
rspq_map[i + RSS_TABLE_SIZE / 2] = (i % nq1) + nq0;
rspq_map[i] = nq[0] ? i % nq[0] : 0;
rspq_map[i + RSS_TABLE_SIZE / 2] = nq[1] ? i % nq[1] + nq[0] : 0;
}
/* Calculate the reverse RSS map table */
for (i = 0; i < RSS_TABLE_SIZE; ++i)
if (adap->rrss_map[rspq_map[i]] == 0xff)
adap->rrss_map[rspq_map[i]] = i;
t3_config_rss(adap, F_RQFEEDBACKENABLE | F_TNLLKPEN | F_TNLMAPEN |
F_TNLPRTEN | F_TNL2TUPEN | F_TNL4TUPEN |
V_RRCPLCPUSIZE(6), cpus, rspq_map);
F_TNLPRTEN | F_TNL2TUPEN | F_TNL4TUPEN | F_OFDMAPEN |
F_RRCPLMAPEN | V_RRCPLCPUSIZE(6), cpus, rspq_map);
}
/*
@ -1175,7 +1365,7 @@ send_pktsched_cmd(struct adapter *adap, int sched, int qidx, int lo,
struct mbuf *m;
struct mngt_pktsched_wr *req;
m = m_gethdr(M_NOWAIT, MT_DATA);
m = m_gethdr(M_DONTWAIT, MT_DATA);
if (m) {
req = mtod(m, struct mngt_pktsched_wr *);
req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_MNGT));
@ -1204,6 +1394,101 @@ bind_qsets(adapter_t *sc)
}
}
static void
update_tpeeprom(struct adapter *adap)
{
const struct firmware *tpeeprom;
char buf[64];
uint32_t version;
unsigned int major, minor;
int ret, len;
char rev;
t3_seeprom_read(adap, TP_SRAM_OFFSET, &version);
major = G_TP_VERSION_MAJOR(version);
minor = G_TP_VERSION_MINOR(version);
if (major == TP_VERSION_MAJOR && minor == TP_VERSION_MINOR)
return;
rev = t3rev2char(adap);
snprintf(buf, sizeof(buf), TPEEPROM_NAME, rev,
TP_VERSION_MAJOR, TP_VERSION_MINOR, TP_VERSION_MICRO);
tpeeprom = firmware_get(buf);
if (tpeeprom == NULL) {
device_printf(adap->dev, "could not load TP EEPROM: unable to load %s\n",
buf);
return;
}
len = tpeeprom->datasize - 4;
ret = t3_check_tpsram(adap, tpeeprom->data, tpeeprom->datasize);
if (ret)
goto release_tpeeprom;
if (len != TP_SRAM_LEN) {
device_printf(adap->dev, "%s length is wrong len=%d expected=%d\n", buf, len, TP_SRAM_LEN);
return;
}
ret = set_eeprom(&adap->port[0], tpeeprom->data, tpeeprom->datasize,
TP_SRAM_OFFSET);
if (!ret) {
device_printf(adap->dev,
"Protocol SRAM image updated in EEPROM to %d.%d.%d\n",
TP_VERSION_MAJOR, TP_VERSION_MINOR, TP_VERSION_MICRO);
} else
device_printf(adap->dev, "Protocol SRAM image update in EEPROM failed\n");
release_tpeeprom:
firmware_put(tpeeprom, FIRMWARE_UNLOAD);
return;
}
static int
update_tpsram(struct adapter *adap)
{
const struct firmware *tpsram;
char buf[64];
int ret;
char rev;
rev = t3rev2char(adap);
if (!rev)
return 0;
update_tpeeprom(adap);
snprintf(buf, sizeof(buf), TPSRAM_NAME, rev,
TP_VERSION_MAJOR, TP_VERSION_MINOR, TP_VERSION_MICRO);
tpsram = firmware_get(buf);
if (tpsram == NULL){
device_printf(adap->dev, "could not load TP SRAM: unable to load %s\n",
buf);
return (EINVAL);
} else
device_printf(adap->dev, "updating TP SRAM with %s\n", buf);
ret = t3_check_tpsram(adap, tpsram->data, tpsram->datasize);
if (ret)
goto release_tpsram;
ret = t3_set_proto_sram(adap, tpsram->data);
if (ret)
device_printf(adap->dev, "loading protocol SRAM failed\n");
release_tpsram:
firmware_put(tpsram, FIRMWARE_UNLOAD);
return ret;
}
/**
* cxgb_up - enable the adapter
* @adap: adapter being enabled
@ -1221,11 +1506,11 @@ cxgb_up(struct adapter *sc)
if ((sc->flags & FULL_INIT_DONE) == 0) {
if ((sc->flags & FW_UPTODATE) == 0)
err = upgrade_fw(sc);
if (err)
goto out;
if ((err = upgrade_fw(sc)))
goto out;
if ((sc->flags & TPS_UPTODATE) == 0)
if ((err = update_tpsram(sc)))
goto out;
err = t3_init_hw(sc, 0);
if (err)
goto out;
@ -1236,6 +1521,7 @@ cxgb_up(struct adapter *sc)
if (err)
goto out;
alloc_filters(sc);
setup_rss(sc);
sc->flags |= FULL_INIT_DONE;
}
@ -1268,9 +1554,11 @@ cxgb_up(struct adapter *sc)
t3_sge_start(sc);
t3_intr_enable(sc);
if ((sc->flags & (USING_MSIX | QUEUES_BOUND)) == USING_MSIX)
if ((sc->flags & (USING_MSIX | QUEUES_BOUND)) == USING_MSIX) {
bind_qsets(sc);
sc->flags |= QUEUES_BOUND;
setup_hw_filters(sc);
sc->flags |= QUEUES_BOUND;
}
out:
return (err);
irq_err:
@ -1334,7 +1622,7 @@ offload_open(struct port_info *pi)
if (!adap_up)
err = cxgb_up(adapter);
ADAPTER_UNLOCK(pi->adapter);
if (err < 0)
if (err)
return (err);
t3_tp_set_offload_mode(adapter, 1);
@ -1407,7 +1695,7 @@ cxgb_init_locked(struct port_info *p)
ifp = p->ifp;
ADAPTER_LOCK(p->adapter);
if ((sc->open_device_map == 0) && ((err = cxgb_up(sc)) < 0)) {
if ((sc->open_device_map == 0) && (err = cxgb_up(sc))) {
ADAPTER_UNLOCK(p->adapter);
cxgb_stop_locked(p);
return;
@ -1866,10 +2154,170 @@ cxgb_tick_handler(void *arg, int count)
*/
ADAPTER_UNLOCK(sc);
if (p->rev == T3_REV_B2)
if (p->rev == T3_REV_B2 && p->nports < 4)
check_t3b2_mac(sc);
}
#if 0
static void *
filter_get_idx(struct seq_file *seq, loff_t pos)
{
int i;
struct adapter *adap = seq->private;
struct filter_info *p = adap->filters;
if (!p)
return NULL;
for (i = 0; i < adap->params.mc5.nfilters; i++, p++)
if (p->valid) {
if (!pos)
return p;
pos--;
}
return NULL;
}
static void *filter_get_nxt_idx(struct seq_file *seq, struct filter_info *p)
{
struct adapter *adap = seq->private;
struct filter_info *end = &adap->filters[adap->params.mc5.nfilters];
while (++p < end && !p->valid)
;
return p < end ? p : NULL;
}
static void *filter_seq_start(struct seq_file *seq, loff_t *pos)
{
return *pos ? filter_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
}
static void *filter_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
v = *pos ? filter_get_nxt_idx(seq, v) : filter_get_idx(seq, 0);
if (v)
++*pos;
return v;
}
static void filter_seq_stop(struct seq_file *seq, void *v)
{
}
static int filter_seq_show(struct seq_file *seq, void *v)
{
static const char *pkt_type[] = { "any", "tcp", "udp", "frag" };
if (v == SEQ_START_TOKEN)
seq_puts(seq, "index SIP DIP sport "
"dport VLAN PRI MAC type Q\n");
else {
char sip[20], dip[20];
struct filter_info *f = v;
struct adapter *adap = seq->private;
sprintf(sip, NIPQUAD_FMT "/%-2u", HIPQUAD(f->sip),
f->sip_mask ? 33 - ffs(f->sip_mask) : 0);
sprintf(dip, NIPQUAD_FMT, HIPQUAD(f->dip));
seq_printf(seq, "%5zu %18s %15s ", f - adap->filters, sip, dip);
seq_printf(seq, f->sport ? "%5u " : " * ", f->sport);
seq_printf(seq, f->dport ? "%5u " : " * ", f->dport);
seq_printf(seq, f->vlan != 0xfff ? "%4u " : " * ", f->vlan);
seq_printf(seq, f->vlan_prio == FILTER_NO_VLAN_PRI ?
" * " : "%1u/%1u ", f->vlan_prio, f->vlan_prio | 1);
if (!f->mac_vld)
seq_printf(seq, " * ");
else if (f->mac_hit)
seq_printf(seq, "%3u ", f->mac_idx);
else
seq_printf(seq, " -1 ");
seq_printf(seq, "%4s ", pkt_type[f->pkt_type]);
if (!f->pass)
seq_printf(seq, "-\n");
else if (f->rss)
seq_printf(seq, "*\n");
else
seq_printf(seq, "%1u\n", f->qset);
}
return 0;
}
static struct seq_operations filter_seq_ops = {
.start = filter_seq_start,
.next = filter_seq_next,
.stop = filter_seq_stop,
.show = filter_seq_show
};
static int filter_seq_open(struct inode *inode, struct file *file)
{
int rc = seq_open(file, &filter_seq_ops);
if (!rc) {
struct proc_dir_entry *dp = PDE(inode);
struct seq_file *seq = file->private_data;
seq->private = dp->data;
}
return rc;
}
static struct file_operations filter_seq_fops = {
.owner = THIS_MODULE,
.open = filter_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release
};
#endif
static int
set_eeprom(struct port_info *pi, const uint8_t *data, int len, int offset)
{
uint8_t *buf;
int err = 0;
u32 aligned_offset, aligned_len, *p;
struct adapter *adapter = pi->adapter;
aligned_offset = offset & ~3;
aligned_len = (len + (offset & 3) + 3) & ~3;
if (aligned_offset != offset || aligned_len != len) {
buf = malloc(aligned_len, M_DEVBUF, M_WAITOK|M_ZERO);
if (!buf)
return (ENOMEM);
err = t3_seeprom_read(adapter, aligned_offset, (u32 *)buf);
if (!err && aligned_len > 4)
err = t3_seeprom_read(adapter,
aligned_offset + aligned_len - 4,
(u32 *)&buf[aligned_len - 4]);
if (err)
goto out;
memcpy(buf + (offset & 3), data, len);
} else
buf = (uint8_t *)(uintptr_t)data;
err = t3_seeprom_wp(adapter, 0);
if (err)
goto out;
for (p = (u32 *)buf; !err && aligned_len; aligned_len -= 4, p++) {
err = t3_seeprom_write(adapter, aligned_offset, *p);
aligned_offset += 4;
}
if (!err)
err = t3_seeprom_wp(adapter, 1);
out:
if (buf != data)
free(buf, M_DEVBUF);
return err;
}
static int
in_range(int val, int lo, int hi)
{
@ -1923,7 +2371,7 @@ cxgb_extension_ioctl(struct cdev *dev, unsigned long cmd, caddr_t data,
if (!mmd)
mmd = MDIO_DEV_PCS;
else if (mmd > MDIO_DEV_XGXS)
return -EINVAL;
return (EINVAL);
error = phy->mdio_read(sc, mid->phy_id & 0x1f, mmd,
mid->reg_num, &val);
@ -2013,7 +2461,7 @@ cxgb_extension_ioctl(struct cdev *dev, unsigned long cmd, caddr_t data,
struct ch_qset_params *t = (struct ch_qset_params *)data;
if (t->qset_idx >= SGE_QSETS)
return -EINVAL;
return (EINVAL);
if (!in_range(t->intr_lat, 0, M_NEWTIMER) ||
!in_range(t->cong_thres, 0, 255) ||
!in_range(t->txq_size[0], MIN_TXQ_ENTRIES,
@ -2026,13 +2474,13 @@ cxgb_extension_ioctl(struct cdev *dev, unsigned long cmd, caddr_t data,
!in_range(t->fl_size[1], MIN_FL_ENTRIES,
MAX_RX_JUMBO_BUFFERS) ||
!in_range(t->rspq_size, MIN_RSPQ_ENTRIES, MAX_RSPQ_ENTRIES))
return -EINVAL;
return (EINVAL);
if ((sc->flags & FULL_INIT_DONE) &&
(t->rspq_size >= 0 || t->fl_size[0] >= 0 ||
t->fl_size[1] >= 0 || t->txq_size[0] >= 0 ||
t->txq_size[1] >= 0 || t->txq_size[2] >= 0 ||
t->polling >= 0 || t->cong_thres >= 0))
return -EBUSY;
return (EBUSY);
q = &sc->params.sge.qset[t->qset_idx];
@ -2141,6 +2589,79 @@ cxgb_extension_ioctl(struct cdev *dev, unsigned long cmd, caddr_t data,
memcpy(m->mtus, sc->params.mtus, sizeof(m->mtus));
m->nmtus = NMTUS;
break;
}
case CHELSIO_SET_FILTER: {
struct ch_filter *f = (struct ch_filter *)data;
struct filter_info *p;
int ret;
if (sc->params.mc5.nfilters == 0)
return (EOPNOTSUPP);
if (!(sc->flags & FULL_INIT_DONE))
return (EAGAIN); /* can still change nfilters */
if (sc->filters == NULL)
return (ENOMEM);
if (f->filter_id >= sc->params.mc5.nfilters ||
(f->val.dip && f->mask.dip != 0xffffffff) ||
(f->val.sport && f->mask.sport != 0xffff) ||
(f->val.dport && f->mask.dport != 0xffff) ||
(f->mask.vlan && f->mask.vlan != 0xfff) ||
(f->mask.vlan_prio && f->mask.vlan_prio != 7) ||
(f->mac_addr_idx != 0xffff && f->mac_addr_idx > 15) ||
f->qset >= SGE_QSETS ||
sc->rrss_map[f->qset] >= RSS_TABLE_SIZE)
return (EINVAL);
p = &sc->filters[f->filter_id];
if (p->locked)
return (EPERM);
p->sip = f->val.sip;
p->sip_mask = f->mask.sip;
p->dip = f->val.dip;
p->sport = f->val.sport;
p->dport = f->val.dport;
p->vlan = f->mask.vlan ? f->val.vlan : 0xfff;
p->vlan_prio = f->mask.vlan_prio ? (f->val.vlan_prio & 6) :
FILTER_NO_VLAN_PRI;
p->mac_hit = f->mac_hit;
p->mac_vld = f->mac_addr_idx != 0xffff;
p->mac_idx = f->mac_addr_idx;
p->pkt_type = f->proto;
p->report_filter_id = f->want_filter_id;
p->pass = f->pass;
p->rss = f->rss;
p->qset = f->qset;
ret = set_filter(sc, f->filter_id, p);
if (ret)
return ret;
p->valid = 1;
break;
}
case CHELSIO_DEL_FILTER: {
struct ch_filter *f = (struct ch_filter *)data;
struct filter_info *p;
if (sc->params.mc5.nfilters == 0)
return (EOPNOTSUPP);
if (!(sc->flags & FULL_INIT_DONE))
return (EAGAIN); /* can still change nfilters */
if (sc->filters == NULL)
return (ENOMEM);
if (f->filter_id >= sc->params.mc5.nfilters)
return (EINVAL);
p = &sc->filters[f->filter_id];
if (p->locked)
return (EPERM);
memset(p, 0, sizeof(*p));
p->sip_mask = 0xffffffff;
p->vlan = 0xfff;
p->vlan_prio = FILTER_NO_VLAN_PRI;
p->pkt_type = 1;
return set_filter(sc, f->filter_id, p);
}
case CHELSIO_DEVUP:
if (!is_offload(sc))
@ -2199,6 +2720,8 @@ cxgb_extension_ioctl(struct cdev *dev, unsigned long cmd, caddr_t data,
if (!is_offload(sc))
return (EOPNOTSUPP);
if (!(sc->flags & FULL_INIT_DONE))
return (EIO); /* need MC5 */
return -t3_read_mc5_range(&sc->mc5, t->addr, 1, t->buf);
break;
}

View File

@ -272,7 +272,7 @@ cxgb_ulp_iscsi_ctl(adapter_t *adapter, unsigned int req, void *data)
t3_write_reg(adapter, A_ULPRX_ISCSI_TAGMASK, uiip->tagmask);
break;
default:
ret = -EOPNOTSUPP;
ret = (EOPNOTSUPP);
}
return ret;
}
@ -315,7 +315,7 @@ cxgb_rdma_ctl(adapter_t *adapter, unsigned int req, void *data)
struct mc7 *mem;
if ((t->addr & 7) || (t->len & 7))
return -EINVAL;
return (EINVAL);
if (t->mem_id == MEM_CM)
mem = &adapter->cm;
else if (t->mem_id == MEM_PMRX)
@ -323,11 +323,11 @@ cxgb_rdma_ctl(adapter_t *adapter, unsigned int req, void *data)
else if (t->mem_id == MEM_PMTX)
mem = &adapter->pmtx;
else
return -EINVAL;
return (EINVAL);
ret = t3_mc7_bd_read(mem, t->addr/8, t->len/8, (u64 *)t->buf);
if (ret)
return ret;
return (ret);
break;
}
case RDMA_CQ_SETUP: {
@ -358,9 +358,9 @@ cxgb_rdma_ctl(adapter_t *adapter, unsigned int req, void *data)
break;
}
default:
ret = -EOPNOTSUPP;
ret = EOPNOTSUPP;
}
return ret;
return (ret);
}
static int
@ -439,7 +439,7 @@ cxgb_offload_ctl(struct toedev *tdev, unsigned int req, void *data)
case ULP_ISCSI_GET_PARAMS:
case ULP_ISCSI_SET_PARAMS:
if (!offload_running(adapter))
return -EAGAIN;
return (EAGAIN);
return cxgb_ulp_iscsi_ctl(adapter, req, data);
case RDMA_GET_PARAMS:
case RDMA_CQ_OP:
@ -448,10 +448,10 @@ cxgb_offload_ctl(struct toedev *tdev, unsigned int req, void *data)
case RDMA_CTRL_QP_SETUP:
case RDMA_GET_MEM:
if (!offload_running(adapter))
return -EAGAIN;
return (EAGAIN);
return cxgb_rdma_ctl(adapter, req, data);
default:
return -EOPNOTSUPP;
return (EOPNOTSUPP);
}
return 0;
}
@ -464,8 +464,8 @@ cxgb_offload_ctl(struct toedev *tdev, unsigned int req, void *data)
static int
rx_offload_blackhole(struct toedev *dev, struct mbuf **m, int n)
{
CH_ERR(tdev2adap(dev), "%d unexpected offload packets, first data %u\n",
n, ntohl(*mtod(m[0], uint32_t *)));
CH_ERR(tdev2adap(dev), "%d unexpected offload packets, first data 0x%x\n",
n, *mtod(m[0], uint32_t *));
while (n--)
m_freem(m[n]);
return 0;
@ -1308,7 +1308,7 @@ init_tid_tabs(struct tid_info *t, unsigned int ntids,
t->tid_tab = cxgb_alloc_mem(size);
if (!t->tid_tab)
return -ENOMEM;
return (ENOMEM);
t->stid_tab = (union listen_entry *)&t->tid_tab[ntids];
t->atid_tab = (union active_open_entry *)&t->stid_tab[nstids];
@ -1598,11 +1598,11 @@ offload_info_proc_setup(struct proc_dir_entry *dir,
struct proc_dir_entry *p;
if (!dir)
return -EINVAL;
return (EINVAL);
p = create_proc_read_entry("info", 0, dir, offload_info_read_proc, d);
if (!p)
return -ENOMEM;
return (ENOMEM);
p->owner = THIS_MODULE;
return 0;

View File

@ -10,11 +10,7 @@ modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the Chelsio Corporation nor the names of its
2. Neither the name of the Chelsio Corporation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

View File

@ -38,8 +38,13 @@ $FreeBSD$
#include <dev/mii/mii.h>
#ifdef CONFIG_DEFINED
#include <common/cxgb_version.h>
#include <cxgb_config.h>
#else
#include <dev/cxgb/common/cxgb_version.h>
#include <dev/cxgb/cxgb_config.h>
#endif
#ifndef _CXGB_OSDEP_H_
#define _CXGB_OSDEP_H_
@ -95,8 +100,16 @@ struct sge_rspq;
#define TX_MAX_SIZE (1 << 16) /* 64KB */
#define TX_MAX_SEGS 36 /* maximum supported by card */
#define TX_MAX_DESC 4 /* max descriptors per packet */
#define TX_START_MIN_DESC (TX_MAX_DESC << 2)
#if 0
#define TX_START_MAX_DESC (TX_ETH_Q_SIZE >> 2) /* maximum number of descriptors */
#endif
#define TX_START_MAX_DESC (TX_MAX_DESC << 3) /* maximum number of descriptors
* call to start used per */
#define TX_CLEAN_MAX_DESC (TX_MAX_DESC << 4) /* maximum tx descriptors
* to clean per iteration */
@ -159,6 +172,7 @@ static const int debug_flags = DBG_RX;
#define max_t(type, a, b) (type)max((a), (b))
#define net_device ifnet
#define cpu_to_be32 htobe32

View File

@ -69,7 +69,7 @@ uint32_t mb_free_vec_free = 0;
int txq_fills = 0;
int collapse_mbufs = 0;
static int recycle_enable = 1;
static int bogus_imm = 0;
/*
* XXX GC
@ -292,20 +292,23 @@ sgl_len(unsigned int n)
*
* Return a packet containing the immediate data of the given response.
*/
static __inline void
get_imm_packet(adapter_t *sc, const struct rsp_desc *resp, struct mbuf *m, void *cl)
static int
get_imm_packet(adapter_t *sc, const struct rsp_desc *resp, struct mbuf *m, void *cl, uint32_t flags)
{
int len;
uint32_t flags = ntohl(resp->flags);
int len, error;
uint8_t sopeop = G_RSPD_SOP_EOP(flags);
/*
* would be a firmware bug
*/
if (sopeop == RSPQ_NSOP_NEOP || sopeop == RSPQ_SOP)
return;
len = G_RSPD_LEN(ntohl(resp->len_cq));
if (sopeop == RSPQ_NSOP_NEOP || sopeop == RSPQ_SOP) {
if (cxgb_debug)
device_printf(sc->dev, "unexpected value sopeop=%d flags=0x%x len=%din get_imm_packet\n", sopeop, flags, len);
bogus_imm++;
return (EINVAL);
}
error = 0;
switch (sopeop) {
case RSPQ_SOP_EOP:
m->m_len = m->m_pkthdr.len = len;
@ -315,7 +318,12 @@ get_imm_packet(adapter_t *sc, const struct rsp_desc *resp, struct mbuf *m, void
memcpy(cl, resp->imm_data, len);
m_iovappend(m, cl, MSIZE, len, 0);
break;
default:
bogus_imm++;
error = EINVAL;
}
return (error);
}
@ -362,8 +370,11 @@ t3_sge_prep(adapter_t *adap, struct sge_params *p)
q->polling = adap->params.rev > 0;
q->coalesce_nsecs = 5000;
if (adap->params.nports > 2)
q->coalesce_nsecs = 50000;
else
q->coalesce_nsecs = 5000;
q->rspq_size = RSPQ_Q_SIZE;
q->fl_size = FL_Q_SIZE;
q->jumbo_size = JUMBO_Q_SIZE;
@ -664,6 +675,35 @@ sge_slow_intr_handler(void *arg, int ncount)
t3_slow_intr_handler(sc);
}
/**
* sge_timer_cb - perform periodic maintenance of an SGE qset
* @data: the SGE queue set to maintain
*
* Runs periodically from a timer to perform maintenance of an SGE queue
* set. It performs two tasks:
*
* a) Cleans up any completed Tx descriptors that may still be pending.
* Normal descriptor cleanup happens when new packets are added to a Tx
* queue so this timer is relatively infrequent and does any cleanup only
* if the Tx queue has not seen any new packets in a while. We make a
* best effort attempt to reclaim descriptors, in that we don't wait
* around if we cannot get a queue's lock (which most likely is because
* someone else is queueing new packets and so will also handle the clean
* up). Since control queues use immediate data exclusively we don't
* bother cleaning them up here.
*
* b) Replenishes Rx queues that have run out due to memory shortage.
* Normally new Rx buffers are added when existing ones are consumed but
* when out of memory a queue can become empty. We try to add only a few
* buffers here, the queue will be replenished fully as these new buffers
* are used up if memory shortage has subsided.
*
* c) Return coalesced response queue credits in case a response queue is
* starved.
*
* d) Ring doorbells for T304 tunnel queues since we have seen doorbell
* fifo overflows and the FW doesn't implement any recovery scheme yet.
*/
static void
sge_timer_cb(void *arg)
{
@ -688,6 +728,17 @@ sge_timer_cb(void *arg)
break;
}
}
if (sc->params.nports > 2) {
int i;
for_each_port(sc, i) {
struct port_info *pi = &sc->port[i];
t3_write_reg(sc, A_SG_KDOORBELL,
F_SELEGRCNTX |
(FW_TUNNEL_SGEEC_START + pi->first_qset));
}
}
if (sc->open_device_map != 0)
callout_reset(&sc->sge_timer_ch, TX_RECLAIM_PERIOD, sge_timer_cb, sc);
}
@ -920,7 +971,7 @@ busdma_map_mbufs(struct mbuf **m, struct sge_txq *txq,
#endif
if (err == EFBIG) {
/* Too many segments, try to defrag */
m0 = m_defrag(m0, M_NOWAIT);
m0 = m_defrag(m0, M_DONTWAIT);
if (m0 == NULL) {
m_freem(*m);
*m = NULL;
@ -2051,6 +2102,7 @@ t3_sge_alloc_qset(adapter_t *sc, u_int id, int nports, int irq_vec_idx,
q->fl[1].size = p->jumbo_size;
q->rspq.gen = 1;
q->rspq.cidx = 0;
q->rspq.size = p->rspq_size;
q->txq[TXQ_ETH].stop_thres = nports *
@ -2211,7 +2263,7 @@ get_packet(adapter_t *adap, unsigned int drop_thres, struct sge_qset *qs,
int ret = 0;
prefetch(sd->cl);
fl->credits--;
bus_dmamap_sync(fl->entry_tag, sd->map, BUS_DMASYNC_POSTREAD);
@ -2328,7 +2380,7 @@ process_responses(adapter_t *adap, struct sge_qset *qs, int budget)
int ngathered = 0;
#ifdef DEBUG
static int last_holdoff = 0;
if (rspq->holdoff_tmr != last_holdoff) {
if (cxgb_debug && rspq->holdoff_tmr != last_holdoff) {
printf("next_holdoff=%d\n", rspq->holdoff_tmr);
last_holdoff = rspq->holdoff_tmr;
}
@ -2349,26 +2401,31 @@ process_responses(adapter_t *adap, struct sge_qset *qs, int budget)
} else if (flags & F_RSPD_IMM_DATA_VALID) {
struct mbuf *m = NULL;
if (cxgb_debug)
printf("IMM DATA VALID\n");
if (rspq->m == NULL)
rspq->m = m_gethdr(M_NOWAIT, MT_DATA);
else
m = m_gethdr(M_NOWAIT, MT_DATA);
if (rspq->m == NULL || m == NULL) {
if (cxgb_debug)
printf("IMM DATA VALID opcode=0x%x rspq->cidx=%d\n", r->rss_hdr.opcode, rspq->cidx);
if (rspq->m == NULL)
rspq->m = m_gethdr(M_DONTWAIT, MT_DATA);
else
m = m_gethdr(M_DONTWAIT, MT_DATA);
/*
* XXX revisit me
*/
if (rspq->m == NULL && m == NULL) {
rspq->next_holdoff = NOMEM_INTR_DELAY;
budget_left--;
break;
}
get_imm_packet(adap, r, rspq->m, m);
if (get_imm_packet(adap, r, rspq->m, m, flags))
goto skip;
eop = 1;
rspq->imm_data++;
} else if (r->len_cq) {
int drop_thresh = eth ? SGE_RX_DROP_THRES : 0;
if (rspq->m == NULL)
rspq->m = m_gethdr(M_NOWAIT, MT_DATA);
rspq->m = m_gethdr(M_DONTWAIT, MT_DATA);
if (rspq->m == NULL) {
log(LOG_WARNING, "failed to get mbuf for packet\n");
break;
@ -2385,7 +2442,7 @@ process_responses(adapter_t *adap, struct sge_qset *qs, int budget)
sleeping |= flags & RSPD_GTS_MASK;
handle_rsp_cntrl_info(qs, flags);
}
skip:
r++;
if (__predict_false(++rspq->cidx == rspq->size)) {
rspq->cidx = 0;
@ -2661,6 +2718,10 @@ t3_add_sysctls(adapter_t *sc)
"txq_overrun",
CTLFLAG_RD, &txq_fills,
0, "#times txq overrun");
SYSCTL_ADD_INT(ctx, children, OID_AUTO,
"bogus_imm",
CTLFLAG_RD, &bogus_imm,
0, "#times a bogus immediate response was seen");
}
/**

View File

@ -134,13 +134,18 @@ m_free_vec(struct mbuf *m)
mb_free_ext(m);
else
uma_zfree(zone_mbuf, m);
if (n)
n->m_flags &= ~M_PKTHDR;
return (n);
}
static __inline void
m_freem_vec(struct mbuf *m)
{
while (m != NULL)
while (m != NULL)
m = m_free_vec(m);
}

View File

@ -0,0 +1,46 @@
/**************************************************************************
Copyright (c) 2007, Chelsio Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Neither the name of the Chelsio Corporation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
$FreeBSD$
***************************************************************************/
begin 644 t3b_protocol_sram-1.1.0.bin.gz
M'XL(".):ED8``W0S8E]P<F]T;V-O;%]S<F%M+3$N,2XP+F)I;@#EECU+PT`8
MQY]<VAA*D?@R:%4(%$L4!X,5<2NZ.91^A([2*?@%3%L<%(6`XN"NLQ_A?"O%
MJ3B(DX-"$:>S=K!5J,]=J20Q@U#:#AXD>>[/O?SRSSUW:;5:7]`NLKA+$K3\
M&I9_J'U6DG+53LRON[0/L$1(\,J70@/G>[*-N;B;3P&R(MU0&#L*Y4MA2V@%
M(,J*K`:-1W0;\@?UGO`UKDT,C(6B2V-IB\P`\F&1+B8&ZM\;!?R^AA$/:$?0
M/R2T!LG7U)+`(=P:RP(HNJP27(;,GCUQ>N%+V21*!,@:5O-V6VN43;D4.9YW
M:RQD<KZ0AT\_%R'W3[J8]/C'BP2@=<O'\('SIF`SJO/QN`<-:EY5(9%+N>9H
M:G6!XLG?;$85L175._XQ171*!?$18U^S=VC7S('OD?ZMX9HDCZ#$.$S!6:9]
MRX5;\^HR<ISS>)7.C*].WU"_][WV)4A[OUV*WP_[^'`9*'K%^WVATJE!T3'[
MYA_R/?OY&&1B&BSZ^'`OQOSEQTC#&=GK1?[^>7^FF:DSN//PL120(4P!OK^\
M.,F-0?)A_A(5J)>O$V_MEQ\.=T7NLX(C.O:;CP5H-:SJD!CU>RIK6O_/MX#_
6EYJ:)(M`PS_MK-?3[6^9;',3!`H`````
`
end

View File

@ -0,0 +1,46 @@
/**************************************************************************
Copyright (c) 2007, Chelsio Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Neither the name of the Chelsio Corporation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
$FreeBSD$
***************************************************************************/
begin 644 t3b_tp_eeprom-1.1.0.bin.gz
M'XL(".):ED8``W0S8E]T<%]E97!R;VTM,2XQ+C`N8FEN`-V5,4O#0!3'_[FK
M[;5634&PZ(&I%8VBT(J@A5J#=7`JW43H$!W$T8\0+8@.@DXBN+4(^0#N410<
M'(I?0'%0W%W<O*MI(@41(77P$=Z1X\][O[R\=P=%@32*3XN[:\9='7?])X+B
MY)CU3&<;W3!,S@#M<SMB_2%#>D*WGIH,JR9?,7(**GP[#=-G8'0N3+#+8#PD
M&=A(\`S5*5WX['445H(W=RKQ1@HOH>!2_%P'71?_`HZ"`<`P<JG@4_PL$-T?
MPJP:L]<(ZP/&K0PVQ'XXD!36CG!+!+$PR=[*.4O*EJMOV&9>K9YY$4*2(2O\
M28+[=>@F4`$%OOV>X4A&T.);,&0*:8H,"M0WB5G@U&,H$NG?W#I<(2)?+73M
M>0Q&<Q%U42J,7>YWH"==04GT(IU@$G(=C],`#SR%+ZAOVEJ>U_P4S@W/]9=+
MK.TS\6V$(!A>S8696KXE*)*&%A9_BX'3'/,R]UB=9BA\9<A`'2P#=E(Y[9,'
MI)@+3;9$YQC:!45RC_.ALA.UE^E!KYA-T7O;6JN1_XK!`2-B+J+'\P>'=WH$
M;4:;S]$NOHL0'*278G2=8,:[NZ1`52F1,]XQAM:]V3J.,F6A31M5;?C]8O$#
(X@X'9$0(````
`
end

View File

@ -1,482 +0,0 @@
/**************************************************************************
Copyright (c) 2007, Chelsio Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Neither the name of the Chelsio Corporation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
$FreeBSD$
***************************************************************************/
begin 644 t3fw-4.1.0.bin.gz
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
6>8ET,/DRTA1`S>E__P.PN$K4G'$`````
`
end

View File

@ -0,0 +1,442 @@
/**************************************************************************
Copyright (c) 2007, Chelsio Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Neither the name of the Chelsio Corporation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
$FreeBSD$
***************************************************************************/
begin 644 t3fw-4.5.0.bin.gz
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
*%P!M0DW?O%L`````
`
end

View File

@ -15,12 +15,28 @@ CFLAGS+= -DCONFIG_CHELSIO_T3_CORE -g -DCONFIG_DEFINED -DDEFAULT_JUMBO -I${CXGB}
.if ${MACHINE_ARCH} != "ia64"
# ld is broken on ia64
t3fw-4.1.0.bin: ${CXGB}/t3fw-4.1.0.bin.gz.uu
uudecode -p < ${CXGB}/t3fw-4.1.0.bin.gz.uu \
t3fw-4.5.0.bin: ${CXGB}/t3fw-4.5.0.bin.gz.uu
uudecode -p < ${CXGB}/t3fw-4.5.0.bin.gz.uu \
| gzip -dc > ${.TARGET}
FIRMWS= t3fw-4.1.0.bin:t3fw410
CLEANFILES+= t3fw-4.1.0.bin
FIRMWS= t3fw-4.5.0.bin:t3fw450
CLEANFILES+= t3fw-4.5.0.bin
t3b_protocol_sram-1.1.0.bin: ${CXGB}/t3b_protocol_sram-1.1.0.bin.gz.uu
uudecode -p < ${CXGB}/t3b_protocol_sram-1.1.0.bin.gz.uu \
| gzip -dc > ${.TARGET}
FIRMWS+= t3b_protocol_sram-1.1.0.bin:t3bps110
CLEANFILES+= t3b_protocol_sram-1.1.0.bin
t3b_tp_eeprom-1.1.0.bin: ${CXGB}/t3b_tp_eeprom-1.1.0.bin.gz.uu
uudecode -p < ${CXGB}/t3b_tp_eeprom-1.1.0.bin.gz.uu \
| gzip -dc > ${.TARGET}
FIRMWS+= t3b_tp_eeprom-1.1.0.bin:t3btpe110
CLEANFILES+= t3b_tp_eeprom-1.1.0.bin
.endif