mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-12-03 19:08:58 +00:00
(MFp4)
- upgrade to reflect state of 1.0.0.86 - move from firmware rev 3.2 to 4.0.0 - import driver bits for offload functionality - remove binary distribution clause from top level files as it runs counter to the intent of purely supporting the hardware MFC after: 3 days
This commit is contained in:
parent
55e1a40108
commit
d722cab49a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=169978
@ -514,6 +514,8 @@ dev/cs/if_cs.c optional cs
|
||||
dev/cs/if_cs_isa.c optional cs isa
|
||||
dev/cs/if_cs_pccard.c optional cs pccard
|
||||
dev/cxgb/cxgb_main.c optional cxgb pci
|
||||
dev/cxgb/cxgb_offload.c optional cxgb pci
|
||||
dev/cxgb/cxgb_l2t.c optional cxgb pci
|
||||
dev/cxgb/cxgb_lro.c optional cxgb pci
|
||||
dev/cxgb/cxgb_sge.c optional cxgb pci
|
||||
dev/cxgb/common/cxgb_mc5.c optional cxgb pci
|
||||
|
@ -46,6 +46,7 @@ enum {
|
||||
NMTUS = 16, /* size of MTU table */
|
||||
NCCTRL_WIN = 32, /* # of congestion control windows */
|
||||
NTX_SCHED = 8, /* # of HW Tx scheduling queues */
|
||||
TP_TMR_RES = 200, /* TP timer resolution in usec */
|
||||
};
|
||||
|
||||
#define MAX_RX_COALESCING_LEN 16224U
|
||||
@ -57,7 +58,6 @@ enum {
|
||||
};
|
||||
|
||||
enum {
|
||||
SUPPORTED_OFFLOAD = 1 << 24,
|
||||
SUPPORTED_IRQ = 1 << 25
|
||||
};
|
||||
|
||||
@ -70,8 +70,8 @@ enum { /* adapter interrupt-maintained statistics */
|
||||
};
|
||||
|
||||
enum {
|
||||
FW_VERSION_MAJOR = 3,
|
||||
FW_VERSION_MINOR = 2,
|
||||
FW_VERSION_MAJOR = 4,
|
||||
FW_VERSION_MINOR = 0,
|
||||
FW_VERSION_MICRO = 0
|
||||
};
|
||||
|
||||
@ -309,6 +309,9 @@ enum {
|
||||
MC5_MODE_72_BIT = 2
|
||||
};
|
||||
|
||||
/* MC5 min active region size */
|
||||
enum { MC5_MIN_TIDS = 16 };
|
||||
|
||||
struct vpd_params {
|
||||
unsigned int cclk;
|
||||
unsigned int mclk;
|
||||
@ -354,6 +357,7 @@ struct adapter_params {
|
||||
unsigned int stats_update_period; /* MAC stats accumulation period */
|
||||
unsigned int linkpoll_period; /* link poll period in 0.1s */
|
||||
unsigned int rev; /* chip revision */
|
||||
unsigned int offload;
|
||||
};
|
||||
|
||||
enum { /* chip revisions */
|
||||
@ -427,8 +431,11 @@ struct cmac {
|
||||
adapter_t *adapter;
|
||||
unsigned int offset;
|
||||
unsigned int nucast; /* # of address filters for unicast MACs */
|
||||
unsigned int tcnt;
|
||||
unsigned int xcnt;
|
||||
unsigned int tx_tcnt;
|
||||
unsigned int tx_xcnt;
|
||||
u64 tx_mcnt;
|
||||
unsigned int rx_xcnt;
|
||||
u64 rx_mcnt;
|
||||
unsigned int toggle_cnt;
|
||||
unsigned int txen;
|
||||
struct mac_stats stats;
|
||||
@ -555,7 +562,7 @@ static inline int is_10G(const adapter_t *adap)
|
||||
static inline int is_offload(const adapter_t *adap)
|
||||
{
|
||||
#ifdef CONFIG_CHELSIO_T3_CORE
|
||||
return adapter_info(adap)->caps & SUPPORTED_OFFLOAD;
|
||||
return adap->params.offload;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
|
@ -329,6 +329,9 @@ int t3_mc5_init(struct mc5 *mc5, unsigned int nservers, unsigned int nfilters,
|
||||
unsigned int tcam_size = mc5->tcam_size;
|
||||
adapter_t *adap = mc5->adapter;
|
||||
|
||||
if (tcam_size == 0)
|
||||
return 0;
|
||||
|
||||
if (nroutes > MAX_ROUTES || nroutes + nservers + nfilters > tcam_size)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -260,6 +260,20 @@ struct work_request_hdr {
|
||||
#define V_WR_BCNTLFLT(x) ((x) << S_WR_BCNTLFLT)
|
||||
#define G_WR_BCNTLFLT(x) (((x) >> S_WR_BCNTLFLT) & M_WR_BCNTLFLT)
|
||||
|
||||
/* 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)
|
||||
|
||||
/* 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_DATATYPE 20
|
||||
#define V_WR_DATATYPE(x) ((x) << S_WR_DATATYPE)
|
||||
#define F_WR_DATATYPE V_WR_DATATYPE(1U)
|
||||
@ -1487,4 +1501,46 @@ struct cpl_rdma_terminate {
|
||||
#define M_TERM_TID 0xFFFFF
|
||||
#define V_TERM_TID(x) ((x) << S_TERM_TID)
|
||||
#define G_TERM_TID(x) (((x) >> S_TERM_TID) & M_TERM_TID)
|
||||
|
||||
/* ULP_TX opcodes */
|
||||
enum { ULP_MEM_READ = 2, ULP_MEM_WRITE = 3, ULP_TXPKT = 4 };
|
||||
|
||||
#define S_ULPTX_CMD 28
|
||||
#define M_ULPTX_CMD 0xF
|
||||
#define V_ULPTX_CMD(x) ((x) << S_ULPTX_CMD)
|
||||
|
||||
#define S_ULPTX_NFLITS 0
|
||||
#define M_ULPTX_NFLITS 0xFF
|
||||
#define V_ULPTX_NFLITS(x) ((x) << S_ULPTX_NFLITS)
|
||||
|
||||
struct ulp_mem_io {
|
||||
WR_HDR;
|
||||
__be32 cmd_lock_addr;
|
||||
__be32 len;
|
||||
};
|
||||
|
||||
/* 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)
|
||||
|
||||
#define S_ULP_MEMIO_LOCK 27
|
||||
#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 */
|
||||
#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)
|
||||
|
||||
struct ulp_txpkt {
|
||||
__be32 cmd_dest;
|
||||
__be32 len;
|
||||
};
|
||||
|
||||
/* 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)
|
||||
|
||||
#endif /* T3_CPL_H */
|
||||
|
@ -441,23 +441,23 @@ static struct adapter_info t3_adap_info[] = {
|
||||
{ 2, 0, 0, 0,
|
||||
F_GPIO2_OEN | F_GPIO4_OEN |
|
||||
F_GPIO2_OUT_VAL | F_GPIO4_OUT_VAL, F_GPIO3 | F_GPIO5,
|
||||
SUPPORTED_OFFLOAD,
|
||||
0,
|
||||
&mi1_mdio_ops, "Chelsio PE9000" },
|
||||
{ 2, 0, 0, 0,
|
||||
F_GPIO2_OEN | F_GPIO4_OEN |
|
||||
F_GPIO2_OUT_VAL | F_GPIO4_OUT_VAL, F_GPIO3 | F_GPIO5,
|
||||
SUPPORTED_OFFLOAD,
|
||||
0,
|
||||
&mi1_mdio_ops, "Chelsio T302" },
|
||||
{ 1, 0, 0, 0,
|
||||
F_GPIO1_OEN | F_GPIO6_OEN | F_GPIO7_OEN | F_GPIO10_OEN |
|
||||
F_GPIO1_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL, 0,
|
||||
SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_OFFLOAD,
|
||||
SUPPORTED_10000baseT_Full | SUPPORTED_AUI,
|
||||
&mi1_mdio_ext_ops, "Chelsio T310" },
|
||||
{ 2, 0, 0, 0,
|
||||
F_GPIO1_OEN | F_GPIO2_OEN | F_GPIO4_OEN | F_GPIO5_OEN | F_GPIO6_OEN |
|
||||
F_GPIO7_OEN | F_GPIO10_OEN | F_GPIO11_OEN | F_GPIO1_OUT_VAL |
|
||||
F_GPIO5_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL, 0,
|
||||
SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_OFFLOAD,
|
||||
SUPPORTED_10000baseT_Full | SUPPORTED_AUI,
|
||||
&mi1_mdio_ext_ops, "Chelsio T320" },
|
||||
};
|
||||
|
||||
@ -2387,9 +2387,6 @@ static void tp_config(adapter_t *adap, const struct tp_params *p)
|
||||
t3_write_reg(adap, A_TP_MOD_RATE_LIMIT, 0);
|
||||
}
|
||||
|
||||
/* Desired TP timer resolution in usec */
|
||||
#define TP_TMR_RES 200
|
||||
|
||||
/* TCP timer values in ms */
|
||||
#define TP_DACK_TIMER 50
|
||||
#define TP_RTO_MIN 250
|
||||
@ -3005,6 +3002,9 @@ static int mc7_init(struct mc7 *mc7, unsigned int mc7_clock, int mem_type)
|
||||
adapter_t *adapter = mc7->adapter;
|
||||
const struct mc7_timing_params *p = &mc7_timings[mem_type];
|
||||
|
||||
if (mc7->size == 0)
|
||||
return 0;
|
||||
|
||||
val = t3_read_reg(adapter, mc7->offset + A_MC7_CFG);
|
||||
slow = val & F_SLOW;
|
||||
width = G_WIDTH(val);
|
||||
@ -3209,9 +3209,10 @@ int t3_init_hw(adapter_t *adapter, u32 fw_params)
|
||||
do { /* wait for uP to initialize */
|
||||
t3_os_sleep(20);
|
||||
} while (t3_read_reg(adapter, A_CIM_HOST_ACC_DATA) && --attempts);
|
||||
if (!attempts)
|
||||
if (!attempts) {
|
||||
CH_ERR(adapter, "uP initialization timed out\n");
|
||||
goto out_err;
|
||||
|
||||
}
|
||||
err = 0;
|
||||
out_err:
|
||||
return err;
|
||||
@ -3309,7 +3310,7 @@ static void __devinit mc7_prep(adapter_t *adapter, struct mc7 *mc7,
|
||||
mc7->name = name;
|
||||
mc7->offset = base_addr - MC7_PMRX_BASE_ADDR;
|
||||
cfg = t3_read_reg(adapter, mc7->offset + A_MC7_CFG);
|
||||
mc7->size = mc7_calc_size(cfg);
|
||||
mc7->size = G_DEN(cfg) == M_DEN ? 0 : mc7_calc_size(cfg);
|
||||
mc7->width = G_WIDTH(cfg);
|
||||
}
|
||||
|
||||
@ -3336,7 +3337,8 @@ void early_hw_init(adapter_t *adapter, const struct adapter_info *ai)
|
||||
V_I2C_CLKDIV(adapter->params.vpd.cclk / 80 - 1));
|
||||
t3_write_reg(adapter, A_T3DBG_GPIO_EN,
|
||||
ai->gpio_out | F_GPIO0_OEN | F_GPIO0_OUT_VAL);
|
||||
|
||||
t3_write_reg(adapter, A_MC5_DB_SERVER_INDEX, 0);
|
||||
|
||||
if (adapter->params.rev == 0 || !uses_xaui(adapter))
|
||||
val |= F_ENRGMII;
|
||||
|
||||
@ -3435,7 +3437,12 @@ int __devinit t3_prep_adapter(adapter_t *adapter,
|
||||
p->ntimer_qs = p->cm_size >= (128 << 20) ||
|
||||
adapter->params.rev > 0 ? 12 : 6;
|
||||
p->dack_re = fls(adapter->params.vpd.cclk / 10) - 1; /* 100us */
|
||||
}
|
||||
adapter->params.offload = t3_mc7_size(&adapter->pmrx) &&
|
||||
t3_mc7_size(&adapter->pmtx) &&
|
||||
t3_mc7_size(&adapter->cm);
|
||||
|
||||
if (is_offload(adapter)) {
|
||||
adapter->params.mc5.nservers = DEFAULT_NSERVERS;
|
||||
adapter->params.mc5.nfilters = adapter->params.rev > 0 ?
|
||||
DEFAULT_NFILTERS : 0;
|
||||
|
@ -41,5 +41,5 @@ $FreeBSD$
|
||||
#define __CHELSIO_VERSION_H
|
||||
#define DRV_DESC "Chelsio T3 Network Driver"
|
||||
#define DRV_NAME "cxgb"
|
||||
#define DRV_VERSION "1.0.071"
|
||||
#endif
|
||||
#define DRV_VERSION "1.0.086"
|
||||
#endif
|
||||
|
@ -329,8 +329,8 @@ int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu)
|
||||
thres = mtu > thres ? (mtu - thres + 7) / 8 : 0;
|
||||
thres = max(thres, 8U); /* need at least 8 */
|
||||
t3_set_reg_field(adap, A_XGM_TXFIFO_CFG + mac->offset,
|
||||
V_TXFIFOTHRESH(M_TXFIFOTHRESH) | V_TXIPG(M_TXIPG),
|
||||
V_TXFIFOTHRESH(thres) | V_TXIPG(1));
|
||||
V_TXFIFOTHRESH(M_TXFIFOTHRESH) | V_TXIPG(M_TXIPG),
|
||||
V_TXFIFOTHRESH(thres) | V_TXIPG(1));
|
||||
|
||||
/* Assuming a minimum drain rate of 2.5Gbps...
|
||||
*/
|
||||
@ -365,7 +365,7 @@ int t3_mac_set_speed_duplex_fc(struct cmac *mac, int speed, int duplex, int fc)
|
||||
t3_set_reg_field(adap, A_XGM_PORT_CFG + oft,
|
||||
V_PORTSPEED(M_PORTSPEED), val);
|
||||
}
|
||||
#if 0
|
||||
#if 0
|
||||
val = t3_read_reg(adap, A_XGM_RXFIFO_CFG + oft);
|
||||
val &= ~V_RXFIFOPAUSEHWM(M_RXFIFOPAUSEHWM);
|
||||
if (fc & PAUSE_TX)
|
||||
@ -382,6 +382,7 @@ int t3_mac_enable(struct cmac *mac, int which)
|
||||
int idx = macidx(mac);
|
||||
adapter_t *adap = mac->adapter;
|
||||
unsigned int oft = mac->offset;
|
||||
struct mac_stats *s = &mac->stats;
|
||||
|
||||
if (which & MAC_DIRECTION_TX) {
|
||||
t3_write_reg(adap, A_XGM_TX_CTRL + oft, F_TXEN);
|
||||
@ -391,12 +392,20 @@ int t3_mac_enable(struct cmac *mac, int which)
|
||||
t3_set_reg_field(adap, A_TP_PIO_DATA, 1 << idx, 1 << idx);
|
||||
|
||||
t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CNT_CH0 + idx);
|
||||
mac->tcnt = (G_TXDROPCNTCH0RCVD(t3_read_reg(adap, A_TP_PIO_DATA)));
|
||||
mac->xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap, A_XGM_TX_SPI4_SOP_EOP_CNT)));
|
||||
mac->tx_mcnt = s->tx_frames;
|
||||
mac->tx_tcnt = (G_TXDROPCNTCH0RCVD(t3_read_reg(adap,
|
||||
A_TP_PIO_DATA)));
|
||||
mac->tx_xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap,
|
||||
A_XGM_TX_SPI4_SOP_EOP_CNT +
|
||||
oft)));
|
||||
mac->rx_mcnt = s->rx_frames;
|
||||
mac->rx_xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap,
|
||||
A_XGM_RX_SPI4_SOP_EOP_CNT +
|
||||
oft)));
|
||||
mac->txen = F_TXEN;
|
||||
mac->toggle_cnt = 0;
|
||||
}
|
||||
if (which & MAC_DIRECTION_RX)
|
||||
if (which & MAC_DIRECTION_RX)
|
||||
t3_write_reg(adap, A_XGM_RX_CTRL + oft, F_RXEN);
|
||||
return 0;
|
||||
}
|
||||
@ -405,6 +414,7 @@ int t3_mac_disable(struct cmac *mac, int which)
|
||||
{
|
||||
int idx = macidx(mac);
|
||||
adapter_t *adap = mac->adapter;
|
||||
int val;
|
||||
|
||||
if (which & MAC_DIRECTION_TX) {
|
||||
t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset, 0);
|
||||
@ -414,39 +424,99 @@ int t3_mac_disable(struct cmac *mac, int which)
|
||||
t3_set_reg_field(adap, A_TP_PIO_DATA, 1 << idx, 1 << idx);
|
||||
mac->txen = 0;
|
||||
}
|
||||
if (which & MAC_DIRECTION_RX)
|
||||
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);
|
||||
t3_write_reg(adap, A_XGM_RX_CTRL + mac->offset, 0);
|
||||
val = F_MAC_RESET_;
|
||||
if (is_10G(adap))
|
||||
val |= F_PCS_RESET_;
|
||||
else if (uses_xaui(adap))
|
||||
val |= F_PCS_RESET_ | F_XG2G_RESET_;
|
||||
else
|
||||
val |= F_RGMII_RESET_ | F_XG2G_RESET_;
|
||||
t3_write_reg(mac->adapter, A_XGM_RESET_CTRL + mac->offset, val);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int t3b2_mac_watchdog_task(struct cmac *mac)
|
||||
{
|
||||
int status;
|
||||
unsigned int tcnt, xcnt;
|
||||
unsigned int tx_tcnt, tx_xcnt;
|
||||
adapter_t *adap = mac->adapter;
|
||||
t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CNT_CH0 + macidx(mac));
|
||||
tcnt = (G_TXDROPCNTCH0RCVD(t3_read_reg(adap, A_TP_PIO_DATA)));
|
||||
xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap, A_XGM_TX_SPI4_SOP_EOP_CNT + mac->offset)));
|
||||
struct mac_stats *s = &mac->stats;
|
||||
unsigned int tx_mcnt = (unsigned int)s->tx_frames;
|
||||
unsigned int rx_mcnt = (unsigned int)s->rx_frames;
|
||||
unsigned int rx_xcnt;
|
||||
|
||||
if ((tcnt != mac->tcnt) && (xcnt == 0) && (mac->xcnt == 0)) {
|
||||
if (mac->toggle_cnt > 4) {
|
||||
t3b2_mac_reset(mac);
|
||||
mac->toggle_cnt = 0;
|
||||
status = 2;
|
||||
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*/
|
||||
rx_xcnt = 1; /* By default rx_xcnt is making progress*/
|
||||
if (tx_mcnt == mac->tx_mcnt) {
|
||||
tx_xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap,
|
||||
A_XGM_TX_SPI4_SOP_EOP_CNT +
|
||||
mac->offset)));
|
||||
if (tx_xcnt == 0) {
|
||||
t3_write_reg(adap, A_TP_PIO_ADDR,
|
||||
A_TP_TX_DROP_CNT_CH0 + macidx(mac));
|
||||
tx_tcnt = (G_TXDROPCNTCH0RCVD(t3_read_reg(adap,
|
||||
A_TP_PIO_DATA)));
|
||||
} else {
|
||||
t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset, 0);
|
||||
t3_read_reg(adap, A_XGM_TX_CTRL + mac->offset); /* flush */
|
||||
t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset, mac->txen);
|
||||
t3_read_reg(adap, A_XGM_TX_CTRL + mac->offset); /* flush */
|
||||
mac->toggle_cnt++;
|
||||
status = 1;
|
||||
}
|
||||
goto rxcheck;
|
||||
}
|
||||
} else {
|
||||
mac->toggle_cnt = 0;
|
||||
status = 0;
|
||||
goto rxcheck;
|
||||
}
|
||||
|
||||
if (((tx_tcnt != mac->tx_tcnt) &&
|
||||
(tx_xcnt == 0) && (mac->tx_xcnt == 0)) ||
|
||||
((mac->tx_mcnt == tx_mcnt) &&
|
||||
(tx_xcnt != 0) && (mac->tx_xcnt != 0))) {
|
||||
if (mac->toggle_cnt > 4) {
|
||||
status = 2;
|
||||
goto out;
|
||||
} else {
|
||||
status = 1;
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
mac->toggle_cnt = 0;
|
||||
goto rxcheck;
|
||||
}
|
||||
|
||||
rxcheck:
|
||||
if (rx_mcnt != mac->rx_mcnt)
|
||||
rx_xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap,
|
||||
A_XGM_RX_SPI4_SOP_EOP_CNT +
|
||||
mac->offset)));
|
||||
else
|
||||
goto out;
|
||||
|
||||
if (mac->rx_mcnt != s->rx_frames && rx_xcnt == 0 && mac->rx_xcnt == 0) {
|
||||
status = 2;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
mac->tx_tcnt = tx_tcnt;
|
||||
mac->tx_xcnt = tx_xcnt;
|
||||
mac->tx_mcnt = s->tx_frames;
|
||||
mac->rx_xcnt = rx_xcnt;
|
||||
mac->rx_mcnt = s->rx_frames;
|
||||
if (status == 1) {
|
||||
t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset, 0);
|
||||
t3_read_reg(adap, A_XGM_TX_CTRL + mac->offset); /* flush */
|
||||
t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset, mac->txen);
|
||||
t3_read_reg(adap, A_XGM_TX_CTRL + mac->offset); /* flush */
|
||||
mac->toggle_cnt++;
|
||||
} else if (status == 2) {
|
||||
t3b2_mac_reset(mac);
|
||||
mac->toggle_cnt = 0;
|
||||
}
|
||||
mac->tcnt = tcnt;
|
||||
mac->xcnt = xcnt;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
140
sys/dev/cxgb/common/jhash.h
Normal file
140
sys/dev/cxgb/common/jhash.h
Normal file
@ -0,0 +1,140 @@
|
||||
#ifndef _JHASH_H
|
||||
#define _JHASH_H
|
||||
|
||||
/* jhash.h: Jenkins hash support.
|
||||
*
|
||||
* Copyright (C) 1996 Bob Jenkins (bob_jenkins@burtleburtle.net)
|
||||
*
|
||||
* http://burtleburtle.net/bob/hash/
|
||||
*
|
||||
* These are the credits from Bob's sources:
|
||||
*
|
||||
* lookup2.c, by Bob Jenkins, December 1996, Public Domain.
|
||||
* hash(), hash2(), hash3, and mix() are externally useful functions.
|
||||
* Routines to test the hash are included if SELF_TEST is defined.
|
||||
* You can use this free for any purpose. It has no warranty.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/* NOTE: Arguments are modified. */
|
||||
#define __jhash_mix(a, b, c) \
|
||||
{ \
|
||||
a -= b; a -= c; a ^= (c>>13); \
|
||||
b -= c; b -= a; b ^= (a<<8); \
|
||||
c -= a; c -= b; c ^= (b>>13); \
|
||||
a -= b; a -= c; a ^= (c>>12); \
|
||||
b -= c; b -= a; b ^= (a<<16); \
|
||||
c -= a; c -= b; c ^= (b>>5); \
|
||||
a -= b; a -= c; a ^= (c>>3); \
|
||||
b -= c; b -= a; b ^= (a<<10); \
|
||||
c -= a; c -= b; c ^= (b>>15); \
|
||||
}
|
||||
|
||||
/* The golden ration: an arbitrary value */
|
||||
#define JHASH_GOLDEN_RATIO 0x9e3779b9
|
||||
|
||||
/* The most generic version, hashes an arbitrary sequence
|
||||
* of bytes. No alignment or length assumptions are made about
|
||||
* the input key.
|
||||
*/
|
||||
static inline u32 jhash(const void *key, u32 length, u32 initval)
|
||||
{
|
||||
u32 a, b, c, len;
|
||||
const u8 *k = key;
|
||||
|
||||
len = length;
|
||||
a = b = JHASH_GOLDEN_RATIO;
|
||||
c = initval;
|
||||
|
||||
while (len >= 12) {
|
||||
a += (k[0] +((u32)k[1]<<8) +((u32)k[2]<<16) +((u32)k[3]<<24));
|
||||
b += (k[4] +((u32)k[5]<<8) +((u32)k[6]<<16) +((u32)k[7]<<24));
|
||||
c += (k[8] +((u32)k[9]<<8) +((u32)k[10]<<16)+((u32)k[11]<<24));
|
||||
|
||||
__jhash_mix(a,b,c);
|
||||
|
||||
k += 12;
|
||||
len -= 12;
|
||||
}
|
||||
|
||||
c += length;
|
||||
switch (len) {
|
||||
case 11: c += ((u32)k[10]<<24);
|
||||
case 10: c += ((u32)k[9]<<16);
|
||||
case 9 : c += ((u32)k[8]<<8);
|
||||
case 8 : b += ((u32)k[7]<<24);
|
||||
case 7 : b += ((u32)k[6]<<16);
|
||||
case 6 : b += ((u32)k[5]<<8);
|
||||
case 5 : b += k[4];
|
||||
case 4 : a += ((u32)k[3]<<24);
|
||||
case 3 : a += ((u32)k[2]<<16);
|
||||
case 2 : a += ((u32)k[1]<<8);
|
||||
case 1 : a += k[0];
|
||||
};
|
||||
|
||||
__jhash_mix(a,b,c);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/* A special optimized version that handles 1 or more of u32s.
|
||||
* The length parameter here is the number of u32s in the key.
|
||||
*/
|
||||
static inline u32 jhash2(u32 *k, u32 length, u32 initval)
|
||||
{
|
||||
u32 a, b, c, len;
|
||||
|
||||
a = b = JHASH_GOLDEN_RATIO;
|
||||
c = initval;
|
||||
len = length;
|
||||
|
||||
while (len >= 3) {
|
||||
a += k[0];
|
||||
b += k[1];
|
||||
c += k[2];
|
||||
__jhash_mix(a, b, c);
|
||||
k += 3; len -= 3;
|
||||
}
|
||||
|
||||
c += length * 4;
|
||||
|
||||
switch (len) {
|
||||
case 2 : b += k[1];
|
||||
case 1 : a += k[0];
|
||||
};
|
||||
|
||||
__jhash_mix(a,b,c);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
/* A special ultra-optimized versions that knows they are hashing exactly
|
||||
* 3, 2 or 1 word(s).
|
||||
*
|
||||
* NOTE: In partilar the "c += length; __jhash_mix(a,b,c);" normally
|
||||
* done at the end is not done here.
|
||||
*/
|
||||
static inline u32 jhash_3words(u32 a, u32 b, u32 c, u32 initval)
|
||||
{
|
||||
a += JHASH_GOLDEN_RATIO;
|
||||
b += JHASH_GOLDEN_RATIO;
|
||||
c += initval;
|
||||
|
||||
__jhash_mix(a, b, c);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static inline u32 jhash_2words(u32 a, u32 b, u32 initval)
|
||||
{
|
||||
return jhash_3words(a, b, 0, initval);
|
||||
}
|
||||
|
||||
static inline u32 jhash_1word(u32 a, u32 initval)
|
||||
{
|
||||
return jhash_3words(a, 0, 0, initval);
|
||||
}
|
||||
|
||||
#endif /* _JHASH_H */
|
@ -9,11 +9,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.
|
||||
|
||||
@ -59,6 +55,9 @@ __FBSDID("$FreeBSD$");
|
||||
#include <dev/pci/pcireg.h>
|
||||
#include <dev/pci/pcivar.h>
|
||||
|
||||
#include <dev/cxgb/ulp/toecore/toedev.h>
|
||||
#include <dev/cxgb/sys/mbufq.h>
|
||||
|
||||
struct adapter;
|
||||
struct sge_qset;
|
||||
extern int cxgb_debug;
|
||||
@ -91,9 +90,6 @@ enum { /* adapter flags */
|
||||
FW_UPTODATE = (1 << 4),
|
||||
};
|
||||
|
||||
/* Max active LRO sessions per queue set */
|
||||
#define MAX_LRO_PER_QSET 8
|
||||
|
||||
|
||||
#define FL_Q_SIZE 4096
|
||||
#define JUMBO_Q_SIZE 512
|
||||
@ -114,25 +110,23 @@ enum {
|
||||
LRO_ACTIVE = (1 << 8),
|
||||
};
|
||||
|
||||
struct sge_lro_session {
|
||||
struct mbuf *m;
|
||||
/* Max concurrent LRO sessions per queue set */
|
||||
#define MAX_LRO_SES 8
|
||||
|
||||
struct t3_lro_session {
|
||||
struct mbuf *head;
|
||||
struct mbuf *tail;
|
||||
uint32_t seq;
|
||||
uint16_t ip_len;
|
||||
uint16_t vtag;
|
||||
uint8_t npkts;
|
||||
};
|
||||
|
||||
struct sge_lro {
|
||||
unsigned int enabled;
|
||||
unsigned int num_active;
|
||||
struct sge_lro_session *last_s;
|
||||
struct sge_lro_session s[MAX_LRO_PER_QSET];
|
||||
};
|
||||
|
||||
/* has its own header on linux XXX
|
||||
* but I don't even know what it is :-/
|
||||
*/
|
||||
|
||||
struct t3cdev {
|
||||
int foo; /* XXX fill in */
|
||||
struct lro_state {
|
||||
unsigned short enabled;
|
||||
unsigned short active_idx;
|
||||
unsigned int nactive;
|
||||
struct t3_lro_session sess[MAX_LRO_SES];
|
||||
};
|
||||
|
||||
#define RX_BUNDLE_SIZE 8
|
||||
@ -148,14 +142,21 @@ struct sge_rspq {
|
||||
uint32_t holdoff_tmr;
|
||||
uint32_t next_holdoff;
|
||||
uint32_t imm_data;
|
||||
uint32_t pure_rsps;
|
||||
struct rsp_desc *desc;
|
||||
bus_addr_t phys_addr;
|
||||
uint32_t cntxt_id;
|
||||
struct mtx lock;
|
||||
struct mbuf *rx_head; /* offload packet receive queue head */
|
||||
struct mbuf *rx_tail; /* offload packet receive queue tail */
|
||||
|
||||
uint32_t offload_pkts;
|
||||
uint32_t offload_bundles;
|
||||
uint32_t pure_rsps;
|
||||
uint32_t unhandled_irqs;
|
||||
|
||||
bus_addr_t phys_addr;
|
||||
bus_dma_tag_t desc_tag;
|
||||
bus_dmamap_t desc_map;
|
||||
struct mbuf *m;
|
||||
struct mtx lock;
|
||||
};
|
||||
|
||||
struct rx_desc;
|
||||
@ -198,12 +199,14 @@ struct sge_txq {
|
||||
struct tx_sw_desc *sdesc;
|
||||
uint32_t token;
|
||||
bus_addr_t phys_addr;
|
||||
struct task qresume_tsk;
|
||||
uint32_t cntxt_id;
|
||||
uint64_t stops;
|
||||
uint64_t restarts;
|
||||
bus_dma_tag_t desc_tag;
|
||||
bus_dmamap_t desc_map;
|
||||
bus_dma_tag_t entry_tag;
|
||||
struct mbuf_head sendq;
|
||||
struct mtx lock;
|
||||
};
|
||||
|
||||
@ -224,9 +227,9 @@ enum {
|
||||
struct sge_qset {
|
||||
struct sge_rspq rspq;
|
||||
struct sge_fl fl[SGE_RXQ_PER_SET];
|
||||
struct sge_lro lro;
|
||||
struct lro_state lro;
|
||||
struct sge_txq txq[SGE_TXQ_PER_SET];
|
||||
unsigned long txq_stopped; /* which Tx queues are stopped */
|
||||
uint32_t txq_stopped; /* which Tx queues are stopped */
|
||||
uint64_t port_stats[SGE_PSTAT_MAX];
|
||||
struct port_info *port;
|
||||
int idx; /* qset # */
|
||||
@ -240,6 +243,7 @@ struct sge {
|
||||
struct adapter {
|
||||
device_t dev;
|
||||
int flags;
|
||||
TAILQ_ENTRY(adapter) adapter_entry;
|
||||
|
||||
/* PCI register resources */
|
||||
uint32_t regs_rid;
|
||||
@ -248,6 +252,7 @@ struct adapter {
|
||||
bus_space_tag_t bt;
|
||||
bus_size_t mmio_len;
|
||||
uint32_t link_width;
|
||||
|
||||
|
||||
/* DMA resources */
|
||||
bus_dma_tag_t parent_dmat;
|
||||
@ -293,10 +298,13 @@ struct adapter {
|
||||
|
||||
struct port_info port[MAX_NPORTS];
|
||||
device_t portdev[MAX_NPORTS];
|
||||
struct t3cdev tdev;
|
||||
struct toedev tdev;
|
||||
char fw_version[64];
|
||||
uint32_t open_device_map;
|
||||
uint32_t registered_device_map;
|
||||
struct mtx lock;
|
||||
driver_intr_t *cxgb_intr;
|
||||
int msi_count;
|
||||
};
|
||||
|
||||
struct t3_rx_mode {
|
||||
@ -384,6 +392,7 @@ int t3_os_pci_restore_state(struct adapter *adapter);
|
||||
void t3_os_link_changed(adapter_t *adapter, int port_id, int link_status,
|
||||
int speed, int duplex, int fc);
|
||||
void t3_sge_err_intr_handler(adapter_t *adapter);
|
||||
int t3_offload_tx(struct toedev *, struct mbuf *);
|
||||
void t3_os_ext_intr_handler(adapter_t *adapter);
|
||||
void t3_os_set_hw_addr(adapter_t *adapter, int port_idx, u8 hw_addr[]);
|
||||
int t3_mgmt_tx(adapter_t *adap, struct mbuf *m);
|
||||
@ -395,6 +404,7 @@ int t3_sge_alloc_qset(adapter_t *, uint32_t, int, int, const struct qset_params
|
||||
int, struct port_info *);
|
||||
void t3_free_sge_resources(adapter_t *);
|
||||
void t3_sge_start(adapter_t *);
|
||||
void t3_sge_stop(adapter_t *);
|
||||
void t3b_intr(void *data);
|
||||
void t3_intr_msi(void *data);
|
||||
void t3_intr_msix(void *data);
|
||||
@ -406,7 +416,7 @@ void t3_sge_deinit_sw(adapter_t *);
|
||||
void t3_rx_eth_lro(adapter_t *adap, struct sge_rspq *rq, struct mbuf *m,
|
||||
int ethpad, uint32_t rss_hash, uint32_t rss_csum, int lro);
|
||||
void t3_rx_eth(struct port_info *p, struct sge_rspq *rq, struct mbuf *m, int ethpad);
|
||||
void t3_sge_lro_flush_all(adapter_t *adap, struct sge_qset *qs);
|
||||
void t3_lro_flush(adapter_t *adap, struct sge_qset *qs, struct lro_state *state);
|
||||
|
||||
void t3_add_sysctls(adapter_t *sc);
|
||||
int t3_get_desc(const struct sge_qset *qs, unsigned int qnum, unsigned int idx,
|
||||
@ -437,6 +447,19 @@ txq_to_qset(struct sge_txq *q, int qidx)
|
||||
return container_of(q, struct sge_qset, txq[qidx]);
|
||||
}
|
||||
|
||||
static __inline struct adapter *
|
||||
tdev2adap(struct toedev *d)
|
||||
{
|
||||
return container_of(d, struct adapter, tdev);
|
||||
}
|
||||
|
||||
#undef container_of
|
||||
|
||||
#define OFFLOAD_DEVMAP_BIT 15
|
||||
static inline int offload_running(adapter_t *adapter)
|
||||
{
|
||||
return isset(&adapter->open_device_map, OFFLOAD_DEVMAP_BIT);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -9,11 +9,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.
|
||||
|
||||
|
@ -9,11 +9,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.
|
||||
|
||||
@ -68,7 +64,8 @@ enum {
|
||||
CH_IFCONF_GETREGS,
|
||||
CH_GETMIIREGS,
|
||||
CH_SETMIIREGS,
|
||||
|
||||
CH_SET_FILTER,
|
||||
CH_SET_HW_SCHED,
|
||||
};
|
||||
|
||||
struct ch_reg {
|
||||
@ -217,6 +214,7 @@ struct mii_data {
|
||||
|
||||
#define CHELSIO_SETREG _IOW('f', CH_SETREG, struct ch_reg)
|
||||
#define CHELSIO_GETREG _IOWR('f', CH_GETREG, struct ch_reg)
|
||||
#define CHELSIO_READ_TCAM_WORD _IOR('f', CH_READ_TCAM_WORD, struct ch_tcam)
|
||||
#define CHELSIO_GET_MEM _IOWR('f', CH_GET_MEM, struct ch_mem_range)
|
||||
#define CHELSIO_GET_SGE_CONTEXT _IOWR('f', CH_GET_SGE_CONTEXT, struct ch_cntxt)
|
||||
#define CHELSIO_GET_SGE_DESC _IOWR('f', CH_GET_SGE_DESC, struct ch_desc)
|
||||
@ -224,6 +222,8 @@ struct mii_data {
|
||||
#define CHELSIO_SET_QSET_PARAMS _IOW('f', CH_SET_QSET_PARAMS, struct ch_qset_params)
|
||||
#define CHELSIO_GET_QSET_NUM _IOWR('f', CH_GET_QSET_NUM, struct ch_reg)
|
||||
#define CHELSIO_SET_QSET_NUM _IOW('f', CH_SET_QSET_NUM, struct ch_reg)
|
||||
#define CHELSIO_GETMTUTAB _IOR('f', CH_GET_QSET_NUM, struct ch_mtus)
|
||||
#define CHELSIO_SETMTUTAB _IOW('f', CH_SET_QSET_NUM, struct ch_mtus)
|
||||
|
||||
|
||||
#define CHELSIO_SET_TRACE_FILTER _IOW('f', CH_SET_TRACE_FILTER, struct ch_trace)
|
||||
@ -231,4 +231,6 @@ struct mii_data {
|
||||
#define CHELSIO_IFCONF_GETREGS _IOWR('f', CH_IFCONF_GETREGS, struct ifconf_regs)
|
||||
#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_DEVUP _IO('f', CH_DEVUP)
|
||||
#endif
|
||||
|
670
sys/dev/cxgb/cxgb_l2t.c
Normal file
670
sys/dev/cxgb/cxgb_l2t.c
Normal file
@ -0,0 +1,670 @@
|
||||
/**************************************************************************
|
||||
|
||||
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.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/rwlock.h>
|
||||
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <net/if.h>
|
||||
#include <net/ethernet.h>
|
||||
#include <net/if_vlan_var.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/route.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/if_ether.h>
|
||||
|
||||
|
||||
#include <dev/cxgb/common/cxgb_common.h>
|
||||
#include <dev/cxgb/common/cxgb_regs.h>
|
||||
#include <dev/cxgb/common/cxgb_sge_defs.h>
|
||||
#include <dev/cxgb/common/cxgb_t3_cpl.h>
|
||||
#include <dev/cxgb/common/cxgb_firmware_exports.h>
|
||||
#include <dev/cxgb/common/jhash.h>
|
||||
#include <dev/cxgb/cxgb_offload.h>
|
||||
|
||||
#define VLAN_NONE 0xfff
|
||||
#define SDL(s) ((struct sockaddr_dl *)s)
|
||||
#define RT_ENADDR(rt) ((char *)LLADDR(SDL((rt))))
|
||||
#define rt_expire rt_rmx.rmx_expire
|
||||
|
||||
struct llinfo_arp {
|
||||
struct callout la_timer;
|
||||
struct rtentry *la_rt;
|
||||
struct mbuf *la_hold; /* last packet until resolved/timeout */
|
||||
u_short la_preempt; /* countdown for pre-expiry arps */
|
||||
u_short la_asked; /* # requests sent */
|
||||
};
|
||||
|
||||
/*
|
||||
* Module locking notes: There is a RW lock protecting the L2 table as a
|
||||
* whole plus a spinlock per L2T entry. Entry lookups and allocations happen
|
||||
* under the protection of the table lock, individual entry changes happen
|
||||
* while holding that entry's spinlock. The table lock nests outside the
|
||||
* entry locks. Allocations of new entries take the table lock as writers so
|
||||
* no other lookups can happen while allocating new entries. Entry updates
|
||||
* take the table lock as readers so multiple entries can be updated in
|
||||
* parallel. An L2T entry can be dropped by decrementing its reference count
|
||||
* and therefore can happen in parallel with entry allocation but no entry
|
||||
* can change state or increment its ref count during allocation as both of
|
||||
* these perform lookups.
|
||||
*/
|
||||
|
||||
static inline unsigned int
|
||||
vlan_prio(const struct l2t_entry *e)
|
||||
{
|
||||
return e->vlan >> 13;
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
arp_hash(u32 key, int ifindex, const struct l2t_data *d)
|
||||
{
|
||||
return jhash_2words(key, ifindex, 0) & (d->nentries - 1);
|
||||
}
|
||||
|
||||
static inline void
|
||||
neigh_replace(struct l2t_entry *e, struct rtentry *rt)
|
||||
{
|
||||
RT_LOCK(rt);
|
||||
RT_ADDREF(rt);
|
||||
RT_UNLOCK(rt);
|
||||
|
||||
if (e->neigh) {
|
||||
RT_LOCK(e->neigh);
|
||||
RT_REMREF(e->neigh);
|
||||
RT_UNLOCK(e->neigh);
|
||||
}
|
||||
e->neigh = rt;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up an L2T entry and send any packets waiting in the arp queue. The
|
||||
* supplied mbuf is used for the CPL_L2T_WRITE_REQ. Must be called with the
|
||||
* entry locked.
|
||||
*/
|
||||
static int
|
||||
setup_l2e_send_pending(struct toedev *dev, struct mbuf *m,
|
||||
struct l2t_entry *e)
|
||||
{
|
||||
struct cpl_l2t_write_req *req;
|
||||
|
||||
if (!m) {
|
||||
if ((m = m_gethdr(M_NOWAIT, MT_DATA)) == NULL)
|
||||
return (ENOMEM);
|
||||
}
|
||||
/*
|
||||
* XXX MH_ALIGN
|
||||
*/
|
||||
req = mtod(m, struct cpl_l2t_write_req *);
|
||||
req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
|
||||
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_L2T_WRITE_REQ, e->idx));
|
||||
req->params = htonl(V_L2T_W_IDX(e->idx) | V_L2T_W_IFF(e->smt_idx) |
|
||||
V_L2T_W_VLAN(e->vlan & EVL_VLID_MASK) |
|
||||
V_L2T_W_PRIO(vlan_prio(e)));
|
||||
|
||||
memcpy(e->dmac, RT_ENADDR(e->neigh), sizeof(e->dmac));
|
||||
memcpy(req->dst_mac, e->dmac, sizeof(req->dst_mac));
|
||||
m_set_priority(m, CPL_PRIORITY_CONTROL);
|
||||
cxgb_ofld_send(dev, m);
|
||||
while (e->arpq_head) {
|
||||
m = e->arpq_head;
|
||||
e->arpq_head = m->m_next;
|
||||
m->m_next = NULL;
|
||||
cxgb_ofld_send(dev, m);
|
||||
}
|
||||
e->arpq_tail = NULL;
|
||||
e->state = L2T_STATE_VALID;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a packet to the an L2T entry's queue of packets awaiting resolution.
|
||||
* Must be called with the entry's lock held.
|
||||
*/
|
||||
static inline void
|
||||
arpq_enqueue(struct l2t_entry *e, struct mbuf *m)
|
||||
{
|
||||
m->m_next = NULL;
|
||||
if (e->arpq_head)
|
||||
e->arpq_tail->m_next = m;
|
||||
else
|
||||
e->arpq_head = m;
|
||||
e->arpq_tail = m;
|
||||
}
|
||||
|
||||
int
|
||||
t3_l2t_send_slow(struct toedev *dev, struct mbuf *m,
|
||||
struct l2t_entry *e)
|
||||
{
|
||||
struct rtentry *rt;
|
||||
struct mbuf *m0;
|
||||
|
||||
if ((m0 = m_gethdr(M_NOWAIT, MT_DATA)) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
rt = e->neigh;
|
||||
|
||||
again:
|
||||
switch (e->state) {
|
||||
case L2T_STATE_STALE: /* entry is stale, kick off revalidation */
|
||||
arpresolve(rt->rt_ifp, rt, m0, rt->rt_gateway, RT_ENADDR(rt));
|
||||
mtx_lock(&e->lock);
|
||||
if (e->state == L2T_STATE_STALE)
|
||||
e->state = L2T_STATE_VALID;
|
||||
mtx_unlock(&e->lock);
|
||||
case L2T_STATE_VALID: /* fast-path, send the packet on */
|
||||
return cxgb_ofld_send(dev, m);
|
||||
case L2T_STATE_RESOLVING:
|
||||
mtx_lock(&e->lock);
|
||||
if (e->state != L2T_STATE_RESOLVING) { // ARP already completed
|
||||
mtx_unlock(&e->lock);
|
||||
goto again;
|
||||
}
|
||||
arpq_enqueue(e, m);
|
||||
mtx_unlock(&e->lock);
|
||||
|
||||
if ((m0 = m_gethdr(M_NOWAIT, MT_DATA)) == NULL)
|
||||
return (ENOMEM);
|
||||
/*
|
||||
* Only the first packet added to the arpq should kick off
|
||||
* resolution. However, because the m_gethdr below can fail,
|
||||
* we allow each packet added to the arpq to retry resolution
|
||||
* as a way of recovering from transient memory exhaustion.
|
||||
* A better way would be to use a work request to retry L2T
|
||||
* entries when there's no memory.
|
||||
*/
|
||||
if (arpresolve(rt->rt_ifp, rt, m0, rt->rt_gateway, RT_ENADDR(rt)) == 0) {
|
||||
|
||||
mtx_lock(&e->lock);
|
||||
if (e->arpq_head)
|
||||
setup_l2e_send_pending(dev, m, e);
|
||||
else
|
||||
m_freem(m);
|
||||
mtx_unlock(&e->lock);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
t3_l2t_send_event(struct toedev *dev, struct l2t_entry *e)
|
||||
{
|
||||
struct rtentry *rt;
|
||||
struct mbuf *m0;
|
||||
|
||||
if ((m0 = m_gethdr(M_NOWAIT, MT_DATA)) == NULL)
|
||||
return;
|
||||
|
||||
rt = e->neigh;
|
||||
again:
|
||||
switch (e->state) {
|
||||
case L2T_STATE_STALE: /* entry is stale, kick off revalidation */
|
||||
arpresolve(rt->rt_ifp, rt, m0, rt->rt_gateway, RT_ENADDR(rt));
|
||||
mtx_lock(&e->lock);
|
||||
if (e->state == L2T_STATE_STALE) {
|
||||
e->state = L2T_STATE_VALID;
|
||||
}
|
||||
mtx_unlock(&e->lock);
|
||||
return;
|
||||
case L2T_STATE_VALID: /* fast-path, send the packet on */
|
||||
return;
|
||||
case L2T_STATE_RESOLVING:
|
||||
mtx_lock(&e->lock);
|
||||
if (e->state != L2T_STATE_RESOLVING) { // ARP already completed
|
||||
mtx_unlock(&e->lock);
|
||||
goto again;
|
||||
}
|
||||
mtx_unlock(&e->lock);
|
||||
|
||||
if ((m0 = m_gethdr(M_NOWAIT, MT_DATA)) == NULL)
|
||||
return;
|
||||
/*
|
||||
* Only the first packet added to the arpq should kick off
|
||||
* resolution. However, because the alloc_skb below can fail,
|
||||
* we allow each packet added to the arpq to retry resolution
|
||||
* as a way of recovering from transient memory exhaustion.
|
||||
* A better way would be to use a work request to retry L2T
|
||||
* entries when there's no memory.
|
||||
*/
|
||||
arpresolve(rt->rt_ifp, rt, m0, rt->rt_gateway, RT_ENADDR(rt));
|
||||
|
||||
}
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Allocate a free L2T entry. Must be called with l2t_data.lock held.
|
||||
*/
|
||||
static struct l2t_entry *
|
||||
alloc_l2e(struct l2t_data *d)
|
||||
{
|
||||
struct l2t_entry *end, *e, **p;
|
||||
|
||||
if (!atomic_load_acq_int(&d->nfree))
|
||||
return NULL;
|
||||
|
||||
/* there's definitely a free entry */
|
||||
for (e = d->rover, end = &d->l2tab[d->nentries]; e != end; ++e)
|
||||
if (atomic_load_acq_int(&e->refcnt) == 0)
|
||||
goto found;
|
||||
|
||||
for (e = &d->l2tab[1]; atomic_load_acq_int(&e->refcnt); ++e) ;
|
||||
found:
|
||||
d->rover = e + 1;
|
||||
atomic_add_int(&d->nfree, -1);
|
||||
|
||||
/*
|
||||
* The entry we found may be an inactive entry that is
|
||||
* presently in the hash table. We need to remove it.
|
||||
*/
|
||||
if (e->state != L2T_STATE_UNUSED) {
|
||||
int hash = arp_hash(e->addr, e->ifindex, d);
|
||||
|
||||
for (p = &d->l2tab[hash].first; *p; p = &(*p)->next)
|
||||
if (*p == e) {
|
||||
*p = e->next;
|
||||
break;
|
||||
}
|
||||
e->state = L2T_STATE_UNUSED;
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when an L2T entry has no more users. The entry is left in the hash
|
||||
* table since it is likely to be reused but we also bump nfree to indicate
|
||||
* that the entry can be reallocated for a different neighbor. We also drop
|
||||
* the existing neighbor reference in case the neighbor is going away and is
|
||||
* waiting on our reference.
|
||||
*
|
||||
* Because entries can be reallocated to other neighbors once their ref count
|
||||
* drops to 0 we need to take the entry's lock to avoid races with a new
|
||||
* incarnation.
|
||||
*/
|
||||
void
|
||||
t3_l2e_free(struct l2t_data *d, struct l2t_entry *e)
|
||||
{
|
||||
mtx_lock(&e->lock);
|
||||
if (atomic_load_acq_int(&e->refcnt) == 0) { /* hasn't been recycled */
|
||||
if (e->neigh) {
|
||||
RT_LOCK(e->neigh);
|
||||
RT_REMREF(e->neigh);
|
||||
RT_UNLOCK(e->neigh);
|
||||
e->neigh = NULL;
|
||||
}
|
||||
}
|
||||
mtx_unlock(&e->lock);
|
||||
atomic_add_int(&d->nfree, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Update an L2T entry that was previously used for the same next hop as neigh.
|
||||
* Must be called with softirqs disabled.
|
||||
*/
|
||||
static inline void
|
||||
reuse_entry(struct l2t_entry *e, struct rtentry *neigh)
|
||||
{
|
||||
struct llinfo_arp *la;
|
||||
|
||||
la = (struct llinfo_arp *)neigh->rt_llinfo;
|
||||
|
||||
mtx_lock(&e->lock); /* avoid race with t3_l2t_free */
|
||||
if (neigh != e->neigh)
|
||||
neigh_replace(e, neigh);
|
||||
|
||||
if (memcmp(e->dmac, RT_ENADDR(neigh), sizeof(e->dmac)) ||
|
||||
(neigh->rt_expire > time_uptime))
|
||||
e->state = L2T_STATE_RESOLVING;
|
||||
else if (la->la_hold == NULL)
|
||||
e->state = L2T_STATE_VALID;
|
||||
else
|
||||
e->state = L2T_STATE_STALE;
|
||||
mtx_unlock(&e->lock);
|
||||
}
|
||||
|
||||
struct l2t_entry *
|
||||
t3_l2t_get(struct toedev *dev, struct rtentry *neigh,
|
||||
unsigned int smt_idx)
|
||||
{
|
||||
struct l2t_entry *e;
|
||||
struct l2t_data *d = L2DATA(dev);
|
||||
u32 addr = *(u32 *) rt_key(neigh);
|
||||
int ifidx = neigh->rt_ifp->if_index;
|
||||
int hash = arp_hash(addr, ifidx, d);
|
||||
|
||||
rw_wlock(&d->lock);
|
||||
for (e = d->l2tab[hash].first; e; e = e->next)
|
||||
if (e->addr == addr && e->ifindex == ifidx &&
|
||||
e->smt_idx == smt_idx) {
|
||||
l2t_hold(d, e);
|
||||
if (atomic_load_acq_int(&e->refcnt) == 1)
|
||||
reuse_entry(e, neigh);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Need to allocate a new entry */
|
||||
e = alloc_l2e(d);
|
||||
if (e) {
|
||||
mtx_lock(&e->lock); /* avoid race with t3_l2t_free */
|
||||
e->next = d->l2tab[hash].first;
|
||||
d->l2tab[hash].first = e;
|
||||
e->state = L2T_STATE_RESOLVING;
|
||||
e->addr = addr;
|
||||
e->ifindex = ifidx;
|
||||
e->smt_idx = smt_idx;
|
||||
atomic_store_rel_int(&e->refcnt, 1);
|
||||
neigh_replace(e, neigh);
|
||||
#ifdef notyet
|
||||
/*
|
||||
* XXX need to add accessor function for vlan tag
|
||||
*/
|
||||
if (neigh->rt_ifp->if_vlantrunk)
|
||||
e->vlan = VLAN_DEV_INFO(neigh->dev)->vlan_id;
|
||||
else
|
||||
#endif
|
||||
e->vlan = VLAN_NONE;
|
||||
mtx_unlock(&e->lock);
|
||||
}
|
||||
done:
|
||||
rw_wunlock(&d->lock);
|
||||
return e;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when address resolution fails for an L2T entry to handle packets
|
||||
* on the arpq head. If a packet specifies a failure handler it is invoked,
|
||||
* otherwise the packets is sent to the TOE.
|
||||
*
|
||||
* XXX: maybe we should abandon the latter behavior and just require a failure
|
||||
* handler.
|
||||
*/
|
||||
static void
|
||||
handle_failed_resolution(struct toedev *dev, struct mbuf *arpq)
|
||||
{
|
||||
|
||||
while (arpq) {
|
||||
struct mbuf *m = arpq;
|
||||
#ifdef notyet
|
||||
struct l2t_mbuf_cb *cb = L2T_MBUF_CB(m);
|
||||
#endif
|
||||
arpq = m->m_next;
|
||||
m->m_next = NULL;
|
||||
#ifdef notyet
|
||||
if (cb->arp_failure_handler)
|
||||
cb->arp_failure_handler(dev, m);
|
||||
else
|
||||
#endif
|
||||
cxgb_ofld_send(dev, m);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if defined(NETEVENT) || !defined(CONFIG_CHELSIO_T3_MODULE)
|
||||
/*
|
||||
* Called when the host's ARP layer makes a change to some entry that is
|
||||
* loaded into the HW L2 table.
|
||||
*/
|
||||
void
|
||||
t3_l2t_update(struct toedev *dev, struct rtentry *neigh)
|
||||
{
|
||||
struct l2t_entry *e;
|
||||
struct mbuf *arpq = NULL;
|
||||
struct l2t_data *d = L2DATA(dev);
|
||||
u32 addr = *(u32 *) rt_key(neigh);
|
||||
int ifidx = neigh->rt_ifp->if_index;
|
||||
int hash = arp_hash(addr, ifidx, d);
|
||||
struct llinfo_arp *la;
|
||||
|
||||
rw_rlock(&d->lock);
|
||||
for (e = d->l2tab[hash].first; e; e = e->next)
|
||||
if (e->addr == addr && e->ifindex == ifidx) {
|
||||
mtx_lock(&e->lock);
|
||||
goto found;
|
||||
}
|
||||
rw_runlock(&d->lock);
|
||||
return;
|
||||
|
||||
found:
|
||||
rw_runlock(&d->lock);
|
||||
if (atomic_load_acq_int(&e->refcnt)) {
|
||||
if (neigh != e->neigh)
|
||||
neigh_replace(e, neigh);
|
||||
|
||||
la = (struct llinfo_arp *)neigh->rt_llinfo;
|
||||
if (e->state == L2T_STATE_RESOLVING) {
|
||||
|
||||
if (la->la_asked >= 5 /* arp_maxtries */) {
|
||||
arpq = e->arpq_head;
|
||||
e->arpq_head = e->arpq_tail = NULL;
|
||||
} else if (la->la_hold == NULL)
|
||||
setup_l2e_send_pending(dev, NULL, e);
|
||||
} else {
|
||||
e->state = (la->la_hold == NULL) ?
|
||||
L2T_STATE_VALID : L2T_STATE_STALE;
|
||||
if (memcmp(e->dmac, RT_ENADDR(neigh), 6))
|
||||
setup_l2e_send_pending(dev, NULL, e);
|
||||
}
|
||||
}
|
||||
mtx_unlock(&e->lock);
|
||||
|
||||
if (arpq)
|
||||
handle_failed_resolution(dev, arpq);
|
||||
}
|
||||
#else
|
||||
/*
|
||||
* Called from a kprobe, interrupts are off.
|
||||
*/
|
||||
void
|
||||
t3_l2t_update(struct toedev *dev, struct rtentry *neigh)
|
||||
{
|
||||
struct l2t_entry *e;
|
||||
struct l2t_data *d = L2DATA(dev);
|
||||
u32 addr = *(u32 *) rt_key(neigh);
|
||||
int ifidx = neigh->dev->ifindex;
|
||||
int hash = arp_hash(addr, ifidx, d);
|
||||
|
||||
rw_rlock(&d->lock);
|
||||
for (e = d->l2tab[hash].first; e; e = e->next)
|
||||
if (e->addr == addr && e->ifindex == ifidx) {
|
||||
mtx_lock(&e->lock);
|
||||
if (atomic_load_acq_int(&e->refcnt)) {
|
||||
if (neigh != e->neigh)
|
||||
neigh_replace(e, neigh);
|
||||
e->tdev = dev;
|
||||
mod_timer(&e->update_timer, jiffies + 1);
|
||||
}
|
||||
mtx_unlock(&e->lock);
|
||||
break;
|
||||
}
|
||||
rw_runlock(&d->lock);
|
||||
}
|
||||
|
||||
static void
|
||||
update_timer_cb(unsigned long data)
|
||||
{
|
||||
struct mbuf *arpq = NULL;
|
||||
struct l2t_entry *e = (struct l2t_entry *)data;
|
||||
struct rtentry *neigh = e->neigh;
|
||||
struct toedev *dev = e->tdev;
|
||||
|
||||
barrier();
|
||||
if (!atomic_load_acq_int(&e->refcnt))
|
||||
return;
|
||||
|
||||
rw_rlock(&neigh->lock);
|
||||
mtx_lock(&e->lock);
|
||||
|
||||
if (atomic_load_acq_int(&e->refcnt)) {
|
||||
if (e->state == L2T_STATE_RESOLVING) {
|
||||
if (neigh->nud_state & NUD_FAILED) {
|
||||
arpq = e->arpq_head;
|
||||
e->arpq_head = e->arpq_tail = NULL;
|
||||
} else if (neigh_is_connected(neigh) && e->arpq_head)
|
||||
setup_l2e_send_pending(dev, NULL, e);
|
||||
} else {
|
||||
e->state = neigh_is_connected(neigh) ?
|
||||
L2T_STATE_VALID : L2T_STATE_STALE;
|
||||
if (memcmp(e->dmac, RT_ENADDR(neigh), sizeof(e->dmac)))
|
||||
setup_l2e_send_pending(dev, NULL, e);
|
||||
}
|
||||
}
|
||||
mtx_unlock(&e->lock);
|
||||
rw_runlock(&neigh->lock);
|
||||
|
||||
if (arpq)
|
||||
handle_failed_resolution(dev, arpq);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct l2t_data *
|
||||
t3_init_l2t(unsigned int l2t_capacity)
|
||||
{
|
||||
struct l2t_data *d;
|
||||
int i, size = sizeof(*d) + l2t_capacity * sizeof(struct l2t_entry);
|
||||
|
||||
d = cxgb_alloc_mem(size);
|
||||
if (!d)
|
||||
return NULL;
|
||||
|
||||
d->nentries = l2t_capacity;
|
||||
d->rover = &d->l2tab[1]; /* entry 0 is not used */
|
||||
atomic_store_rel_int(&d->nfree, l2t_capacity - 1);
|
||||
rw_init(&d->lock, "L2T");
|
||||
|
||||
for (i = 0; i < l2t_capacity; ++i) {
|
||||
d->l2tab[i].idx = i;
|
||||
d->l2tab[i].state = L2T_STATE_UNUSED;
|
||||
mtx_init(&d->l2tab[i].lock, "L2TAB", NULL, MTX_DEF);
|
||||
atomic_store_rel_int(&d->l2tab[i].refcnt, 0);
|
||||
#ifndef NETEVENT
|
||||
#ifdef CONFIG_CHELSIO_T3_MODULE
|
||||
setup_timer(&d->l2tab[i].update_timer, update_timer_cb,
|
||||
(unsigned long)&d->l2tab[i]);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
void
|
||||
t3_free_l2t(struct l2t_data *d)
|
||||
{
|
||||
#ifndef NETEVENT
|
||||
#ifdef CONFIG_CHELSIO_T3_MODULE
|
||||
int i;
|
||||
|
||||
/* Stop all L2T timers */
|
||||
for (i = 0; i < d->nentries; ++i)
|
||||
del_timer_sync(&d->l2tab[i].update_timer);
|
||||
#endif
|
||||
#endif
|
||||
cxgb_free_mem(d);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
#include <linux/module.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
|
||||
static inline void *
|
||||
l2t_get_idx(struct seq_file *seq, loff_t pos)
|
||||
{
|
||||
struct l2t_data *d = seq->private;
|
||||
|
||||
return pos >= d->nentries ? NULL : &d->l2tab[pos];
|
||||
}
|
||||
|
||||
static void *
|
||||
l2t_seq_start(struct seq_file *seq, loff_t *pos)
|
||||
{
|
||||
return *pos ? l2t_get_idx(seq, *pos) : SEQ_START_TOKEN;
|
||||
}
|
||||
|
||||
static void *
|
||||
l2t_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
||||
{
|
||||
v = l2t_get_idx(seq, *pos + 1);
|
||||
if (v)
|
||||
++*pos;
|
||||
return v;
|
||||
}
|
||||
|
||||
static void
|
||||
l2t_seq_stop(struct seq_file *seq, void *v)
|
||||
{
|
||||
}
|
||||
|
||||
static char
|
||||
l2e_state(const struct l2t_entry *e)
|
||||
{
|
||||
switch (e->state) {
|
||||
case L2T_STATE_VALID: return 'V'; /* valid, fast-path entry */
|
||||
case L2T_STATE_STALE: return 'S'; /* needs revalidation, but usable */
|
||||
case L2T_STATE_RESOLVING:
|
||||
return e->arpq_head ? 'A' : 'R';
|
||||
default:
|
||||
return 'U';
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
l2t_seq_show(struct seq_file *seq, void *v)
|
||||
{
|
||||
if (v == SEQ_START_TOKEN)
|
||||
seq_puts(seq, "Index IP address Ethernet address VLAN "
|
||||
"Prio State Users SMTIDX Port\n");
|
||||
else {
|
||||
char ip[20];
|
||||
struct l2t_entry *e = v;
|
||||
|
||||
mtx_lock(&e->lock);
|
||||
sprintf(ip, "%u.%u.%u.%u", NIPQUAD(e->addr));
|
||||
seq_printf(seq, "%-5u %-15s %02x:%02x:%02x:%02x:%02x:%02x %4d"
|
||||
" %3u %c %7u %4u %s\n",
|
||||
e->idx, ip, e->dmac[0], e->dmac[1], e->dmac[2],
|
||||
e->dmac[3], e->dmac[4], e->dmac[5],
|
||||
e->vlan & EVL_VLID_MASK, vlan_prio(e),
|
||||
l2e_state(e), atomic_load_acq_int(&e->refcnt), e->smt_idx,
|
||||
e->neigh ? e->neigh->dev->name : "");
|
||||
mtx_unlock(&e->lock);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
154
sys/dev/cxgb/cxgb_l2t.h
Normal file
154
sys/dev/cxgb/cxgb_l2t.h
Normal file
@ -0,0 +1,154 @@
|
||||
/**************************************************************************
|
||||
|
||||
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$
|
||||
|
||||
***************************************************************************/
|
||||
#ifndef _CHELSIO_L2T_H
|
||||
#define _CHELSIO_L2T_H
|
||||
|
||||
#include <dev/cxgb/ulp/toecore/toedev.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/rwlock.h>
|
||||
|
||||
enum {
|
||||
L2T_STATE_VALID, /* entry is up to date */
|
||||
L2T_STATE_STALE, /* entry may be used but needs revalidation */
|
||||
L2T_STATE_RESOLVING, /* entry needs address resolution */
|
||||
L2T_STATE_UNUSED /* entry not in use */
|
||||
};
|
||||
|
||||
/*
|
||||
* Each L2T entry plays multiple roles. First of all, it keeps state for the
|
||||
* corresponding entry of the HW L2 table and maintains a queue of offload
|
||||
* packets awaiting address resolution. Second, it is a node of a hash table
|
||||
* chain, where the nodes of the chain are linked together through their next
|
||||
* pointer. Finally, each node is a bucket of a hash table, pointing to the
|
||||
* first element in its chain through its first pointer.
|
||||
*/
|
||||
struct l2t_entry {
|
||||
uint16_t state; /* entry state */
|
||||
uint16_t idx; /* entry index */
|
||||
uint32_t addr; /* dest IP address */
|
||||
int ifindex; /* neighbor's net_device's ifindex */
|
||||
uint16_t smt_idx; /* SMT index */
|
||||
uint16_t vlan; /* VLAN TCI (id: bits 0-11, prio: 13-15 */
|
||||
struct rtentry *neigh; /* associated neighbour */
|
||||
struct l2t_entry *first; /* start of hash chain */
|
||||
struct l2t_entry *next; /* next l2t_entry on chain */
|
||||
struct mbuf *arpq_head; /* queue of packets awaiting resolution */
|
||||
struct mbuf *arpq_tail;
|
||||
struct mtx lock;
|
||||
volatile uint32_t refcnt; /* entry reference count */
|
||||
uint8_t dmac[6]; /* neighbour's MAC address */
|
||||
#ifndef NETEVENT
|
||||
#ifdef CONFIG_CHELSIO_T3_MODULE
|
||||
struct timer_list update_timer;
|
||||
struct toedev *tdev;
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
struct l2t_data {
|
||||
unsigned int nentries; /* number of entries */
|
||||
struct l2t_entry *rover; /* starting point for next allocation */
|
||||
volatile uint32_t nfree; /* number of free entries */
|
||||
struct rwlock lock;
|
||||
struct l2t_entry l2tab[0];
|
||||
};
|
||||
|
||||
typedef void (*arp_failure_handler_func)(struct toedev *dev,
|
||||
struct mbuf *m);
|
||||
|
||||
/*
|
||||
* Callback stored in an skb to handle address resolution failure.
|
||||
*/
|
||||
struct l2t_mbuf_cb {
|
||||
arp_failure_handler_func arp_failure_handler;
|
||||
};
|
||||
|
||||
/*
|
||||
* XXX
|
||||
*/
|
||||
#define L2T_MBUF_CB(skb) ((struct l2t_mbuf_cb *)(skb)->cb)
|
||||
|
||||
|
||||
static __inline void set_arp_failure_handler(struct mbuf *m,
|
||||
arp_failure_handler_func hnd)
|
||||
{
|
||||
#if 0
|
||||
L2T_SKB_CB(skb)->arp_failure_handler = hnd;
|
||||
#endif
|
||||
panic("implement me");
|
||||
}
|
||||
|
||||
/*
|
||||
* Getting to the L2 data from an offload device.
|
||||
*/
|
||||
#define L2DATA(dev) ((dev)->l2opt)
|
||||
|
||||
void t3_l2e_free(struct l2t_data *d, struct l2t_entry *e);
|
||||
void t3_l2t_update(struct toedev *dev, struct rtentry *ifp);
|
||||
struct l2t_entry *t3_l2t_get(struct toedev *dev, struct rtentry *neigh,
|
||||
unsigned int smt_idx);
|
||||
int t3_l2t_send_slow(struct toedev *dev, struct mbuf *m,
|
||||
struct l2t_entry *e);
|
||||
void t3_l2t_send_event(struct toedev *dev, struct l2t_entry *e);
|
||||
struct l2t_data *t3_init_l2t(unsigned int l2t_capacity);
|
||||
void t3_free_l2t(struct l2t_data *d);
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
int t3_l2t_proc_setup(struct proc_dir_entry *dir, struct l2t_data *d);
|
||||
void t3_l2t_proc_free(struct proc_dir_entry *dir);
|
||||
#else
|
||||
#define l2t_proc_setup(dir, d) 0
|
||||
#define l2t_proc_free(dir)
|
||||
#endif
|
||||
|
||||
int cxgb_ofld_send(struct toedev *dev, struct mbuf *m);
|
||||
|
||||
static inline int l2t_send(struct toedev *dev, struct mbuf *m,
|
||||
struct l2t_entry *e)
|
||||
{
|
||||
if (__predict_true(e->state == L2T_STATE_VALID))
|
||||
return cxgb_ofld_send(dev, m);
|
||||
return t3_l2t_send_slow(dev, m, e);
|
||||
}
|
||||
|
||||
static inline void l2t_release(struct l2t_data *d, struct l2t_entry *e)
|
||||
{
|
||||
if (atomic_fetchadd_int(&e->refcnt, -1) == 1)
|
||||
t3_l2e_free(d, e);
|
||||
}
|
||||
|
||||
static inline void l2t_hold(struct l2t_data *d, struct l2t_entry *e)
|
||||
{
|
||||
if (atomic_fetchadd_int(&e->refcnt, 1) == 1) /* 0 -> 1 transition */
|
||||
atomic_add_int(&d->nfree, 1);
|
||||
}
|
||||
|
||||
#endif
|
@ -9,11 +9,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.
|
||||
|
||||
@ -82,51 +78,40 @@ __FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
|
||||
#define IPH_OFFSET (2 + sizeof (struct cpl_rx_pkt) + ETHER_HDR_LEN)
|
||||
#define LRO_SESSION_IDX_HINT_HASH(hash) (hash & (MAX_LRO_PER_QSET - 1))
|
||||
#define LRO_IDX_INC(idx) idx = (idx + 1) & (MAX_LRO_PER_QSET - 1)
|
||||
|
||||
static __inline struct sge_lro_session *
|
||||
lro_session(struct sge_lro *l, int idx)
|
||||
{
|
||||
return l->s + idx;
|
||||
}
|
||||
#define LRO_SESSION_IDX_HINT_HASH(hash) (hash & (MAX_LRO_SES - 1))
|
||||
#define LRO_IDX_INC(idx) idx = (idx + 1) & (MAX_LRO_SES - 1)
|
||||
|
||||
static __inline int
|
||||
lro_match_session(struct sge_lro_session *s,
|
||||
struct ip *ih, struct tcphdr *th)
|
||||
lro_match(struct mbuf *m, struct ip *ih, struct tcphdr *th)
|
||||
{
|
||||
struct ip *sih = (struct ip *)(s->m->m_data + IPH_OFFSET);
|
||||
struct ip *sih = (struct ip *)(m->m_data + IPH_OFFSET);
|
||||
struct tcphdr *sth = (struct tcphdr *) (sih + 1);
|
||||
|
||||
/*
|
||||
* Linux driver doesn't include destination port check --
|
||||
* need to find out why XXX
|
||||
* Why don't we check dest ports?
|
||||
*/
|
||||
return (*(uint32_t *)&th->th_sport == *(uint32_t *)&sth->th_sport &&
|
||||
*(uint32_t *)&th->th_dport == *(uint32_t *)&sth->th_dport &&
|
||||
ih->ip_src.s_addr == ih->ip_src.s_addr &&
|
||||
ih->ip_dst.s_addr == sih->ip_dst.s_addr);
|
||||
}
|
||||
|
||||
static __inline struct sge_lro_session *
|
||||
lro_find_session(struct sge_lro *l, int idx, struct ip *ih, struct tcphdr *th)
|
||||
static __inline struct t3_lro_session *
|
||||
lro_lookup(struct lro_state *l, int idx, struct ip *ih, struct tcphdr *th)
|
||||
{
|
||||
struct sge_lro_session *s;
|
||||
int active = 0;
|
||||
struct t3_lro_session *s = NULL;
|
||||
int active = l->nactive;
|
||||
|
||||
while (active < l->num_active) {
|
||||
s = lro_session(l, idx);
|
||||
if (s->m) {
|
||||
if (lro_match_session(s, ih, th)) {
|
||||
l->last_s = s;
|
||||
return s;
|
||||
}
|
||||
active++;
|
||||
while (active) {
|
||||
s = &l->sess[idx];
|
||||
if (s->head) {
|
||||
if (lro_match(s->head, ih, th))
|
||||
break;
|
||||
active--;
|
||||
}
|
||||
LRO_IDX_INC(idx);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return (s);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
@ -174,7 +159,7 @@ can_lro_tcpsegment(struct tcphdr *th)
|
||||
}
|
||||
|
||||
static __inline void
|
||||
lro_new_session_init(struct sge_lro_session *s, struct mbuf *m)
|
||||
lro_new_session_init(struct t3_lro_session *s, struct mbuf *m)
|
||||
{
|
||||
struct ip *ih = (struct ip *)(m->m_data + IPH_OFFSET);
|
||||
struct tcphdr *th = (struct tcphdr *) (ih + 1);
|
||||
@ -182,7 +167,7 @@ lro_new_session_init(struct sge_lro_session *s, struct mbuf *m)
|
||||
|
||||
DPRINTF("%s(s=%p, m=%p)\n", __FUNCTION__, s, m);
|
||||
|
||||
s->m = m;
|
||||
s->head = m;
|
||||
|
||||
MBUF_HEADER_CHECK(m);
|
||||
s->ip_len = ip_len;
|
||||
@ -191,10 +176,10 @@ lro_new_session_init(struct sge_lro_session *s, struct mbuf *m)
|
||||
}
|
||||
|
||||
static void
|
||||
lro_flush_session(struct sge_qset *qs, struct sge_lro_session *s, struct mbuf *m)
|
||||
lro_flush_session(struct sge_qset *qs, struct t3_lro_session *s, struct mbuf *m)
|
||||
{
|
||||
struct sge_lro *l = &qs->lro;
|
||||
struct mbuf *sm = s->m;
|
||||
struct lro_state *l = &qs->lro;
|
||||
struct mbuf *sm = s->head;
|
||||
struct ip *ih = (struct ip *)(sm->m_data + IPH_OFFSET);
|
||||
|
||||
|
||||
@ -216,33 +201,33 @@ lro_flush_session(struct sge_qset *qs, struct sge_lro_session *s, struct mbuf *m
|
||||
t3_rx_eth(qs->port, &qs->rspq, sm, 2);
|
||||
|
||||
if (m) {
|
||||
s->m = m;
|
||||
s->head = m;
|
||||
lro_new_session_init(s, m);
|
||||
} else {
|
||||
s->m = NULL;
|
||||
l->num_active--;
|
||||
s->head = NULL;
|
||||
l->nactive--;
|
||||
}
|
||||
|
||||
qs->port_stats[SGE_PSTATS_LRO_FLUSHED]++;
|
||||
}
|
||||
|
||||
static __inline struct sge_lro_session *
|
||||
static __inline struct t3_lro_session *
|
||||
lro_new_session(struct sge_qset *qs, struct mbuf *m, uint32_t rss_hash)
|
||||
{
|
||||
struct sge_lro *l = &qs->lro;
|
||||
struct lro_state *l = &qs->lro;
|
||||
int idx = LRO_SESSION_IDX_HINT_HASH(rss_hash);
|
||||
struct sge_lro_session *s = lro_session(l, idx);
|
||||
struct t3_lro_session *s = &l->sess[idx];
|
||||
|
||||
DPRINTF("%s(qs=%p, m=%p, rss_hash=0x%x)\n", __FUNCTION__,
|
||||
qs, m, rss_hash);
|
||||
|
||||
if (__predict_true(!s->m))
|
||||
if (__predict_true(!s->head))
|
||||
goto done;
|
||||
|
||||
if (l->num_active > MAX_LRO_PER_QSET)
|
||||
if (l->nactive > MAX_LRO_SES)
|
||||
panic("MAX_LRO_PER_QSET exceeded");
|
||||
|
||||
if (l->num_active == MAX_LRO_PER_QSET) {
|
||||
if (l->nactive == MAX_LRO_SES) {
|
||||
lro_flush_session(qs, s, m);
|
||||
qs->port_stats[SGE_PSTATS_LRO_X_STREAMS]++;
|
||||
return s;
|
||||
@ -250,21 +235,21 @@ lro_new_session(struct sge_qset *qs, struct mbuf *m, uint32_t rss_hash)
|
||||
|
||||
while (1) {
|
||||
LRO_IDX_INC(idx);
|
||||
s = lro_session(l, idx);
|
||||
if (!s->m)
|
||||
s = &l->sess[idx];
|
||||
if (!s->head)
|
||||
break;
|
||||
}
|
||||
done:
|
||||
lro_new_session_init(s, m);
|
||||
l->num_active++;
|
||||
l->nactive++;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
static __inline int
|
||||
lro_update_session(struct sge_lro_session *s, struct mbuf *m)
|
||||
lro_update_session(struct t3_lro_session *s, struct mbuf *m)
|
||||
{
|
||||
struct mbuf *sm = s->m;
|
||||
struct mbuf *sm = s->head;
|
||||
struct cpl_rx_pkt *cpl = (struct cpl_rx_pkt *)(sm->m_data + 2);
|
||||
struct cpl_rx_pkt *ncpl = (struct cpl_rx_pkt *)(m->m_data + 2);
|
||||
struct ip *nih = (struct ip *)(m->m_data + IPH_OFFSET);
|
||||
@ -354,7 +339,7 @@ t3_rx_eth_lro(adapter_t *adap, struct sge_rspq *rq, struct mbuf *m,
|
||||
struct ether_header *eh = (struct ether_header *)(cpl + 1);
|
||||
struct ip *ih;
|
||||
struct tcphdr *th;
|
||||
struct sge_lro_session *s = NULL;
|
||||
struct t3_lro_session *s = NULL;
|
||||
struct port_info *pi = qs->port;
|
||||
|
||||
if (lro == 0)
|
||||
@ -369,7 +354,7 @@ t3_rx_eth_lro(adapter_t *adap, struct sge_rspq *rq, struct mbuf *m,
|
||||
ih = (struct ip *)(eh + 1);
|
||||
th = (struct tcphdr *)(ih + 1);
|
||||
|
||||
s = lro_find_session(&qs->lro,
|
||||
s = lro_lookup(&qs->lro,
|
||||
LRO_SESSION_IDX_HINT_HASH(rss_hash), ih, th);
|
||||
|
||||
if (__predict_false(!can_lro_tcpsegment(th))) {
|
||||
@ -380,7 +365,7 @@ t3_rx_eth_lro(adapter_t *adap, struct sge_rspq *rq, struct mbuf *m,
|
||||
if (lro_update_session(s, m)) {
|
||||
lro_flush_session(qs, s, m);
|
||||
}
|
||||
if (__predict_false(s->m->m_pkthdr.len + pi->ifp->if_mtu > 65535)) {
|
||||
if (__predict_false(s->head->m_pkthdr.len + pi->ifp->if_mtu > 65535)) {
|
||||
lro_flush_session(qs, s, NULL);
|
||||
}
|
||||
}
|
||||
@ -398,21 +383,15 @@ no_lro:
|
||||
}
|
||||
|
||||
void
|
||||
t3_sge_lro_flush_all(adapter_t *adap, struct sge_qset *qs)
|
||||
t3_lro_flush(adapter_t *adap, struct sge_qset *qs, struct lro_state *state)
|
||||
{
|
||||
struct sge_lro *l = &qs->lro;
|
||||
struct sge_lro_session *s = l->last_s;
|
||||
int active = 0, idx = 0, num_active = l->num_active;
|
||||
unsigned int idx = state->active_idx;
|
||||
|
||||
if (__predict_false(!s))
|
||||
s = lro_session(l, idx);
|
||||
|
||||
while (active < num_active) {
|
||||
if (s->m) {
|
||||
while (state->nactive) {
|
||||
struct t3_lro_session *s = &state->sess[idx];
|
||||
|
||||
if (s->head)
|
||||
lro_flush_session(qs, s, NULL);
|
||||
active++;
|
||||
}
|
||||
LRO_IDX_INC(idx);
|
||||
s = lro_session(l, idx);
|
||||
}
|
||||
}
|
||||
|
@ -9,11 +9,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.
|
||||
|
||||
@ -79,6 +75,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <dev/cxgb/cxgb_osdep.h>
|
||||
#include <dev/cxgb/common/cxgb_common.h>
|
||||
#include <dev/cxgb/cxgb_ioctl.h>
|
||||
#include <dev/cxgb/cxgb_offload.h>
|
||||
#include <dev/cxgb/common/cxgb_regs.h>
|
||||
#include <dev/cxgb/common/cxgb_t3_cpl.h>
|
||||
#include <dev/cxgb/common/cxgb_firmware_exports.h>
|
||||
@ -103,6 +100,7 @@ static void cxgb_media_status(struct ifnet *, struct ifmediareq *);
|
||||
static int setup_sge_qsets(adapter_t *);
|
||||
static void cxgb_async_intr(void *);
|
||||
static void cxgb_ext_intr_handler(void *, int);
|
||||
static void cxgb_down(struct adapter *sc);
|
||||
static void cxgb_tick(void *);
|
||||
static void setup_rss(adapter_t *sc);
|
||||
|
||||
@ -117,6 +115,10 @@ static __inline void reg_block_dump(struct adapter *ap, uint8_t *buf, unsigned i
|
||||
unsigned int end);
|
||||
static void cxgb_get_regs(adapter_t *sc, struct ifconf_regs *regs, uint8_t *buf);
|
||||
static int cxgb_get_regs_len(void);
|
||||
static int offload_open(struct port_info *pi);
|
||||
static int offload_close(struct toedev *tdev);
|
||||
|
||||
|
||||
|
||||
static device_method_t cxgb_controller_methods[] = {
|
||||
DEVMETHOD(device_probe, cxgb_controller_probe),
|
||||
@ -179,14 +181,27 @@ extern int collapse_mbufs;
|
||||
*/
|
||||
static int msi_allowed = 2;
|
||||
TUNABLE_INT("hw.cxgb.msi_allowed", &msi_allowed);
|
||||
|
||||
SYSCTL_NODE(_hw, OID_AUTO, cxgb, CTLFLAG_RD, 0, "CXGB driver parameters");
|
||||
SYSCTL_UINT(_hw_cxgb, OID_AUTO, msi_allowed, CTLFLAG_RDTUN, &msi_allowed, 0,
|
||||
"MSI-X, MSI, INTx selector");
|
||||
|
||||
/*
|
||||
* Multiple queues need further tuning
|
||||
* The driver enables offload as a default.
|
||||
* To disable it, use ofld_disable = 1.
|
||||
*/
|
||||
static int ofld_disable = 0;
|
||||
TUNABLE_INT("hw.cxgb.ofld_disable", &ofld_disable);
|
||||
SYSCTL_UINT(_hw_cxgb, OID_AUTO, ofld_disable, CTLFLAG_RDTUN, &ofld_disable, 0,
|
||||
"disable ULP offload");
|
||||
|
||||
/*
|
||||
* The driver uses an auto-queue algorithm by default.
|
||||
* To disable it and force a single queue-set per port, use singleq = 1.
|
||||
*/
|
||||
static int singleq = 1;
|
||||
TUNABLE_INT("hw.cxgb.singleq", &singleq);
|
||||
SYSCTL_UINT(_hw_cxgb, OID_AUTO, singleq, CTLFLAG_RDTUN, &singleq, 0,
|
||||
"use a single queue-set per port");
|
||||
|
||||
enum {
|
||||
MAX_TXQ_ENTRIES = 16384,
|
||||
@ -272,7 +287,7 @@ cxgb_controller_probe(device_t dev)
|
||||
}
|
||||
|
||||
static int
|
||||
cxgb_fw_download(adapter_t *sc, device_t dev)
|
||||
upgrade_fw(adapter_t *sc)
|
||||
{
|
||||
char buf[32];
|
||||
#ifdef FIRMWARE_LATEST
|
||||
@ -282,15 +297,14 @@ cxgb_fw_download(adapter_t *sc, device_t dev)
|
||||
#endif
|
||||
int status;
|
||||
|
||||
snprintf(&buf[0], sizeof(buf), "t3fw%d%d", FW_VERSION_MAJOR,
|
||||
FW_VERSION_MINOR);
|
||||
snprintf(&buf[0], sizeof(buf), "t3fw%d%d%d", FW_VERSION_MAJOR,
|
||||
FW_VERSION_MINOR, FW_VERSION_MICRO);
|
||||
|
||||
fw = firmware_get(buf);
|
||||
|
||||
|
||||
if (fw == NULL) {
|
||||
device_printf(dev, "Could not find firmware image %s\n", buf);
|
||||
return ENOENT;
|
||||
device_printf(sc->dev, "Could not find firmware image %s\n", buf);
|
||||
return (ENOENT);
|
||||
}
|
||||
|
||||
status = t3_load_fw(sc, (const uint8_t *)fw->data, fw->datasize);
|
||||
@ -300,7 +314,6 @@ cxgb_fw_download(adapter_t *sc, device_t dev)
|
||||
return (status);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
cxgb_controller_attach(device_t dev)
|
||||
{
|
||||
@ -308,13 +321,14 @@ cxgb_controller_attach(device_t dev)
|
||||
device_t child;
|
||||
const struct adapter_info *ai;
|
||||
struct adapter *sc;
|
||||
int i, reg, msi_needed, msi_count = 0, error = 0;
|
||||
int i, reg, msi_needed, error = 0;
|
||||
uint32_t vers;
|
||||
int port_qsets = 1;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
sc->dev = dev;
|
||||
|
||||
sc->msi_count = 0;
|
||||
|
||||
/* find the PCIe link width and set max read request to 4KB*/
|
||||
if (pci_find_extcap(dev, PCIY_EXPRESS, ®) == 0) {
|
||||
uint16_t lnk, pectl;
|
||||
@ -370,13 +384,14 @@ cxgb_controller_attach(device_t dev)
|
||||
(sc->msix_regs_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
|
||||
&sc->msix_regs_rid, RF_ACTIVE)) != NULL) {
|
||||
|
||||
msi_needed = msi_count = SGE_MSIX_COUNT;
|
||||
msi_needed = sc->msi_count = SGE_MSIX_COUNT;
|
||||
|
||||
if ((pci_alloc_msix(dev, &msi_count) != 0) ||
|
||||
(msi_count != msi_needed)) {
|
||||
device_printf(dev, "msix allocation failed"
|
||||
" will try msi\n");
|
||||
msi_count = 0;
|
||||
if (((error = pci_alloc_msix(dev, &sc->msi_count)) != 0) ||
|
||||
(sc->msi_count != msi_needed)) {
|
||||
device_printf(dev, "msix allocation failed - msi_count = %d"
|
||||
" msi_needed=%d will try msi err=%d\n", sc->msi_count,
|
||||
msi_needed, error);
|
||||
sc->msi_count = 0;
|
||||
pci_release_msi(dev);
|
||||
bus_release_resource(dev, SYS_RES_MEMORY,
|
||||
sc->msix_regs_rid, sc->msix_regs_res);
|
||||
@ -387,11 +402,11 @@ cxgb_controller_attach(device_t dev)
|
||||
}
|
||||
}
|
||||
|
||||
if ((msi_allowed >= 1) && (msi_count == 0)) {
|
||||
msi_count = 1;
|
||||
if (pci_alloc_msi(dev, &msi_count)) {
|
||||
if ((msi_allowed >= 1) && (sc->msi_count == 0)) {
|
||||
sc->msi_count = 1;
|
||||
if (pci_alloc_msi(dev, &sc->msi_count)) {
|
||||
device_printf(dev, "alloc msi failed - will try INTx\n");
|
||||
msi_count = 0;
|
||||
sc->msi_count = 0;
|
||||
pci_release_msi(dev);
|
||||
} else {
|
||||
sc->flags |= USING_MSI;
|
||||
@ -400,7 +415,7 @@ cxgb_controller_attach(device_t dev)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (msi_count == 0) {
|
||||
if (sc->msi_count == 0) {
|
||||
device_printf(dev, "using line interrupts\n");
|
||||
sc->irq_rid = 0;
|
||||
cxgb_intr = t3b_intr;
|
||||
@ -432,22 +447,14 @@ cxgb_controller_attach(device_t dev)
|
||||
/*
|
||||
* Warn user that a firmware update will be attempted in init.
|
||||
*/
|
||||
device_printf(dev, "firmware needs to be updated to version %d.%d\n",
|
||||
FW_VERSION_MAJOR, FW_VERSION_MINOR);
|
||||
device_printf(dev, "firmware needs to be updated to version %d.%d.%d\n",
|
||||
FW_VERSION_MAJOR, FW_VERSION_MINOR, FW_VERSION_MICRO);
|
||||
sc->flags &= ~FW_UPTODATE;
|
||||
} else {
|
||||
sc->flags |= FW_UPTODATE;
|
||||
}
|
||||
|
||||
if (t3_init_hw(sc, 0) != 0) {
|
||||
device_printf(dev, "hw initialization failed\n");
|
||||
error = ENXIO;
|
||||
goto out;
|
||||
}
|
||||
t3_write_reg(sc, A_ULPRX_TDDP_PSZ, V_HPZ0(PAGE_SHIFT - 12));
|
||||
|
||||
|
||||
if ((singleq == 0) && (sc->flags & USING_MSIX))
|
||||
if ((sc->flags & USING_MSIX) && !singleq)
|
||||
port_qsets = min((SGE_QSETS/(sc)->params.nports), mp_ncpus);
|
||||
|
||||
/*
|
||||
@ -468,52 +475,32 @@ cxgb_controller_attach(device_t dev)
|
||||
device_set_softc(child, &sc->port[i]);
|
||||
}
|
||||
if ((error = bus_generic_attach(dev)) != 0)
|
||||
goto out;;
|
||||
|
||||
if ((error = setup_sge_qsets(sc)) != 0)
|
||||
goto out;
|
||||
|
||||
setup_rss(sc);
|
||||
|
||||
/* If it's MSI or INTx, allocate a single interrupt for everything */
|
||||
if ((sc->flags & USING_MSIX) == 0) {
|
||||
if ((sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
|
||||
&sc->irq_rid, RF_SHAREABLE | RF_ACTIVE)) == NULL) {
|
||||
device_printf(dev, "Cannot allocate interrupt rid=%d\n", sc->irq_rid);
|
||||
error = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
device_printf(dev, "allocated irq_res=%p\n", sc->irq_res);
|
||||
|
||||
if (bus_setup_intr(dev, sc->irq_res, INTR_MPSAFE|INTR_TYPE_NET,
|
||||
#ifdef INTR_FILTERS
|
||||
NULL,
|
||||
#endif
|
||||
cxgb_intr, sc, &sc->intr_tag)) {
|
||||
device_printf(dev, "Cannot set up interrupt\n");
|
||||
error = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
cxgb_setup_msix(sc, msi_count);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX need to poll for link status
|
||||
*/
|
||||
sc->params.stats_update_period = 1;
|
||||
|
||||
/* initialize sge private state */
|
||||
t3_sge_init_sw(sc);
|
||||
|
||||
t3_led_ready(sc);
|
||||
|
||||
|
||||
cxgb_offload_init();
|
||||
if (is_offload(sc)) {
|
||||
setbit(&sc->registered_device_map, OFFLOAD_DEVMAP_BIT);
|
||||
cxgb_adapter_ofld(sc);
|
||||
}
|
||||
error = t3_get_fw_version(sc, &vers);
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
snprintf(&sc->fw_version[0], sizeof(sc->fw_version), "%d.%d", G_FW_VERSION_MAJOR(vers),
|
||||
G_FW_VERSION_MINOR(vers));
|
||||
|
||||
snprintf(&sc->fw_version[0], sizeof(sc->fw_version), "%d.%d.%d",
|
||||
G_FW_VERSION_MAJOR(vers), G_FW_VERSION_MINOR(vers),
|
||||
G_FW_VERSION_MICRO(vers));
|
||||
|
||||
t3_add_sysctls(sc);
|
||||
|
||||
out:
|
||||
if (error)
|
||||
cxgb_free(sc);
|
||||
@ -538,11 +525,25 @@ cxgb_free(struct adapter *sc)
|
||||
{
|
||||
int i;
|
||||
|
||||
cxgb_down(sc);
|
||||
|
||||
#ifdef MSI_SUPPORTED
|
||||
if (sc->flags & (USING_MSI | USING_MSIX)) {
|
||||
device_printf(sc->dev, "releasing msi message(s)\n");
|
||||
pci_release_msi(sc->dev);
|
||||
} else {
|
||||
device_printf(sc->dev, "no msi message to release\n");
|
||||
}
|
||||
#endif
|
||||
if (sc->msix_regs_res != NULL) {
|
||||
bus_release_resource(sc->dev, SYS_RES_MEMORY, sc->msix_regs_rid,
|
||||
sc->msix_regs_res);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX need to drain the ifq by hand until
|
||||
* it is taught about mbuf iovecs
|
||||
*/
|
||||
|
||||
callout_drain(&sc->cxgb_tick_ch);
|
||||
|
||||
t3_sge_deinit_sw(sc);
|
||||
@ -559,41 +560,14 @@ cxgb_free(struct adapter *sc)
|
||||
|
||||
bus_generic_detach(sc->dev);
|
||||
|
||||
if (is_offload(sc)) {
|
||||
cxgb_adapter_unofld(sc);
|
||||
if (isset(&sc->open_device_map, OFFLOAD_DEVMAP_BIT))
|
||||
offload_close(&sc->tdev);
|
||||
}
|
||||
t3_free_sge_resources(sc);
|
||||
t3_sge_free(sc);
|
||||
|
||||
for (i = 0; i < SGE_QSETS; i++) {
|
||||
if (sc->msix_intr_tag[i] != NULL) {
|
||||
bus_teardown_intr(sc->dev, sc->msix_irq_res[i],
|
||||
sc->msix_intr_tag[i]);
|
||||
}
|
||||
if (sc->msix_irq_res[i] != NULL) {
|
||||
bus_release_resource(sc->dev, SYS_RES_IRQ,
|
||||
sc->msix_irq_rid[i], sc->msix_irq_res[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (sc->intr_tag != NULL) {
|
||||
bus_teardown_intr(sc->dev, sc->irq_res, sc->intr_tag);
|
||||
}
|
||||
|
||||
if (sc->irq_res != NULL) {
|
||||
device_printf(sc->dev, "de-allocating interrupt irq_rid=%d irq_res=%p\n",
|
||||
sc->irq_rid, sc->irq_res);
|
||||
bus_release_resource(sc->dev, SYS_RES_IRQ, sc->irq_rid,
|
||||
sc->irq_res);
|
||||
}
|
||||
#ifdef MSI_SUPPORTED
|
||||
if (sc->flags & (USING_MSI | USING_MSIX)) {
|
||||
device_printf(sc->dev, "releasing msi message(s)\n");
|
||||
pci_release_msi(sc->dev);
|
||||
}
|
||||
#endif
|
||||
if (sc->msix_regs_res != NULL) {
|
||||
bus_release_resource(sc->dev, SYS_RES_MEMORY, sc->msix_regs_rid,
|
||||
sc->msix_regs_res);
|
||||
}
|
||||
|
||||
if (sc->regs_res != NULL)
|
||||
bus_release_resource(sc->dev, SYS_RES_MEMORY, sc->regs_rid,
|
||||
sc->regs_res);
|
||||
@ -617,7 +591,7 @@ static int
|
||||
setup_sge_qsets(adapter_t *sc)
|
||||
{
|
||||
int i, j, err, irq_idx, qset_idx;
|
||||
u_int ntxq = 3;
|
||||
u_int ntxq = SGE_TXQ_PER_SET;
|
||||
|
||||
if ((err = t3_sge_alloc(sc)) != 0) {
|
||||
device_printf(sc->dev, "t3_sge_alloc returned %d\n", err);
|
||||
@ -821,7 +795,7 @@ cxgb_port_attach(device_t dev)
|
||||
ifmedia_add(&p->media, IFM_ETHER | IFM_AUTO, 0, NULL);
|
||||
ifmedia_set(&p->media, media_flags);
|
||||
|
||||
snprintf(buf, sizeof(buf), "cxgb_port_taskq%d", p->port);
|
||||
snprintf(buf, sizeof(buf), "cxgb_port_taskq%d", p->port);
|
||||
#ifdef TASKQUEUE_CURRENT
|
||||
/* Create a port for handling TX without starvation */
|
||||
p->tq = taskqueue_create(buf, M_NOWAIT,
|
||||
@ -851,6 +825,11 @@ cxgb_port_detach(device_t dev)
|
||||
struct port_info *p;
|
||||
|
||||
p = device_get_softc(dev);
|
||||
|
||||
PORT_LOCK(p);
|
||||
cxgb_stop_locked(p);
|
||||
PORT_UNLOCK(p);
|
||||
|
||||
mtx_destroy(&p->lock);
|
||||
if (p->tq != NULL) {
|
||||
taskqueue_drain(p->tq, &p->start_task);
|
||||
@ -962,15 +941,20 @@ t3_os_link_changed(adapter_t *adapter, int port_id, int link_status, int speed,
|
||||
int duplex, int fc)
|
||||
{
|
||||
struct port_info *pi = &adapter->port[port_id];
|
||||
struct cmac *mac = &adapter->port[port_id].mac;
|
||||
|
||||
if ((pi->ifp->if_flags & IFF_UP) == 0)
|
||||
return;
|
||||
|
||||
if (link_status)
|
||||
|
||||
if (link_status) {
|
||||
t3_mac_enable(mac, MAC_DIRECTION_RX);
|
||||
if_link_state_change(pi->ifp, LINK_STATE_UP);
|
||||
else
|
||||
} else {
|
||||
if_link_state_change(pi->ifp, LINK_STATE_DOWN);
|
||||
|
||||
pi->phy.ops->power_down(&pi->phy, 1);
|
||||
t3_mac_disable(mac, MAC_DIRECTION_RX);
|
||||
t3_link_start(&pi->phy, mac, &pi->link_config);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -988,11 +972,13 @@ t3_os_ext_intr_handler(adapter_t *sc)
|
||||
* interrupts in the meantime and let the task reenable them when
|
||||
* it's done.
|
||||
*/
|
||||
ADAPTER_LOCK(sc);
|
||||
if (sc->slow_intr_mask) {
|
||||
sc->slow_intr_mask &= ~F_T3DBG;
|
||||
t3_write_reg(sc, A_PL_INT_ENABLE0, sc->slow_intr_mask);
|
||||
taskqueue_enqueue(sc->tq, &sc->ext_intr_task);
|
||||
}
|
||||
ADAPTER_UNLOCK(sc);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1067,6 +1053,66 @@ setup_rss(adapter_t *adap)
|
||||
V_RRCPLCPUSIZE(6), cpus, rspq_map);
|
||||
}
|
||||
|
||||
/*
|
||||
* Sends an mbuf to an offload queue driver
|
||||
* after dealing with any active network taps.
|
||||
*/
|
||||
static inline int
|
||||
offload_tx(struct toedev *tdev, struct mbuf *m)
|
||||
{
|
||||
int ret;
|
||||
|
||||
critical_enter();
|
||||
ret = t3_offload_tx(tdev, m);
|
||||
critical_exit();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
write_smt_entry(struct adapter *adapter, int idx)
|
||||
{
|
||||
struct port_info *pi = &adapter->port[idx];
|
||||
struct cpl_smt_write_req *req;
|
||||
struct mbuf *m;
|
||||
|
||||
if ((m = m_gethdr(M_NOWAIT, MT_DATA)) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
req = mtod(m, struct cpl_smt_write_req *);
|
||||
req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
|
||||
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SMT_WRITE_REQ, idx));
|
||||
req->mtu_idx = NMTUS - 1; /* should be 0 but there's a T3 bug */
|
||||
req->iff = idx;
|
||||
memset(req->src_mac1, 0, sizeof(req->src_mac1));
|
||||
memcpy(req->src_mac0, pi->hw_addr, ETHER_ADDR_LEN);
|
||||
|
||||
m_set_priority(m, 1);
|
||||
|
||||
offload_tx(&adapter->tdev, m);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
init_smt(struct adapter *adapter)
|
||||
{
|
||||
int i;
|
||||
|
||||
for_each_port(adapter, i)
|
||||
write_smt_entry(adapter, i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
init_port_mtus(adapter_t *adapter)
|
||||
{
|
||||
unsigned int mtus = adapter->port[0].ifp->if_mtu;
|
||||
|
||||
if (adapter->port[1].ifp)
|
||||
mtus |= adapter->port[1].ifp->if_mtu << 16;
|
||||
t3_write_reg(adapter, A_TP_MTU_PORT_TABLE, mtus);
|
||||
}
|
||||
|
||||
static void
|
||||
send_pktsched_cmd(struct adapter *adap, int sched, int qidx, int lo,
|
||||
int hi, int port)
|
||||
@ -1076,7 +1122,7 @@ send_pktsched_cmd(struct adapter *adap, int sched, int qidx, int lo,
|
||||
|
||||
m = m_gethdr(M_NOWAIT, MT_DATA);
|
||||
if (m) {
|
||||
req = (struct mngt_pktsched_wr *)m->m_data;
|
||||
req = mtod(m, struct mngt_pktsched_wr *);
|
||||
req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_MNGT));
|
||||
req->mngt_opcode = FW_MNGTOPCODE_PKTSCHED_SET;
|
||||
req->sched = sched;
|
||||
@ -1103,6 +1149,192 @@ bind_qsets(adapter_t *sc)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* cxgb_up - enable the adapter
|
||||
* @adap: adapter being enabled
|
||||
*
|
||||
* Called when the first port is enabled, this function performs the
|
||||
* actions necessary to make an adapter operational, such as completing
|
||||
* the initialization of HW modules, and enabling interrupts.
|
||||
*
|
||||
*/
|
||||
static int
|
||||
cxgb_up(struct adapter *sc)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
if ((sc->flags & FULL_INIT_DONE) == 0) {
|
||||
|
||||
if ((sc->flags & FW_UPTODATE) == 0)
|
||||
err = upgrade_fw(sc);
|
||||
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
err = t3_init_hw(sc, 0);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
t3_write_reg(sc, A_ULPRX_TDDP_PSZ, V_HPZ0(PAGE_SHIFT - 12));
|
||||
|
||||
err = setup_sge_qsets(sc);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
setup_rss(sc);
|
||||
sc->flags |= FULL_INIT_DONE;
|
||||
}
|
||||
|
||||
t3_intr_clear(sc);
|
||||
|
||||
/* If it's MSI or INTx, allocate a single interrupt for everything */
|
||||
if ((sc->flags & USING_MSIX) == 0) {
|
||||
if ((sc->irq_res = bus_alloc_resource_any(sc->dev, SYS_RES_IRQ,
|
||||
&sc->irq_rid, RF_SHAREABLE | RF_ACTIVE)) == NULL) {
|
||||
device_printf(sc->dev, "Cannot allocate interrupt rid=%d\n", sc->irq_rid);
|
||||
err = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
device_printf(sc->dev, "allocated irq_res=%p\n", sc->irq_res);
|
||||
|
||||
if (bus_setup_intr(sc->dev, sc->irq_res, INTR_MPSAFE|INTR_TYPE_NET,
|
||||
#ifdef INTR_FILTERS
|
||||
NULL,
|
||||
#endif
|
||||
sc->cxgb_intr, sc, &sc->intr_tag)) {
|
||||
device_printf(sc->dev, "Cannot set up interrupt\n");
|
||||
err = EINVAL;
|
||||
goto irq_err;
|
||||
}
|
||||
} else {
|
||||
cxgb_setup_msix(sc, sc->msi_count);
|
||||
}
|
||||
|
||||
t3_sge_start(sc);
|
||||
t3_intr_enable(sc);
|
||||
|
||||
if ((sc->flags & (USING_MSIX | QUEUES_BOUND)) == USING_MSIX)
|
||||
bind_qsets(sc);
|
||||
sc->flags |= QUEUES_BOUND;
|
||||
out:
|
||||
return (err);
|
||||
irq_err:
|
||||
CH_ERR(sc, "request_irq failed, err %d\n", err);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Release resources when all the ports and offloading have been stopped.
|
||||
*/
|
||||
static void
|
||||
cxgb_down(struct adapter *sc)
|
||||
{
|
||||
int i;
|
||||
|
||||
t3_sge_stop(sc);
|
||||
t3_intr_disable(sc);
|
||||
|
||||
for (i = 0; i < SGE_QSETS; i++) {
|
||||
if (sc->msix_intr_tag[i] != NULL) {
|
||||
bus_teardown_intr(sc->dev, sc->msix_irq_res[i],
|
||||
sc->msix_intr_tag[i]);
|
||||
sc->msix_intr_tag[i] = NULL;
|
||||
}
|
||||
if (sc->msix_irq_res[i] != NULL) {
|
||||
bus_release_resource(sc->dev, SYS_RES_IRQ,
|
||||
sc->msix_irq_rid[i], sc->msix_irq_res[i]);
|
||||
sc->msix_irq_res[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (sc->intr_tag != NULL) {
|
||||
bus_teardown_intr(sc->dev, sc->irq_res, sc->intr_tag);
|
||||
sc->intr_tag = NULL;
|
||||
}
|
||||
if (sc->irq_res != NULL) {
|
||||
device_printf(sc->dev, "de-allocating interrupt irq_rid=%d irq_res=%p\n",
|
||||
sc->irq_rid, sc->irq_res);
|
||||
bus_release_resource(sc->dev, SYS_RES_IRQ, sc->irq_rid,
|
||||
sc->irq_res);
|
||||
sc->irq_res = NULL;
|
||||
}
|
||||
|
||||
callout_drain(&sc->sge_timer_ch);
|
||||
taskqueue_drain(sc->tq, &sc->slow_intr_task);
|
||||
taskqueue_drain(sc->tq, &sc->timer_reclaim_task);
|
||||
}
|
||||
|
||||
static int
|
||||
offload_open(struct port_info *pi)
|
||||
{
|
||||
struct adapter *adapter = pi->adapter;
|
||||
struct toedev *tdev = TOEDEV(pi->ifp);
|
||||
int adap_up = adapter->open_device_map & PORT_MASK;
|
||||
int err = 0;
|
||||
|
||||
if (atomic_cmpset_int(&adapter->open_device_map,
|
||||
(adapter->open_device_map & ~OFFLOAD_DEVMAP_BIT),
|
||||
(adapter->open_device_map | OFFLOAD_DEVMAP_BIT)) == 0)
|
||||
return (0);
|
||||
|
||||
ADAPTER_LOCK(pi->adapter);
|
||||
if (!adap_up)
|
||||
err = cxgb_up(adapter);
|
||||
ADAPTER_UNLOCK(pi->adapter);
|
||||
if (err < 0)
|
||||
return (err);
|
||||
|
||||
t3_tp_set_offload_mode(adapter, 1);
|
||||
tdev->lldev = adapter->port[0].ifp;
|
||||
err = cxgb_offload_activate(adapter);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
init_port_mtus(adapter);
|
||||
t3_load_mtus(adapter, adapter->params.mtus, adapter->params.a_wnd,
|
||||
adapter->params.b_wnd,
|
||||
adapter->params.rev == 0 ?
|
||||
adapter->port[0].ifp->if_mtu : 0xffff);
|
||||
init_smt(adapter);
|
||||
|
||||
/* Call back all registered clients */
|
||||
cxgb_add_clients(tdev);
|
||||
|
||||
out:
|
||||
/* restore them in case the offload module has changed them */
|
||||
if (err) {
|
||||
t3_tp_set_offload_mode(adapter, 0);
|
||||
clrbit(&adapter->open_device_map, OFFLOAD_DEVMAP_BIT);
|
||||
cxgb_set_dummy_ops(tdev);
|
||||
}
|
||||
return (err);
|
||||
}
|
||||
|
||||
static int
|
||||
offload_close(struct toedev *tdev)
|
||||
{
|
||||
struct adapter *adapter = tdev2adap(tdev);
|
||||
|
||||
if (!isset(&adapter->open_device_map, OFFLOAD_DEVMAP_BIT))
|
||||
return 0;
|
||||
|
||||
/* Call back all registered clients */
|
||||
cxgb_remove_clients(tdev);
|
||||
tdev->lldev = NULL;
|
||||
cxgb_set_dummy_ops(tdev);
|
||||
t3_tp_set_offload_mode(adapter, 0);
|
||||
clrbit(&adapter->open_device_map, OFFLOAD_DEVMAP_BIT);
|
||||
|
||||
ADAPTER_LOCK(adapter);
|
||||
if (!adapter->open_device_map)
|
||||
cxgb_down(adapter);
|
||||
ADAPTER_UNLOCK(adapter);
|
||||
|
||||
cxgb_offload_deactivate(adapter);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
cxgb_init(void *arg)
|
||||
{
|
||||
@ -1118,43 +1350,39 @@ cxgb_init_locked(struct port_info *p)
|
||||
{
|
||||
struct ifnet *ifp;
|
||||
adapter_t *sc = p->adapter;
|
||||
int error;
|
||||
int err;
|
||||
|
||||
mtx_assert(&p->lock, MA_OWNED);
|
||||
|
||||
ifp = p->ifp;
|
||||
if ((sc->flags & FW_UPTODATE) == 0) {
|
||||
device_printf(sc->dev, "updating firmware to version %d.%d\n",
|
||||
FW_VERSION_MAJOR, FW_VERSION_MINOR);
|
||||
if ((error = cxgb_fw_download(sc, sc->dev)) != 0) {
|
||||
device_printf(sc->dev, "firmware download failed err: %d"
|
||||
"interface will be unavailable\n", error);
|
||||
return;
|
||||
}
|
||||
sc->flags |= FW_UPTODATE;
|
||||
}
|
||||
|
||||
cxgb_link_start(p);
|
||||
ADAPTER_LOCK(p->adapter);
|
||||
if ((sc->open_device_map == 0) && ((err = cxgb_up(sc)) < 0)) {
|
||||
ADAPTER_UNLOCK(p->adapter);
|
||||
cxgb_stop_locked(p);
|
||||
return;
|
||||
}
|
||||
if (p->adapter->open_device_map == 0)
|
||||
t3_intr_clear(sc);
|
||||
t3_sge_start(sc);
|
||||
|
||||
p->adapter->open_device_map |= (1 << p->port);
|
||||
setbit(&p->adapter->open_device_map, p->port);
|
||||
|
||||
ADAPTER_UNLOCK(p->adapter);
|
||||
t3_intr_enable(sc);
|
||||
if (is_offload(sc) && !ofld_disable) {
|
||||
err = offload_open(p);
|
||||
if (err)
|
||||
log(LOG_WARNING,
|
||||
"Could not initialize offload capabilities\n");
|
||||
}
|
||||
cxgb_link_start(p);
|
||||
t3_port_intr_enable(sc, p->port);
|
||||
|
||||
if ((p->adapter->flags & (USING_MSIX | QUEUES_BOUND)) == USING_MSIX)
|
||||
bind_qsets(sc);
|
||||
p->adapter->flags |= QUEUES_BOUND;
|
||||
|
||||
callout_reset(&sc->cxgb_tick_ch, sc->params.stats_update_period * hz,
|
||||
cxgb_tick, sc);
|
||||
|
||||
|
||||
PORT_LOCK(p);
|
||||
ifp->if_drv_flags |= IFF_DRV_RUNNING;
|
||||
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
|
||||
PORT_UNLOCK(p);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1179,15 +1407,21 @@ cxgb_stop_locked(struct port_info *p)
|
||||
|
||||
ifp = p->ifp;
|
||||
|
||||
ADAPTER_LOCK(p->adapter);
|
||||
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
|
||||
p->adapter->open_device_map &= ~(1 << p->port);
|
||||
if (p->adapter->open_device_map == 0)
|
||||
t3_intr_disable(p->adapter);
|
||||
ADAPTER_UNLOCK(p->adapter);
|
||||
t3_port_intr_disable(p->adapter, p->port);
|
||||
PORT_LOCK(p);
|
||||
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
|
||||
PORT_UNLOCK(p);
|
||||
p->phy.ops->power_down(&p->phy, 1);
|
||||
t3_mac_disable(&p->mac, MAC_DIRECTION_TX | MAC_DIRECTION_RX);
|
||||
|
||||
|
||||
ADAPTER_LOCK(p->adapter);
|
||||
clrbit(&p->adapter->open_device_map, p->port);
|
||||
/*
|
||||
* XXX cancel check_task
|
||||
*/
|
||||
if (p->adapter->open_device_map == 0)
|
||||
cxgb_down(p->adapter);
|
||||
ADAPTER_UNLOCK(p->adapter);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1357,7 +1591,7 @@ cxgb_start_tx(struct ifnet *ifp, uint32_t txmax)
|
||||
m = m0;
|
||||
if ((err = t3_encap(p, &m)) != 0)
|
||||
break;
|
||||
BPF_MTAP(ifp, m);
|
||||
BPF_MTAP(ifp, m);
|
||||
}
|
||||
mtx_unlock(&txq->lock);
|
||||
|
||||
@ -1468,11 +1702,13 @@ cxgb_ext_intr_handler(void *arg, int count)
|
||||
t3_phy_intr_handler(sc);
|
||||
|
||||
/* Now reenable external interrupts */
|
||||
ADAPTER_LOCK(sc);
|
||||
if (sc->slow_intr_mask) {
|
||||
sc->slow_intr_mask |= F_T3DBG;
|
||||
t3_write_reg(sc, A_PL_INT_CAUSE0, F_T3DBG);
|
||||
t3_write_reg(sc, A_PL_INT_ENABLE0, sc->slow_intr_mask);
|
||||
}
|
||||
ADAPTER_UNLOCK(sc);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1750,9 +1986,9 @@ cxgb_extension_ioctl(struct cdev *dev, unsigned long cmd, caddr_t data,
|
||||
if (edata->val + sc->port[!port_idx].nqsets > SGE_QSETS)
|
||||
return (EINVAL);
|
||||
sc->port[port_idx].nqsets = edata->val;
|
||||
sc->port[0].first_qset = 0;
|
||||
/*
|
||||
* XXX we're hardcoding ourselves to 2 ports
|
||||
* just like the LEENUX
|
||||
* XXX hardcode ourselves to 2 ports just like LEEENUX
|
||||
*/
|
||||
sc->port[1].first_qset = sc->port[0].nqsets;
|
||||
break;
|
||||
@ -1762,20 +1998,52 @@ cxgb_extension_ioctl(struct cdev *dev, unsigned long cmd, caddr_t data,
|
||||
edata->val = pi->nqsets;
|
||||
break;
|
||||
}
|
||||
#ifdef notyet
|
||||
/*
|
||||
* XXX FreeBSD driver does not currently support any
|
||||
* offload functionality
|
||||
*/
|
||||
#ifdef notyet
|
||||
case CHELSIO_LOAD_FW:
|
||||
case CHELSIO_DEVUP:
|
||||
case CHELSIO_SETMTUTAB:
|
||||
case CHELSIO_GET_PM:
|
||||
case CHELSIO_SET_PM:
|
||||
case CHELSIO_READ_TCAM_WORD:
|
||||
return (EOPNOTSUPP);
|
||||
break;
|
||||
#endif
|
||||
case CHELSIO_SETMTUTAB: {
|
||||
struct ch_mtus *m = (struct ch_mtus *)data;
|
||||
int i;
|
||||
|
||||
if (!is_offload(sc))
|
||||
return (EOPNOTSUPP);
|
||||
if (offload_running(sc))
|
||||
return (EBUSY);
|
||||
if (m->nmtus != NMTUS)
|
||||
return (EINVAL);
|
||||
if (m->mtus[0] < 81) /* accommodate SACK */
|
||||
return (EINVAL);
|
||||
|
||||
/*
|
||||
* MTUs must be in ascending order
|
||||
*/
|
||||
for (i = 1; i < NMTUS; ++i)
|
||||
if (m->mtus[i] < m->mtus[i - 1])
|
||||
return (EINVAL);
|
||||
|
||||
memcpy(sc->params.mtus, m->mtus,
|
||||
sizeof(sc->params.mtus));
|
||||
break;
|
||||
}
|
||||
case CHELSIO_GETMTUTAB: {
|
||||
struct ch_mtus *m = (struct ch_mtus *)data;
|
||||
|
||||
if (!is_offload(sc))
|
||||
return (EOPNOTSUPP);
|
||||
|
||||
memcpy(m->mtus, sc->params.mtus, sizeof(m->mtus));
|
||||
m->nmtus = NMTUS;
|
||||
break;
|
||||
}
|
||||
case CHELSIO_DEVUP:
|
||||
if (!is_offload(sc))
|
||||
return (EOPNOTSUPP);
|
||||
return offload_open(pi);
|
||||
break;
|
||||
case CHELSIO_GET_MEM: {
|
||||
struct ch_mem_range *t = (struct ch_mem_range *)data;
|
||||
struct mc7 *mem;
|
||||
@ -1823,6 +2091,14 @@ cxgb_extension_ioctl(struct cdev *dev, unsigned long cmd, caddr_t data,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CHELSIO_READ_TCAM_WORD: {
|
||||
struct ch_tcam_word *t = (struct ch_tcam_word *)data;
|
||||
|
||||
if (!is_offload(sc))
|
||||
return (EOPNOTSUPP);
|
||||
return -t3_read_mc5_range(&sc->mc5, t->addr, 1, t->buf);
|
||||
break;
|
||||
}
|
||||
case CHELSIO_SET_TRACE_FILTER: {
|
||||
struct ch_trace *t = (struct ch_trace *)data;
|
||||
const struct trace_params *tp;
|
||||
@ -1864,6 +2140,42 @@ cxgb_extension_ioctl(struct cdev *dev, unsigned long cmd, caddr_t data,
|
||||
|
||||
break;
|
||||
}
|
||||
case CHELSIO_SET_HW_SCHED: {
|
||||
struct ch_hw_sched *t = (struct ch_hw_sched *)data;
|
||||
unsigned int ticks_per_usec = core_ticks_per_usec(sc);
|
||||
|
||||
if ((sc->flags & FULL_INIT_DONE) == 0)
|
||||
return (EAGAIN); /* need TP to be initialized */
|
||||
if (t->sched >= NTX_SCHED || !in_range(t->mode, 0, 1) ||
|
||||
!in_range(t->channel, 0, 1) ||
|
||||
!in_range(t->kbps, 0, 10000000) ||
|
||||
!in_range(t->class_ipg, 0, 10000 * 65535 / ticks_per_usec) ||
|
||||
!in_range(t->flow_ipg, 0,
|
||||
dack_ticks_to_usec(sc, 0x7ff)))
|
||||
return (EINVAL);
|
||||
|
||||
if (t->kbps >= 0) {
|
||||
error = t3_config_sched(sc, t->kbps, t->sched);
|
||||
if (error < 0)
|
||||
return (-error);
|
||||
}
|
||||
if (t->class_ipg >= 0)
|
||||
t3_set_sched_ipg(sc, t->sched, t->class_ipg);
|
||||
if (t->flow_ipg >= 0) {
|
||||
t->flow_ipg *= 1000; /* us -> ns */
|
||||
t3_set_pace_tbl(sc, &t->flow_ipg, t->sched, 1);
|
||||
}
|
||||
if (t->mode >= 0) {
|
||||
int bit = 1 << (S_TX_MOD_TIMER_MODE + t->sched);
|
||||
|
||||
t3_set_reg_field(sc, A_TP_TX_MOD_QUEUE_REQ_MAP,
|
||||
bit, t->mode ? bit : 0);
|
||||
}
|
||||
if (t->channel >= 0)
|
||||
t3_set_reg_field(sc, A_TP_TX_MOD_QUEUE_REQ_MAP,
|
||||
1 << t->sched, t->channel << t->sched);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return (EOPNOTSUPP);
|
||||
break;
|
||||
|
1634
sys/dev/cxgb/cxgb_offload.c
Normal file
1634
sys/dev/cxgb/cxgb_offload.c
Normal file
File diff suppressed because it is too large
Load Diff
260
sys/dev/cxgb/cxgb_offload.h
Normal file
260
sys/dev/cxgb/cxgb_offload.h
Normal file
@ -0,0 +1,260 @@
|
||||
|
||||
/**************************************************************************
|
||||
|
||||
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. 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
|
||||
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$
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _CXGB_OFFLOAD_H
|
||||
#define _CXGB_OFFLOAD_H
|
||||
|
||||
|
||||
#include <dev/cxgb/common/cxgb_tcb.h>
|
||||
#include <dev/cxgb/cxgb_l2t.h>
|
||||
|
||||
#include <dev/cxgb/ulp/toecore/toedev.h>
|
||||
#include <dev/cxgb/common/cxgb_t3_cpl.h>
|
||||
|
||||
struct adapter;
|
||||
struct cxgb_client;
|
||||
|
||||
void cxgb_offload_init(void);
|
||||
void cxgb_offload_exit(void);
|
||||
|
||||
void cxgb_adapter_ofld(struct adapter *adapter);
|
||||
void cxgb_adapter_unofld(struct adapter *adapter);
|
||||
int cxgb_offload_activate(struct adapter *adapter);
|
||||
void cxgb_offload_deactivate(struct adapter *adapter);
|
||||
int cxgb_ofld_recv(struct toedev *dev, struct mbuf **m, int n);
|
||||
|
||||
void cxgb_set_dummy_ops(struct toedev *dev);
|
||||
|
||||
|
||||
/*
|
||||
* Client registration. Users of T3 driver must register themselves.
|
||||
* The T3 driver will call the add function of every client for each T3
|
||||
* adapter activated, passing up the toedev ptr. Each client fills out an
|
||||
* array of callback functions to process CPL messages.
|
||||
*/
|
||||
|
||||
void cxgb_register_client(struct cxgb_client *client);
|
||||
void cxgb_unregister_client(struct cxgb_client *client);
|
||||
void cxgb_add_clients(struct toedev *tdev);
|
||||
void cxgb_remove_clients(struct toedev *tdev);
|
||||
|
||||
typedef int (*cxgb_cpl_handler_func)(struct toedev *dev,
|
||||
struct mbuf *m, void *ctx);
|
||||
|
||||
struct cxgb_client {
|
||||
char *name;
|
||||
void (*add) (struct toedev *);
|
||||
void (*remove) (struct toedev *);
|
||||
cxgb_cpl_handler_func *handlers;
|
||||
int (*redirect)(void *ctx, struct rtentry *old,
|
||||
struct rtentry *new,
|
||||
struct l2t_entry *l2t);
|
||||
TAILQ_ENTRY(cxgb_client) client_entry;
|
||||
};
|
||||
|
||||
/*
|
||||
* TID allocation services.
|
||||
*/
|
||||
int cxgb_alloc_atid(struct toedev *dev, struct cxgb_client *client,
|
||||
void *ctx);
|
||||
int cxgb_alloc_stid(struct toedev *dev, struct cxgb_client *client,
|
||||
void *ctx);
|
||||
void *cxgb_free_atid(struct toedev *dev, int atid);
|
||||
void cxgb_free_stid(struct toedev *dev, int stid);
|
||||
void cxgb_insert_tid(struct toedev *dev, struct cxgb_client *client,
|
||||
void *ctx,
|
||||
unsigned int tid);
|
||||
void cxgb_queue_tid_release(struct toedev *dev, unsigned int tid);
|
||||
void cxgb_remove_tid(struct toedev *dev, void *ctx, unsigned int tid);
|
||||
|
||||
struct toe_tid_entry {
|
||||
struct cxgb_client *client;
|
||||
void *ctx;
|
||||
};
|
||||
|
||||
/* CPL message priority levels */
|
||||
enum {
|
||||
CPL_PRIORITY_DATA = 0, /* data messages */
|
||||
CPL_PRIORITY_SETUP = 1, /* connection setup messages */
|
||||
CPL_PRIORITY_TEARDOWN = 0, /* connection teardown messages */
|
||||
CPL_PRIORITY_LISTEN = 1, /* listen start/stop messages */
|
||||
CPL_PRIORITY_ACK = 1, /* RX ACK messages */
|
||||
CPL_PRIORITY_CONTROL = 1 /* offload control messages */
|
||||
};
|
||||
|
||||
/* Flags for return value of CPL message handlers */
|
||||
enum {
|
||||
CPL_RET_BUF_DONE = 1, // buffer processing done, buffer may be freed
|
||||
CPL_RET_BAD_MSG = 2, // bad CPL message (e.g., unknown opcode)
|
||||
CPL_RET_UNKNOWN_TID = 4 // unexpected unknown TID
|
||||
};
|
||||
|
||||
typedef int (*cpl_handler_func)(struct toedev *dev, struct mbuf *m);
|
||||
|
||||
/*
|
||||
* Returns a pointer to the first byte of the CPL header in an sk_buff that
|
||||
* contains a CPL message.
|
||||
*/
|
||||
static inline void *cplhdr(struct mbuf *m)
|
||||
{
|
||||
return m->m_data;
|
||||
}
|
||||
|
||||
void t3_register_cpl_handler(unsigned int opcode, cpl_handler_func h);
|
||||
|
||||
union listen_entry {
|
||||
struct toe_tid_entry toe_tid;
|
||||
union listen_entry *next;
|
||||
};
|
||||
|
||||
union active_open_entry {
|
||||
struct toe_tid_entry toe_tid;
|
||||
union active_open_entry *next;
|
||||
};
|
||||
|
||||
/*
|
||||
* Holds the size, base address, free list start, etc of the TID, server TID,
|
||||
* and active-open TID tables for a offload device.
|
||||
* The tables themselves are allocated dynamically.
|
||||
*/
|
||||
struct tid_info {
|
||||
struct toe_tid_entry *tid_tab;
|
||||
unsigned int ntids;
|
||||
volatile int tids_in_use;
|
||||
|
||||
union listen_entry *stid_tab;
|
||||
unsigned int nstids;
|
||||
unsigned int stid_base;
|
||||
|
||||
union active_open_entry *atid_tab;
|
||||
unsigned int natids;
|
||||
unsigned int atid_base;
|
||||
|
||||
/*
|
||||
* The following members are accessed R/W so we put them in their own
|
||||
* cache lines.
|
||||
*
|
||||
* XXX We could combine the atid fields above with the lock here since
|
||||
* atids are use once (unlike other tids). OTOH the above fields are
|
||||
* usually in cache due to tid_tab.
|
||||
*/
|
||||
struct mtx atid_lock /* ____cacheline_aligned_in_smp */;
|
||||
union active_open_entry *afree;
|
||||
unsigned int atids_in_use;
|
||||
|
||||
struct mtx stid_lock /*____cacheline_aligned */;
|
||||
union listen_entry *sfree;
|
||||
unsigned int stids_in_use;
|
||||
};
|
||||
|
||||
struct toe_data {
|
||||
#ifdef notyet
|
||||
struct list_head list_node;
|
||||
#endif
|
||||
struct toedev *dev;
|
||||
unsigned int tx_max_chunk; /* max payload for TX_DATA */
|
||||
unsigned int max_wrs; /* max in-flight WRs per connection */
|
||||
unsigned int nmtus;
|
||||
const unsigned short *mtus;
|
||||
struct tid_info tid_maps;
|
||||
|
||||
struct toe_tid_entry *tid_release_list;
|
||||
struct mtx tid_release_lock;
|
||||
struct task tid_release_task;
|
||||
};
|
||||
|
||||
/*
|
||||
* toedev -> toe_data accessor
|
||||
*/
|
||||
#define TOE_DATA(dev) (*(struct toe_data **)&(dev)->l4opt)
|
||||
|
||||
/*
|
||||
* Map an ATID or STID to their entries in the corresponding TID tables.
|
||||
*/
|
||||
static inline union active_open_entry *atid2entry(const struct tid_info *t,
|
||||
unsigned int atid)
|
||||
{
|
||||
return &t->atid_tab[atid - t->atid_base];
|
||||
}
|
||||
|
||||
|
||||
static inline union listen_entry *stid2entry(const struct tid_info *t,
|
||||
unsigned int stid)
|
||||
{
|
||||
return &t->stid_tab[stid - t->stid_base];
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the connection corresponding to a TID.
|
||||
*/
|
||||
static inline struct toe_tid_entry *lookup_tid(const struct tid_info *t,
|
||||
unsigned int tid)
|
||||
{
|
||||
return tid < t->ntids ? &(t->tid_tab[tid]) : NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the connection corresponding to a server TID.
|
||||
*/
|
||||
static inline struct toe_tid_entry *lookup_stid(const struct tid_info *t,
|
||||
unsigned int tid)
|
||||
{
|
||||
if (tid < t->stid_base || tid >= t->stid_base + t->nstids)
|
||||
return NULL;
|
||||
return &(stid2entry(t, tid)->toe_tid);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the connection corresponding to an active-open TID.
|
||||
*/
|
||||
static inline struct toe_tid_entry *lookup_atid(const struct tid_info *t,
|
||||
unsigned int tid)
|
||||
{
|
||||
if (tid < t->atid_base || tid >= t->atid_base + t->natids)
|
||||
return NULL;
|
||||
return &(atid2entry(t, tid)->toe_tid);
|
||||
}
|
||||
|
||||
void *cxgb_alloc_mem(unsigned long size);
|
||||
void cxgb_free_mem(void *addr);
|
||||
void cxgb_neigh_update(struct rtentry *rt);
|
||||
void cxgb_redirect(struct rtentry *old, struct rtentry *new);
|
||||
int process_rx(struct toedev *dev, struct mbuf **m, int n);
|
||||
int attach_toedev(struct toedev *dev);
|
||||
void detach_toedev(struct toedev *dev);
|
||||
|
||||
|
||||
#endif
|
@ -9,11 +9,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.
|
||||
|
||||
@ -49,9 +45,17 @@ $FreeBSD$
|
||||
#define _CXGB_OSDEP_H_
|
||||
|
||||
typedef struct adapter adapter_t;
|
||||
|
||||
struct sge_rspq;
|
||||
|
||||
#define PANIC_IF(exp) do { \
|
||||
if (exp) \
|
||||
panic("BUG: %s", exp); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define m_get_priority(m) ((uintptr_t)(m)->m_pkthdr.rcvif)
|
||||
#define m_set_priority(m, pri) ((m)->m_pkthdr.rcvif = (struct ifnet *)(pri))
|
||||
|
||||
#if __FreeBSD_version > 700030
|
||||
#define INTR_FILTERS
|
||||
#define FIRMWARE_LATEST
|
||||
@ -68,6 +72,8 @@ struct sge_rspq;
|
||||
#define TASKQUEUE_CURRENT
|
||||
#endif
|
||||
|
||||
#define __read_mostly __attribute__((__section__(".data.read_mostly")))
|
||||
|
||||
/*
|
||||
* Workaround for weird Chelsio issue
|
||||
*/
|
||||
@ -75,9 +81,10 @@ struct sge_rspq;
|
||||
#define PRIV_SUPPORTED
|
||||
#endif
|
||||
|
||||
#define CXGB_TX_CLEANUP_THRESHOLD 32
|
||||
#define CXGB_TX_CLEANUP_THRESHOLD 32
|
||||
|
||||
#define LOG_WARNING 1
|
||||
#define LOG_WARNING 1
|
||||
#define LOG_ERR 2
|
||||
|
||||
#ifdef DEBUG_PRINT
|
||||
#define DPRINTF printf
|
||||
@ -107,6 +114,16 @@ void prefetch(void *x)
|
||||
__asm volatile("prefetcht0 %0" :: "m" (*(unsigned long *)x));
|
||||
}
|
||||
|
||||
extern void kdb_backtrace(void);
|
||||
|
||||
#define WARN_ON(condition) do { \
|
||||
if (unlikely((condition)!=0)) { \
|
||||
log(LOG_WARNING, "BUG: warning at %s:%d/%s()\n", __FILE__, __LINE__, __FUNCTION__); \
|
||||
kdb_backtrace(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
#else /* !i386 && !amd64 */
|
||||
#define mb()
|
||||
#define rmb()
|
||||
@ -137,7 +154,13 @@ static const int debug_flags = DBG_RX;
|
||||
|
||||
#define t3_os_sleep(x) DELAY((x) * 1000)
|
||||
|
||||
#define test_and_clear_bit(bit, p) atomic_cmpset_int((p), ((*(p)) | bit), ((*(p)) & ~bit))
|
||||
|
||||
|
||||
#define max_t(type, a, b) (type)max((a), (b))
|
||||
#define net_device ifnet
|
||||
|
||||
|
||||
|
||||
/* Standard PHY definitions */
|
||||
#define BMCR_LOOPBACK BMCR_LOOP
|
||||
|
File diff suppressed because it is too large
Load Diff
86
sys/dev/cxgb/sys/mbufq.h
Normal file
86
sys/dev/cxgb/sys/mbufq.h
Normal file
@ -0,0 +1,86 @@
|
||||
/**************************************************************************
|
||||
|
||||
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$
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
struct mbuf_head {
|
||||
struct mbuf *head;
|
||||
struct mbuf *tail;
|
||||
uint32_t qlen;
|
||||
struct mtx lock;
|
||||
};
|
||||
|
||||
static __inline void
|
||||
mbufq_init(struct mbuf_head *l)
|
||||
{
|
||||
l->head = l->tail = NULL;
|
||||
}
|
||||
|
||||
static __inline int
|
||||
mbufq_empty(struct mbuf_head *l)
|
||||
{
|
||||
return (l->head == NULL);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
mbufq_len(struct mbuf_head *l)
|
||||
{
|
||||
return (l->qlen);
|
||||
}
|
||||
|
||||
|
||||
static __inline void
|
||||
mbufq_tail(struct mbuf_head *l, struct mbuf *m)
|
||||
{
|
||||
l->qlen++;
|
||||
l->tail->m_nextpkt = m;
|
||||
l->tail = m;
|
||||
}
|
||||
|
||||
static __inline struct mbuf *
|
||||
mbufq_dequeue(struct mbuf_head *l)
|
||||
{
|
||||
struct mbuf *m;
|
||||
|
||||
m = l->head;
|
||||
if (m) {
|
||||
if (m == l->tail)
|
||||
l->tail = NULL;
|
||||
l->head = m->m_nextpkt;
|
||||
l->qlen--;
|
||||
}
|
||||
|
||||
return (m);
|
||||
}
|
||||
|
||||
static __inline struct mbuf *
|
||||
mbufq_peek(struct mbuf_head *l)
|
||||
{
|
||||
return (l->head);
|
||||
}
|
@ -1,478 +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. 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 Inc, 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
|
||||
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
|
||||
MT2DXW^X7YX]AP\_1&T.&D\%:VG[*U>ES>E9UE0^]YZ+*AR0VXMT%E..A.
|
||||
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
|
||||
MY"10[$$.NR'N!LB$A&"=^_A5$(/H/$0R\_4$ED>6URHRT0<TW"#D]*S7C0
|
||||
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
|
||||
F(Q36JAPY(A"B5!-O-2%"%:5/%$*)6JBV`T>?Z/H;`"WDR?AO````
|
||||
`
|
||||
end
|
483
sys/dev/cxgb/t3fw-4.0.0.bin.gz.uu
Normal file
483
sys/dev/cxgb/t3fw-4.0.0.bin.gz.uu
Normal file
@ -0,0 +1,483 @@
|
||||
/**************************************************************************
|
||||
|
||||
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.0.0.bin.gz
|
||||
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
|
||||
!````
|
||||
`
|
||||
end
|
@ -6,19 +6,21 @@ CXGB = ${.CURDIR}/../../dev/cxgb
|
||||
KMOD= if_cxgb
|
||||
SRCS= cxgb_mc5.c cxgb_vsc8211.c cxgb_ael1002.c cxgb_mv88e1xxx.c
|
||||
SRCS+= cxgb_xgmac.c cxgb_t3_hw.c cxgb_main.c cxgb_sge.c cxgb_lro.c
|
||||
SRCS+= device_if.h bus_if.h pci_if.h
|
||||
SRCS+= cxgb_offload.c cxgb_l2t.c
|
||||
SRCS+= device_if.h bus_if.h pci_if.h opt_zero.h
|
||||
SRCS+= uipc_mvec.c
|
||||
|
||||
CFLAGS+= -DCONFIG_CHELSIO_T3_CORE -g -DDEFAULT_JUMBO -DCONFIG_DEFINED
|
||||
CFLAGS+= -DCONFIG_CHELSIO_T3_CORE -g -DDEFAULT_JUMBO -DCONFIG_DEFINED
|
||||
#CFLAGS+= -DINVARIANT_SUPPORT -DINVARIANTS -DDEBUG
|
||||
|
||||
.if ${MACHINE_ARCH} != "ia64"
|
||||
# ld is broken on ia64
|
||||
t3fw-3.2.bin: ${CXGB}/t3fw-3.2.bin.gz.uu
|
||||
uudecode -p < ${CXGB}/t3fw-3.2.bin.gz.uu \
|
||||
t3fw-4.0.0.bin: ${CXGB}/t3fw-4.0.0.bin.gz.uu
|
||||
uudecode -p < ${CXGB}/t3fw-4.0.0.bin.gz.uu \
|
||||
| gzip -dc > ${.TARGET}
|
||||
|
||||
FIRMWS= t3fw-3.2.bin:t3fw32
|
||||
CLEANFILES+= t3fw-3.2.bin
|
||||
FIRMWS= t3fw-4.0.0.bin:t3fw400
|
||||
CLEANFILES+= t3fw-4.0.0.bin
|
||||
.endif
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user