- import new common code for the T304

- update to firmware version 4.1.0

- switch over to standard method for initializing cdevs (contributed by scottl@)
- break out timer_reclaim_task to be per-port
- move msix teardown into separate function
- fix bus_setup_intr for msi-x for the multi-port case so that msi-x resources
  are not corrupted on unload
- handle 10/100/1000 base-T media and auto negotiation
- bind qset to cpu even for singleq case
- white space cleanups
- remove recursive PORT_LOCK
- move mtu setting to separate function
- stop and re-init port when changing mtu
- replace all direct references to m_data with calls to mtod
- handle attach failure better by not trying to de-initialize
  taskqueues when they have not been allocated
- no longer default to jumbo frames

Sponsored by: Chelsio
MFC after: 3 days
This commit is contained in:
Kip Macy 2007-06-13 05:36:00 +00:00
parent 5224d0a1d6
commit ef72318f0e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=170654
17 changed files with 1489 additions and 767 deletions

View File

@ -519,6 +519,7 @@ 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
dev/cxgb/common/cxgb_vsc7323.c optional cxgb pci
dev/cxgb/common/cxgb_vsc8211.c optional cxgb pci
dev/cxgb/common/cxgb_ael1002.c optional cxgb pci
dev/cxgb/common/cxgb_mv88e1xxx.c optional cxgb pci

View File

@ -277,7 +277,13 @@ static int xaui_direct_get_link_status(struct cphy *phy, int *link_ok,
unsigned int status;
status = t3_read_reg(phy->adapter,
XGM_REG(A_XGM_SERDES_STAT0, phy->addr));
XGM_REG(A_XGM_SERDES_STAT0, phy->addr)) |
t3_read_reg(phy->adapter,
XGM_REG(A_XGM_SERDES_STAT1, phy->addr)) |
t3_read_reg(phy->adapter,
XGM_REG(A_XGM_SERDES_STAT2, phy->addr)) |
t3_read_reg(phy->adapter,
XGM_REG(A_XGM_SERDES_STAT3, phy->addr));
*link_ok = !(status & F_LOWSIG0);
}
if (speed)
@ -323,5 +329,5 @@ static struct cphy_ops xaui_direct_ops = {
void t3_xaui_direct_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr,
const struct mdio_ops *mdio_ops)
{
cphy_init(phy, adapter, 1, &xaui_direct_ops, mdio_ops);
cphy_init(phy, adapter, phy_addr, &xaui_direct_ops, mdio_ops);
}

View File

@ -38,18 +38,19 @@ $FreeBSD$
#endif
enum {
MAX_NPORTS = 2, /* max # of ports */
MAX_FRAME_SIZE = 10240, /* max MAC frame size, including header + FCS */
MAX_NPORTS = 4,
TP_TMR_RES = 200, /* TP timer resolution in usec */
MAX_FRAME_SIZE = 10240, /* max MAC frame size, includes header + FCS */
EEPROMSIZE = 8192, /* Serial EEPROM size */
RSS_TABLE_SIZE = 64, /* size of RSS lookup and mapping tables */
TCB_SIZE = 128, /* TCB size */
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 */
PROTO_SRAM_LINES = 128, /* size of protocol sram */
};
#define MAX_RX_COALESCING_LEN 16224U
#define MAX_RX_COALESCING_LEN 12288U
enum {
PAUSE_RX = 1 << 0,
@ -58,7 +59,7 @@ enum {
};
enum {
SUPPORTED_IRQ = 1 << 25
SUPPORTED_IRQ = 1 << 24
};
enum { /* adapter interrupt-maintained statistics */
@ -69,9 +70,33 @@ enum { /* adapter interrupt-maintained statistics */
IRQ_NUM_STATS /* keep last */
};
enum {
TP_VERSION_MAJOR = 1,
TP_VERSION_MINOR = 0,
TP_VERSION_MICRO = 44
};
#define S_TP_VERSION_MAJOR 16
#define M_TP_VERSION_MAJOR 0xFF
#define V_TP_VERSION_MAJOR(x) ((x) << S_TP_VERSION_MAJOR)
#define G_TP_VERSION_MAJOR(x) \
(((x) >> S_TP_VERSION_MAJOR) & M_TP_VERSION_MAJOR)
#define S_TP_VERSION_MINOR 8
#define M_TP_VERSION_MINOR 0xFF
#define V_TP_VERSION_MINOR(x) ((x) << S_TP_VERSION_MINOR)
#define G_TP_VERSION_MINOR(x) \
(((x) >> S_TP_VERSION_MINOR) & M_TP_VERSION_MINOR)
#define S_TP_VERSION_MICRO 0
#define M_TP_VERSION_MICRO 0xFF
#define V_TP_VERSION_MICRO(x) ((x) << S_TP_VERSION_MICRO)
#define G_TP_VERSION_MICRO(x) \
(((x) >> S_TP_VERSION_MICRO) & M_TP_VERSION_MICRO)
enum {
FW_VERSION_MAJOR = 4,
FW_VERSION_MINOR = 0,
FW_VERSION_MINOR = 1,
FW_VERSION_MICRO = 0
};
@ -116,10 +141,11 @@ struct mdio_ops {
};
struct adapter_info {
unsigned char nports; /* # of ports */
unsigned char nports0; /* # of ports on channel 0 */
unsigned char nports1; /* # of ports on channel 1 */
unsigned char phy_base_addr; /* MDIO PHY base address */
unsigned char mdien;
unsigned char mdiinv;
unsigned char mdien:1;
unsigned char mdiinv:1;
unsigned int gpio_out; /* GPIO output settings */
unsigned int gpio_intr; /* GPIO IRQ enable mask */
unsigned long caps; /* adapter capabilities */
@ -271,11 +297,13 @@ struct tp_params {
unsigned int rx_num_pgs; /* # of Rx pages */
unsigned int tx_num_pgs; /* # of Tx pages */
unsigned int ntimer_qs; /* # of timer queues */
unsigned int tre; /* log2 of core clocks per TP tick */
unsigned int dack_re; /* DACK timer resolution */
};
struct qset_params { /* SGE queue set parameters */
unsigned int polling; /* polling/interrupt service for rspq */
unsigned int lro; /* large receive offload */
unsigned int coalesce_nsecs; /* irq coalescing timer */
unsigned int rspq_size; /* # of entries in response queue */
unsigned int fl_size; /* # of entries in regular free list */
@ -354,6 +382,7 @@ struct adapter_params {
unsigned short b_wnd[NCCTRL_WIN];
#endif
unsigned int nports; /* # of ethernet ports */
unsigned int chan_map; /* bitmap of in-use Tx channels */
unsigned int stats_update_period; /* MAC stats accumulation period */
unsigned int linkpoll_period; /* link poll period in 0.1s */
unsigned int rev; /* chip revision */
@ -430,7 +459,10 @@ static inline unsigned int t3_mc7_size(const struct mc7 *p)
struct cmac {
adapter_t *adapter;
unsigned int offset;
unsigned int nucast; /* # of address filters for unicast MACs */
unsigned char nucast; /* # of address filters for unicast MACs */
unsigned char multiport; /* multiple ports connected to this MAC */
unsigned char ext_port; /* external MAC port */
unsigned char promisc_map; /* which external ports are promiscuous */
unsigned int tx_tcnt;
unsigned int tx_xcnt;
u64 tx_mcnt;
@ -589,9 +621,6 @@ static inline unsigned int is_pcie(const adapter_t *adap)
}
void t3_set_reg_field(adapter_t *adap, unsigned int addr, u32 mask, u32 val);
void t3_read_indirect(adapter_t *adap, unsigned int addr_reg,
unsigned int data_reg, u32 *vals, unsigned int nregs,
unsigned int start_idx);
void t3_write_regs(adapter_t *adapter, const struct addr_val_pair *p, int n,
unsigned int offset);
int t3_wait_op_done_val(adapter_t *adapter, int reg, u32 mask, int polarity,
@ -627,13 +656,14 @@ int t3_seeprom_write(adapter_t *adapter, u32 addr, u32 data);
int t3_seeprom_wp(adapter_t *adapter, int enable);
int t3_read_flash(adapter_t *adapter, unsigned int addr, unsigned int nwords,
u32 *data, int byte_oriented);
int t3_check_tpsram_version(adapter_t *adapter);
int t3_check_tpsram(adapter_t *adapter, u8 *tp_ram, unsigned int size);
int t3_load_fw(adapter_t *adapter, const u8 *fw_data, unsigned int size);
int t3_get_fw_version(adapter_t *adapter, u32 *vers);
int t3_check_fw_version(adapter_t *adapter);
int t3_init_hw(adapter_t *adapter, u32 fw_params);
void mac_prep(struct cmac *mac, adapter_t *adapter, int index);
void early_hw_init(adapter_t *adapter, const struct adapter_info *ai);
int t3_reset_adapter(adapter_t *adapter);
int t3_prep_adapter(adapter_t *adapter, const struct adapter_info *ai, int reset);
void t3_led_ready(adapter_t *adapter);
void t3_fatal_err(adapter_t *adapter);
@ -641,6 +671,7 @@ void t3_set_vlan_accel(adapter_t *adapter, unsigned int ports, int on);
void t3_config_rss(adapter_t *adapter, unsigned int rss_config, const u8 *cpus,
const u16 *rspq);
int t3_read_rss(adapter_t *adapter, u8 *lkup, u16 *map);
int t3_set_proto_sram(adapter_t *adap, u8 *data);
int t3_mps_set_active_ports(adapter_t *adap, unsigned int port_mask);
void t3_port_failover(adapter_t *adapter, int port);
void t3_failover_done(adapter_t *adapter, int port);
@ -657,7 +688,7 @@ int t3_mac_disable(struct cmac *mac, int which);
int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu);
int t3_mac_set_rx_mode(struct cmac *mac, struct t3_rx_mode *rm);
int t3_mac_set_address(struct cmac *mac, unsigned int idx, u8 addr[6]);
int t3_mac_set_num_ucast(struct cmac *mac, int n);
int t3_mac_set_num_ucast(struct cmac *mac, unsigned char n);
const struct mac_stats *t3_mac_update_stats(struct cmac *mac);
int t3_mac_set_speed_duplex_fc(struct cmac *mac, int speed, int duplex,
int fc);
@ -718,6 +749,16 @@ int t3_sge_read_rspq(adapter_t *adapter, unsigned int id, u32 data[4]);
int t3_sge_cqcntxt_op(adapter_t *adapter, unsigned int id, unsigned int op,
unsigned int credits);
int t3_elmr_blk_write(adapter_t *adap, int start, const u32 *vals, int n);
int t3_elmr_blk_read(adapter_t *adap, int start, u32 *vals, int n);
int t3_vsc7323_init(adapter_t *adap, int nports);
int t3_vsc7323_set_speed_fc(adapter_t *adap, int speed, int fc, int port);
int t3_vsc7323_set_addr(adapter_t *adap, u8 addr[6], int port);
int t3_vsc7323_set_mtu(adapter_t *adap, unsigned int mtu, int port);
int t3_vsc7323_enable(adapter_t *adap, int port, int which);
int t3_vsc7323_disable(adapter_t *adap, int port, int which);
const struct mac_stats *t3_vsc7323_update_stats(struct cmac *mac);
void t3_mv88e1xxx_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr,
const struct mdio_ops *mdio_ops);
void t3_vsc8211_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr,

View File

@ -31,9 +31,11 @@ POSSIBILITY OF SUCH DAMAGE.
__FBSDID("$FreeBSD$");
#ifdef CONFIG_DEFINED
#include <cxgb_include.h>
#include <common/cxgb_common.h>
#include <common/cxgb_regs.h>
#else
#include <dev/cxgb/cxgb_include.h>
#include <dev/cxgb/common/cxgb_common.h>
#include <dev/cxgb/common/cxgb_regs.h>
#endif
enum {
@ -328,9 +330,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)
if (!tcam_size)
return 0;
if (nroutes > MAX_ROUTES || nroutes + nservers + nfilters > tcam_size)
return -EINVAL;

View File

@ -30,12 +30,17 @@ POSSIBILITY OF SUCH DAMAGE.
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#ifdef CONFIG_DEFINED
#include <cxgb_include.h>
#else
#include <dev/cxgb/cxgb_include.h>
#endif
#define DENTER() printf("entered %s\n", __FUNCTION__);
#define DEXIT() printf("exiting %s\n", __FUNCTION__);
/**
* t3_wait_op_done_val - wait until an operation is completed
* @adapter: the adapter performing the operation
@ -119,7 +124,7 @@ void t3_set_reg_field(adapter_t *adapter, unsigned int addr, u32 mask, u32 val)
* Reads registers that are accessed indirectly through an address/data
* register pair.
*/
void t3_read_indirect(adapter_t *adap, unsigned int addr_reg,
static void t3_read_indirect(adapter_t *adap, unsigned int addr_reg,
unsigned int data_reg, u32 *vals, unsigned int nregs,
unsigned int start_idx)
{
@ -202,7 +207,7 @@ static void mi1_init(adapter_t *adap, const struct adapter_info *ai)
t3_write_reg(adap, A_MI1_CFG, val);
}
#define MDIO_ATTEMPTS 10
#define MDIO_ATTEMPTS 20
/*
* MI1 read/write operations for direct-addressed PHYs.
@ -219,7 +224,7 @@ static int mi1_read(adapter_t *adapter, int phy_addr, int mmd_addr,
MDIO_LOCK(adapter);
t3_write_reg(adapter, A_MI1_ADDR, addr);
t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(2));
ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 20);
ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 10);
if (!ret)
*valp = t3_read_reg(adapter, A_MI1_DATA);
MDIO_UNLOCK(adapter);
@ -239,7 +244,7 @@ static int mi1_write(adapter_t *adapter, int phy_addr, int mmd_addr,
t3_write_reg(adapter, A_MI1_ADDR, addr);
t3_write_reg(adapter, A_MI1_DATA, val);
t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(1));
ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 20);
ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 10);
MDIO_UNLOCK(adapter);
return ret;
}
@ -262,11 +267,11 @@ static int mi1_ext_read(adapter_t *adapter, int phy_addr, int mmd_addr,
t3_write_reg(adapter, A_MI1_ADDR, addr);
t3_write_reg(adapter, A_MI1_DATA, reg_addr);
t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(0));
ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 20);
ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 10);
if (!ret) {
t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(3));
ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0,
MDIO_ATTEMPTS, 20);
MDIO_ATTEMPTS, 10);
if (!ret)
*valp = t3_read_reg(adapter, A_MI1_DATA);
}
@ -284,12 +289,12 @@ static int mi1_ext_write(adapter_t *adapter, int phy_addr, int mmd_addr,
t3_write_reg(adapter, A_MI1_ADDR, addr);
t3_write_reg(adapter, A_MI1_DATA, reg_addr);
t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(0));
ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 20);
ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 10);
if (!ret) {
t3_write_reg(adapter, A_MI1_DATA, val);
t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(1));
ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0,
MDIO_ATTEMPTS, 20);
MDIO_ATTEMPTS, 10);
}
MDIO_UNLOCK(adapter);
return ret;
@ -435,27 +440,32 @@ int t3_set_phy_speed_duplex(struct cphy *phy, int speed, int duplex)
}
static struct adapter_info t3_adap_info[] = {
{ 2, 0, 0, 0,
{ 1, 1, 0, 0, 0,
F_GPIO2_OEN | F_GPIO4_OEN |
F_GPIO2_OUT_VAL | F_GPIO4_OUT_VAL, F_GPIO3 | F_GPIO5,
0,
&mi1_mdio_ops, "Chelsio PE9000" },
{ 2, 0, 0, 0,
{ 1, 1, 0, 0, 0,
F_GPIO2_OEN | F_GPIO4_OEN |
F_GPIO2_OUT_VAL | F_GPIO4_OUT_VAL, F_GPIO3 | F_GPIO5,
0,
&mi1_mdio_ops, "Chelsio T302" },
{ 1, 0, 0, 0,
{ 1, 0, 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,
&mi1_mdio_ext_ops, "Chelsio T310" },
{ 2, 0, 0, 0,
{ 1, 1, 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,
&mi1_mdio_ext_ops, "Chelsio T320" },
{ 4, 0, 0, 0, 0,
F_GPIO5_OEN | F_GPIO6_OEN | F_GPIO7_OEN | F_GPIO5_OUT_VAL |
F_GPIO6_OUT_VAL | F_GPIO7_OUT_VAL,
F_GPIO1 | F_GPIO2 | F_GPIO3 | F_GPIO4, SUPPORTED_AUI,
&mi1_mdio_ops, "Chelsio T304" },
};
/*
@ -472,7 +482,7 @@ const struct adapter_info *t3_get_adapter_info(unsigned int id)
#define CAPS_10G (SUPPORTED_10000baseT_Full | SUPPORTED_AUI)
static struct port_type_info port_types[] = {
{ NULL },
{ NULL, 0, NULL },
{ t3_ael1002_phy_prep, CAPS_10G | SUPPORTED_FIBRE,
"10GBASE-XR" },
{ t3_vsc8211_phy_prep, CAPS_1G | SUPPORTED_TP | SUPPORTED_IRQ,
@ -656,6 +666,8 @@ static int get_vpd_params(adapter_t *adapter, struct vpd_params *p)
} else {
p->port_type[0] = (u8)hex2int(vpd.port0_data[0]);
p->port_type[1] = (u8)hex2int(vpd.port1_data[0]);
p->port_type[2] = (u8)hex2int(vpd.port2_data[0]);
p->port_type[3] = (u8)hex2int(vpd.port3_data[0]);
p->xauicfg[0] = simple_strtoul(vpd.xaui0cfg_data, NULL, 16);
p->xauicfg[1] = simple_strtoul(vpd.xaui1cfg_data, NULL, 16);
}
@ -847,6 +859,64 @@ static int t3_write_flash(adapter_t *adapter, unsigned int addr,
return 0;
}
/**
* t3_check_tpsram_version - read the tp sram version
* @adapter: the adapter
*
* Reads the protocol sram version from serial eeprom.
*/
int t3_check_tpsram_version(adapter_t *adapter)
{
int ret;
u32 vers;
unsigned int major, minor;
/* Get version loaded in SRAM */
t3_write_reg(adapter, A_TP_EMBED_OP_FIELD0, 0);
ret = t3_wait_op_done(adapter, A_TP_EMBED_OP_FIELD0,
1, 1, 5, 1);
if (ret)
return ret;
vers = t3_read_reg(adapter, A_TP_EMBED_OP_FIELD1);
major = G_TP_VERSION_MAJOR(vers);
minor = G_TP_VERSION_MINOR(vers);
if (major == TP_VERSION_MAJOR && minor == TP_VERSION_MINOR)
return 0;
return -EINVAL;
}
/**
* t3_check_tpsram - check if provided protocol SRAM
* is compatible with this driver
* @adapter: the adapter
* @tp_sram: the firmware image to write
* @size: image size
*
* Checks if an adapter's tp sram is compatible with the driver.
* Returns 0 if the versions are compatible, a negative error otherwise.
*/
int t3_check_tpsram(adapter_t *adapter, u8 *tp_sram, unsigned int size)
{
u32 csum;
unsigned int i;
const u32 *p = (const u32 *)tp_sram;
/* Verify checksum */
for (csum = 0, i = 0; i < size / sizeof(csum); i++)
csum += ntohl(p[i]);
if (csum != 0xffffffff) {
CH_ERR(adapter, "corrupted protocol SRAM image, checksum %u\n",
csum);
return -EINVAL;
}
return 0;
}
enum fw_version_type {
FW_VERSION_N3,
FW_VERSION_T3
@ -889,9 +959,9 @@ int t3_check_fw_version(adapter_t *adapter)
minor == FW_VERSION_MINOR)
return 0;
CH_ERR(adapter, "found wrong FW version(%u.%u), "
"driver needs version %d.%d\n", major, minor,
FW_VERSION_MAJOR, FW_VERSION_MINOR);
CH_ERR(adapter, "found wrong FW version (%u.%u), "
"driver needs version %d.%d\n", major, minor,
FW_VERSION_MAJOR, FW_VERSION_MINOR);
return -EINVAL;
}
@ -921,7 +991,7 @@ static int t3_flash_erase_sectors(adapter_t *adapter, int start, int end)
/*
* t3_load_fw - download firmware
* @adapter: the adapter
* @fw_data: the firrware image to write
* @fw_data: the firmware image to write
* @size: image size
*
* Write the supplied firmware image to the card's serial flash.
@ -936,7 +1006,7 @@ int t3_load_fw(adapter_t *adapter, const u8 *fw_data, unsigned int size)
const u32 *p = (const u32 *)fw_data;
int ret, addr, fw_sector = FW_FLASH_BOOT_ADDR >> 16;
if ((size & 3) || (size < FW_MIN_SIZE))
if ((size & 3) || size < FW_MIN_SIZE)
return -EINVAL;
if (size > FW_VERS_ADDR + 8 - FW_FLASH_BOOT_ADDR)
return -EFBIG;
@ -1015,9 +1085,10 @@ int t3_cim_ctl_blk_read(adapter_t *adap, unsigned int addr, unsigned int n,
void t3_link_changed(adapter_t *adapter, int port_id)
{
int link_ok, speed, duplex, fc;
struct cphy *phy = &adapter->port[port_id].phy;
struct cmac *mac = &adapter->port[port_id].mac;
struct link_config *lc = &adapter->port[port_id].link_config;
struct port_info *pi = adap2pinfo(adapter, port_id);
struct cphy *phy = &pi->phy;
struct cmac *mac = &pi->mac;
struct link_config *lc = &pi->link_config;
phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc);
@ -1487,8 +1558,12 @@ static void mc7_intr_handler(struct mc7 *mc7)
*/
static int mac_intr_handler(adapter_t *adap, unsigned int idx)
{
struct cmac *mac = &adap->port[idx].mac;
u32 cause = t3_read_reg(adap, A_XGM_INT_CAUSE + mac->offset);
u32 cause;
struct cmac *mac;
idx = idx == 0 ? 0 : adapter_info(adap)->nports0; /* MAC idx -> port */
mac = &adap2pinfo(adap, idx)->mac;
cause = t3_read_reg(adap, A_XGM_INT_CAUSE + mac->offset);
if (cause & V_TXFIFO_PRTY_ERR(M_TXFIFO_PRTY_ERR)) {
mac->stats.tx_fifo_parity_err++;
@ -1524,7 +1599,7 @@ int t3_phy_intr_handler(adapter_t *adapter)
u32 i, cause = t3_read_reg(adapter, A_T3DBG_INT_CAUSE);
for_each_port(adapter, i) {
struct port_info *p = &adapter->port[i];
struct port_info *p = adap2pinfo(adapter, i);
mask = gpi - (gpi & (gpi - 1));
gpi -= mask;
@ -1556,7 +1631,6 @@ int t3_slow_intr_handler(adapter_t *adapter)
cause &= adapter->slow_intr_mask;
if (!cause)
return 0;
if (cause & F_PCIM0) {
if (is_pcie(adapter))
pcie_intr_handler(adapter);
@ -1647,11 +1721,10 @@ void t3_intr_enable(adapter_t *adapter)
adapter_info(adapter)->gpio_intr);
t3_write_reg(adapter, A_T3DBG_INT_ENABLE,
adapter_info(adapter)->gpio_intr);
if (is_pcie(adapter)) {
if (is_pcie(adapter))
t3_write_reg(adapter, A_PCIE_INT_ENABLE, PCIE_INTR_MASK);
} else {
else
t3_write_reg(adapter, A_PCIX_INT_ENABLE, PCIX_INTR_MASK);
}
t3_write_reg(adapter, A_PL_INT_ENABLE0, adapter->slow_intr_mask);
(void) t3_read_reg(adapter, A_PL_INT_ENABLE0); /* flush */
}
@ -1719,8 +1792,10 @@ void t3_intr_clear(adapter_t *adapter)
*/
void t3_port_intr_enable(adapter_t *adapter, int idx)
{
t3_write_reg(adapter, XGM_REG(A_XGM_INT_ENABLE, idx), XGM_INTR_MASK);
adapter->port[idx].phy.ops->intr_enable(&adapter->port[idx].phy);
struct port_info *pi = adap2pinfo(adapter, idx);
t3_write_reg(adapter, A_XGM_INT_ENABLE + pi->mac.offset, XGM_INTR_MASK);
pi->phy.ops->intr_enable(&pi->phy);
}
/**
@ -1733,8 +1808,10 @@ void t3_port_intr_enable(adapter_t *adapter, int idx)
*/
void t3_port_intr_disable(adapter_t *adapter, int idx)
{
t3_write_reg(adapter, XGM_REG(A_XGM_INT_ENABLE, idx), 0);
adapter->port[idx].phy.ops->intr_disable(&adapter->port[idx].phy);
struct port_info *pi = adap2pinfo(adapter, idx);
t3_write_reg(adapter, A_XGM_INT_ENABLE + pi->mac.offset, 0);
pi->phy.ops->intr_disable(&pi->phy);
}
/**
@ -1747,10 +1824,11 @@ void t3_port_intr_disable(adapter_t *adapter, int idx)
*/
void t3_port_intr_clear(adapter_t *adapter, int idx)
{
t3_write_reg(adapter, XGM_REG(A_XGM_INT_CAUSE, idx), 0xffffffff);
adapter->port[idx].phy.ops->intr_clear(&adapter->port[idx].phy);
}
struct port_info *pi = adap2pinfo(adapter, idx);
t3_write_reg(adapter, A_XGM_INT_CAUSE + pi->mac.offset, 0xffffffff);
pi->phy.ops->intr_clear(&pi->phy);
}
/**
* t3_sge_write_context - write an SGE context
@ -2344,6 +2422,14 @@ static inline void tp_wr_indirect(adapter_t *adap, unsigned int addr, u32 val)
t3_write_reg(adap, A_TP_PIO_DATA, val);
}
static void tp_wr_bits_indirect(adapter_t *adap, unsigned int addr,
unsigned int mask, unsigned int val)
{
t3_write_reg(adap, A_TP_PIO_ADDR, addr);
val |= t3_read_reg(adap, A_TP_PIO_DATA) & ~mask;
t3_write_reg(adap, A_TP_PIO_DATA, val);
}
static void tp_config(adapter_t *adap, const struct tp_params *p)
{
t3_write_reg(adap, A_TP_GLOBAL_CONFIG, F_TXPACINGENABLE | F_PATHMTU |
@ -2360,14 +2446,16 @@ static void tp_config(adapter_t *adap, const struct tp_params *p)
F_IPV6ENABLE | F_NICMODE);
t3_write_reg(adap, A_TP_TX_RESOURCE_LIMIT, 0x18141814);
t3_write_reg(adap, A_TP_PARA_REG4, 0x5050105);
t3_set_reg_field(adap, A_TP_PARA_REG6,
adap->params.rev > 0 ? F_ENABLEESND : F_T3A_ENABLEESND,
0);
t3_set_reg_field(adap, A_TP_PARA_REG6, 0,
adap->params.rev > 0 ? F_ENABLEESND :
F_T3A_ENABLEESND);
t3_set_reg_field(adap, A_TP_PC_CONFIG,
F_ENABLEEPCMDAFULL | F_ENABLEOCSPIFULL,
F_TXDEFERENABLE | F_HEARBEATDACK | F_TXCONGESTIONMODE |
F_RXCONGESTIONMODE);
F_ENABLEEPCMDAFULL,
F_ENABLEOCSPIFULL |F_TXDEFERENABLE | F_HEARBEATDACK |
F_TXCONGESTIONMODE | F_RXCONGESTIONMODE);
t3_set_reg_field(adap, A_TP_PC_CONFIG2, F_CHDRAFULL, 0);
t3_write_reg(adap, A_TP_PROXY_FLOW_CNTL, 1080);
t3_write_reg(adap, A_TP_PROXY_FLOW_CNTL, 1000);
if (adap->params.rev > 0) {
tp_wr_indirect(adap, A_TP_EGRESS_CONFIG, F_REWRITEFORCETOSIZE);
@ -2381,7 +2469,21 @@ static void tp_config(adapter_t *adap, const struct tp_params *p)
t3_write_reg(adap, A_TP_TX_MOD_QUEUE_WEIGHT1, 0);
t3_write_reg(adap, A_TP_TX_MOD_QUEUE_WEIGHT0, 0);
t3_write_reg(adap, A_TP_MOD_CHANNEL_WEIGHT, 0);
t3_write_reg(adap, A_TP_MOD_RATE_LIMIT, 0);
t3_write_reg(adap, A_TP_MOD_RATE_LIMIT, 0xf2200000);
if (adap->params.nports > 2) {
t3_set_reg_field(adap, A_TP_PC_CONFIG2, 0,
F_ENABLETXPORTFROMDA | F_ENABLERXPORTFROMADDR);
tp_wr_bits_indirect(adap, A_TP_QOS_RX_MAP_MODE,
V_RXMAPMODE(M_RXMAPMODE), 0);
tp_wr_indirect(adap, A_TP_INGRESS_CONFIG, V_BITPOS0(48) |
V_BITPOS1(49) | V_BITPOS2(50) | V_BITPOS3(51) |
F_ENABLEEXTRACT | F_ENABLEEXTRACTIONSFD |
F_ENABLEINSERTION | F_ENABLEINSERTIONSFD);
tp_wr_indirect(adap, A_TP_PREAMBLE_MSB, 0xfb000000);
tp_wr_indirect(adap, A_TP_PREAMBLE_LSB, 0xd5);
tp_wr_indirect(adap, A_TP_INTF_FROM_TX_PKT, F_INTFFROMTXPKT);
}
}
/* TCP timer values in ms */
@ -2398,7 +2500,7 @@ static void tp_config(adapter_t *adap, const struct tp_params *p)
*/
static void tp_set_timers(adapter_t *adap, unsigned int core_clk)
{
unsigned int tre = fls(core_clk / (1000000 / TP_TMR_RES)) - 1;
unsigned int tre = adap->params.tp.tre;
unsigned int dack_re = adap->params.tp.dack_re;
unsigned int tstamp_re = fls(core_clk / 1000); /* 1ms, at least */
unsigned int tps = core_clk >> tre;
@ -2456,6 +2558,7 @@ int t3_tp_set_coalescing_size(adapter_t *adap, unsigned int size, int psh)
val |= F_RXCOALESCEENABLE;
if (psh)
val |= F_RXCOALESCEPSHEN;
size = min(MAX_RX_COALESCING_LEN, size);
t3_write_reg(adap, A_TP_PARA_REG2, V_RXCOALESCESIZE(size) |
V_MAXRXDATA(MAX_RX_COALESCING_LEN));
}
@ -2485,11 +2588,10 @@ static void __devinit init_mtus(unsigned short mtus[])
* are enabled and still have at least 8 bytes of payload.
*/
mtus[0] = 88;
mtus[1] = 88; /* workaround for silicon starting at 1 */
mtus[1] = 88;
mtus[2] = 256;
mtus[3] = 512;
mtus[4] = 576;
/* mtus[4] = 808; */
mtus[5] = 1024;
mtus[6] = 1280;
mtus[7] = 1492;
@ -2705,6 +2807,33 @@ static void ulp_config(adapter_t *adap, const struct tp_params *p)
ulp_region(adap, PBL, m, p->chan_rx_size / 4);
t3_write_reg(adap, A_ULPRX_TDDP_TAGMASK, 0xffffffff);
}
/**
* t3_set_proto_sram - set the contents of the protocol sram
* @adapter: the adapter
* @data: the protocol image
*
* Write the contents of the protocol SRAM.
*/
int t3_set_proto_sram(adapter_t *adap, u8 *data)
{
int i;
u32 *buf = (u32 *)data;
for (i = 0; i < PROTO_SRAM_LINES; i++) {
t3_write_reg(adap, A_TP_EMBED_OP_FIELD5, htobe32(*buf++));
t3_write_reg(adap, A_TP_EMBED_OP_FIELD4, htobe32(*buf++));
t3_write_reg(adap, A_TP_EMBED_OP_FIELD3, htobe32(*buf++));
t3_write_reg(adap, A_TP_EMBED_OP_FIELD2, htobe32(*buf++));
t3_write_reg(adap, A_TP_EMBED_OP_FIELD1, htobe32(*buf++));
t3_write_reg(adap, A_TP_EMBED_OP_FIELD0, i << 1 | 1 << 31);
if (t3_wait_op_done(adap, A_TP_EMBED_OP_FIELD0, 1, 1, 5, 1))
return -EIO;
}
return 0;
}
#endif
void t3_config_trace_filter(adapter_t *adapter, const struct trace_params *tp,
@ -2883,20 +3012,22 @@ int t3_mps_set_active_ports(adapter_t *adap, unsigned int port_mask)
}
/*
* Perform the bits of HW initialization that are dependent on the number
* of available ports.
* Perform the bits of HW initialization that are dependent on the Tx
* channels being used.
*/
static void init_hw_for_avail_ports(adapter_t *adap, int nports)
static void chan_init_hw(adapter_t *adap, unsigned int chan_map)
{
int i;
if (nports == 1) {
if (chan_map != 3) { /* one channel */
t3_set_reg_field(adap, A_ULPRX_CTL, F_ROUND_ROBIN, 0);
t3_set_reg_field(adap, A_ULPTX_CONFIG, F_CFG_RR_ARB, 0);
t3_write_reg(adap, A_MPS_CFG, F_TPRXPORTEN | F_TPTXPORT0EN |
F_PORT0ACTIVE | F_ENFORCEPKT);
t3_write_reg(adap, A_PM1_TX_CFG, 0xc000c000);
} else {
t3_write_reg(adap, A_MPS_CFG, F_TPRXPORTEN | F_ENFORCEPKT |
(chan_map == 1 ? F_TPTXPORT0EN | F_PORT0ACTIVE :
F_TPTXPORT1EN | F_PORT1ACTIVE));
t3_write_reg(adap, A_PM1_TX_CFG,
chan_map == 1 ? 0xffffffff : 0);
} else { /* two channels */
t3_set_reg_field(adap, A_ULPRX_CTL, 0, F_ROUND_ROBIN);
t3_set_reg_field(adap, A_ULPTX_CONFIG, 0, F_CFG_RR_ARB);
t3_write_reg(adap, A_ULPTX_DMA_WEIGHT,
@ -2999,9 +3130,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)
if (!mc7->size)
return 0;
val = t3_read_reg(adapter, mc7->offset + A_MC7_CFG);
slow = val & F_SLOW;
width = G_WIDTH(val);
@ -3166,6 +3297,12 @@ int t3_init_hw(adapter_t *adapter, u32 fw_params)
else if (calibrate_xgm(adapter))
goto out_err;
if (adapter->params.nports > 2) {
t3_mac_reset(&adap2pinfo(adapter, 0)->mac);
if ((err = t3_vsc7323_init(adapter, adapter->params.nports)))
goto out_err;
}
if (vpd->mclk) {
partition_mem(adapter, &adapter->params.tp);
@ -3194,8 +3331,8 @@ int t3_init_hw(adapter_t *adapter, u32 fw_params)
else
t3_set_reg_field(adapter, A_PCIX_CFG, 0, F_CLIDECEN);
t3_write_reg(adapter, A_PM1_RX_CFG, 0xf000f000);
init_hw_for_avail_ports(adapter, adapter->params.nports);
t3_write_reg(adapter, A_PM1_RX_CFG, 0xffffffff);
chan_init_hw(adapter, adapter->params.chan_map);
t3_sge_init(adapter, &adapter->params.sge);
t3_write_reg(adapter, A_CIM_HOST_ACC_DATA, vpd->uclk | fw_params);
@ -3210,6 +3347,7 @@ int t3_init_hw(adapter_t *adapter, u32 fw_params)
CH_ERR(adapter, "uP initialization timed out\n");
goto out_err;
}
err = 0;
out_err:
return err;
@ -3314,8 +3452,16 @@ static void __devinit mc7_prep(adapter_t *adapter, struct mc7 *mc7,
void mac_prep(struct cmac *mac, adapter_t *adapter, int index)
{
mac->adapter = adapter;
mac->multiport = adapter->params.nports > 2;
if (mac->multiport) {
mac->ext_port = (unsigned char)index;
mac->nucast = 8;
index = 0;
} else
mac->nucast = 1;
mac->offset = (XGMAC0_1_BASE_ADDR - XGMAC0_0_BASE_ADDR) * index;
mac->nucast = 1;
if (adapter->params.rev == 0 && uses_xaui(adapter)) {
t3_write_reg(adapter, A_XGM_SERDES_CTRL + mac->offset,
@ -3327,7 +3473,8 @@ void mac_prep(struct cmac *mac, adapter_t *adapter, int index)
void early_hw_init(adapter_t *adapter, const struct adapter_info *ai)
{
u32 val = V_PORTSPEED(is_10G(adapter) ? 3 : 2);
u32 val = V_PORTSPEED(is_10G(adapter) || adapter->params.nports > 2 ?
3 : 2);
mi1_init(adapter, ai);
t3_write_reg(adapter, A_I2C_CFG, /* set for 80KHz */
@ -3335,7 +3482,7 @@ void early_hw_init(adapter_t *adapter, const struct adapter_info *ai)
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;
@ -3354,9 +3501,9 @@ void early_hw_init(adapter_t *adapter, const struct adapter_info *ai)
* Reset the adapter. PCIe cards lose their config space during reset, PCI-X
* ones don't.
*/
int t3_reset_adapter(adapter_t *adapter)
static int t3_reset_adapter(adapter_t *adapter)
{
int i, save_and_restore_pcie =
int i, save_and_restore_pcie =
adapter->params.rev < T3_REV_B2 && is_pcie(adapter);
uint16_t devid = 0;
@ -3397,7 +3544,8 @@ int __devinit t3_prep_adapter(adapter_t *adapter,
get_pci_mode(adapter, &adapter->params.pci);
adapter->params.info = ai;
adapter->params.nports = ai->nports;
adapter->params.nports = ai->nports0 + ai->nports1;
adapter->params.chan_map = !!ai->nports0 | (!!ai->nports1 << 1);
adapter->params.rev = t3_read_reg(adapter, A_PL_REV);
adapter->params.linkpoll_period = 0;
adapter->params.stats_update_period = is_10G(adapter) ?
@ -3406,9 +3554,10 @@ int __devinit t3_prep_adapter(adapter_t *adapter,
t3_os_find_pci_capability(adapter, PCI_CAP_ID_VPD);
ret = get_vpd_params(adapter, &adapter->params.vpd);
if (ret < 0)
if (ret < 0) {
printf("failed to get VPD params\n");
return ret;
}
if (reset && t3_reset_adapter(adapter))
return -1;
@ -3421,7 +3570,7 @@ int __devinit t3_prep_adapter(adapter_t *adapter,
mc7_prep(adapter, &adapter->pmtx, MC7_PMTX_BASE_ADDR, "PMTX");
mc7_prep(adapter, &adapter->cm, MC7_CM_BASE_ADDR, "CM");
p->nchan = ai->nports;
p->nchan = adapter->params.chan_map == 3 ? 2 : 1;
p->pmrx_size = t3_mc7_size(&adapter->pmrx);
p->pmtx_size = t3_mc7_size(&adapter->pmtx);
p->cm_size = t3_mc7_size(&adapter->cm);
@ -3433,11 +3582,14 @@ int __devinit t3_prep_adapter(adapter_t *adapter,
p->tx_num_pgs = pm_num_pages(p->chan_tx_size, p->tx_pg_size);
p->ntimer_qs = p->cm_size >= (128 << 20) ||
adapter->params.rev > 0 ? 12 : 6;
p->tre = fls(adapter->params.vpd.cclk / (1000 / TP_TMR_RES)) -
1;
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);
t3_mc7_size(&adapter->pmtx) &&
t3_mc7_size(&adapter->cm);
if (is_offload(adapter)) {
adapter->params.mc5.nservers = DEFAULT_NSERVERS;
@ -3456,12 +3608,22 @@ int __devinit t3_prep_adapter(adapter_t *adapter,
for_each_port(adapter, i) {
u8 hw_addr[6];
struct port_info *p = &adapter->port[i];
struct port_info *p = adap2pinfo(adapter, i);
while (!adapter->params.vpd.port_type[j])
while (adapter->params.vpd.port_type[j] == 0) {
++j;
}
if (adapter->params.vpd.port_type[j] > sizeof(port_types)/sizeof(port_types[0])) {
printf("bad port type idx=%d\n", adapter->params.vpd.port_type[j]);
printf("port types: ");
for (i = 0; i < j; i++)
printf("port[%d]=%d ", i, adapter->params.vpd.port_type[i]);
printf("\n");
return -1;
}
p->port_type = &port_types[adapter->params.vpd.port_type[j]];
p->port_type = &port_types[adapter->params.vpd.port_type[j]];
p->port_type->phy_prep(&p->phy, adapter, ai->phy_base_addr + j,
ai->mdio_ops);
mac_prep(&p->mac, adapter, j);

View File

@ -0,0 +1,340 @@
/**************************************************************************
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$");
#ifdef CONFIG_DEFINED
#include <common/cxgb_common.h>
#else
#include <dev/cxgb/common/cxgb_common.h>
#endif
enum {
ELMR_ADDR = 0,
ELMR_STAT = 1,
ELMR_DATA_LO = 2,
ELMR_DATA_HI = 3,
ELMR_MDIO_ADDR = 10
};
#define VSC_REG(block, subblock, reg) \
((reg) | ((subblock) << 8) | ((block) << 12))
int t3_elmr_blk_write(adapter_t *adap, int start, const u32 *vals, int n)
{
int ret;
const struct mdio_ops *mo = adapter_info(adap)->mdio_ops;
ELMR_LOCK(adap);
ret = mo->write(adap, ELMR_MDIO_ADDR, 0, ELMR_ADDR, start);
for ( ; !ret && n; n--, vals++) {
ret = mo->write(adap, ELMR_MDIO_ADDR, 0, ELMR_DATA_LO,
*vals & 0xffff);
if (!ret)
ret = mo->write(adap, ELMR_MDIO_ADDR, 0, ELMR_DATA_HI,
*vals >> 16);
}
ELMR_UNLOCK(adap);
return ret;
}
static int elmr_write(adapter_t *adap, int addr, u32 val)
{
return t3_elmr_blk_write(adap, addr, &val, 1);
}
int t3_elmr_blk_read(adapter_t *adap, int start, u32 *vals, int n)
{
int ret;
unsigned int v;
const struct mdio_ops *mo = adapter_info(adap)->mdio_ops;
ELMR_LOCK(adap);
ret = mo->write(adap, ELMR_MDIO_ADDR, 0, ELMR_ADDR, start);
if (ret)
goto out;
ret = mo->read(adap, ELMR_MDIO_ADDR, 0, ELMR_STAT, &v);
if (ret)
goto out;
if (v != 1) {
ret = -ETIMEDOUT;
goto out;
}
for ( ; !ret && n; n--, vals++) {
ret = mo->read(adap, ELMR_MDIO_ADDR, 0, ELMR_DATA_LO, vals);
if (!ret) {
ret = mo->read(adap, ELMR_MDIO_ADDR, 0, ELMR_DATA_HI,
&v);
*vals |= v << 16;
}
}
out: ELMR_UNLOCK(adap);
return ret;
}
int t3_vsc7323_init(adapter_t *adap, int nports)
{
static struct addr_val_pair sys_avp[] = {
{ VSC_REG(7, 15, 0xf), 2 },
{ VSC_REG(7, 15, 0x19), 0xd6 },
{ VSC_REG(7, 15, 7), 0xc },
{ VSC_REG(7, 1, 0), 0x220 },
};
static struct addr_val_pair fifo_avp[] = {
{ VSC_REG(2, 0, 0x2f), 0 },
{ VSC_REG(2, 0, 0xf), 0xa0010291 },
{ VSC_REG(2, 1, 0x2f), 1 },
{ VSC_REG(2, 1, 0xf), 0xa0026301 }
};
static struct addr_val_pair xg_avp[] = {
{ VSC_REG(1, 10, 0), 0x600b },
{ VSC_REG(1, 10, 2), 0x4000 },
{ VSC_REG(1, 10, 5), 0x65 },
{ VSC_REG(1, 10, 7), 3 },
{ VSC_REG(1, 10, 0x23), 0x800007bf },
{ VSC_REG(1, 10, 0x24), 4 }
};
int i, ret, ing_step, egr_step, ing_bot, egr_bot;
for (i = 0; i < ARRAY_SIZE(sys_avp); i++)
if ((ret = t3_elmr_blk_write(adap, sys_avp[i].reg_addr,
&sys_avp[i].val, 1)))
return ret;
ing_step = 0xc0 / nports;
egr_step = 0x40 / nports;
ing_bot = egr_bot = 0;
// ing_wm = ing_step * 64;
// egr_wm = egr_step * 64;
/* {ING,EGR}_CONTROL.CLR = 1 here */
for (i = 0; i < nports; i++)
if ((ret = elmr_write(adap, VSC_REG(2, 0, 0x10 + i),
((ing_bot + ing_step) << 16) | ing_bot)) ||
(ret = elmr_write(adap, VSC_REG(2, 0, 0x50 + i), 0)) ||
(ret = elmr_write(adap, VSC_REG(2, 1, 0x10 + i),
((egr_bot + egr_step) << 16) | egr_bot)) ||
(ret = elmr_write(adap, VSC_REG(2, 1, 0x40 + i),
0x2000280)) ||
(ret = elmr_write(adap, VSC_REG(2, 1, 0x50 + i), 0)))
return ret;
for (i = 0; i < ARRAY_SIZE(fifo_avp); i++)
if ((ret = t3_elmr_blk_write(adap, fifo_avp[i].reg_addr,
&fifo_avp[i].val, 1)))
return ret;
for (i = 0; i < ARRAY_SIZE(xg_avp); i++)
if ((ret = t3_elmr_blk_write(adap, xg_avp[i].reg_addr,
&xg_avp[i].val, 1)))
return ret;
for (i = 0; i < nports; i++)
if ((ret = elmr_write(adap, VSC_REG(1, i, 0), 0xa59c)) ||
(ret = elmr_write(adap, VSC_REG(1, i, 5),
(i << 12) | 0x63)) ||
(ret = elmr_write(adap, VSC_REG(1, i, 0xb), 0x96)) ||
(ret = elmr_write(adap, VSC_REG(1, i, 0x15), 0x21)))
return ret;
return ret;
}
int t3_vsc7323_set_speed_fc(adapter_t *adap, int speed, int fc, int port)
{
int mode, clk, r;
if (speed >= 0) {
if (speed == SPEED_10)
mode = clk = 1;
else if (speed == SPEED_100)
mode = 1, clk = 2;
else if (speed == SPEED_1000)
mode = clk = 3;
else
return -EINVAL;
if ((r = elmr_write(adap, VSC_REG(1, port, 0),
0xa590 | (mode << 2))) ||
(r = elmr_write(adap, VSC_REG(1, port, 0xb),
0x91 | (clk << 1))) ||
(r = elmr_write(adap, VSC_REG(1, port, 0xb),
0x90 | (clk << 1))) ||
(r = elmr_write(adap, VSC_REG(1, port, 0),
0xa593 | (mode << 2))))
return r;
}
r = (fc & PAUSE_RX) ? 0x6ffff : 0x2ffff;
if (fc & PAUSE_TX)
r |= (1 << 19);
return elmr_write(adap, VSC_REG(1, port, 1), r);
}
int t3_vsc7323_set_mtu(adapter_t *adap, unsigned int mtu, int port)
{
return elmr_write(adap, VSC_REG(1, port, 2), mtu);
}
int t3_vsc7323_set_addr(adapter_t *adap, u8 addr[6], int port)
{
int ret;
ret = elmr_write(adap, VSC_REG(1, port, 3),
(addr[0] << 16) | (addr[1] << 8) | addr[2]);
if (!ret)
ret = elmr_write(adap, VSC_REG(1, port, 4),
(addr[3] << 16) | (addr[4] << 8) | addr[5]);
return ret;
}
int t3_vsc7323_enable(adapter_t *adap, int port, int which)
{
int ret;
unsigned int v, orig;
ret = t3_elmr_blk_read(adap, VSC_REG(1, port, 0), &v, 1);
if (!ret) {
orig = v;
if (which & MAC_DIRECTION_TX)
v |= 1;
if (which & MAC_DIRECTION_RX)
v |= 2;
if (v != orig)
ret = elmr_write(adap, VSC_REG(1, port, 0), v);
}
return ret;
}
int t3_vsc7323_disable(adapter_t *adap, int port, int which)
{
int ret;
unsigned int v, orig;
ret = t3_elmr_blk_read(adap, VSC_REG(1, port, 0), &v, 1);
if (!ret) {
orig = v;
if (which & MAC_DIRECTION_TX)
v &= ~1;
if (which & MAC_DIRECTION_RX)
v &= ~2;
if (v != orig)
ret = elmr_write(adap, VSC_REG(1, port, 0), v);
}
return ret;
}
#define STATS0_START 1
#define STATS1_START 0x24
#define NSTATS0 (0x1d - STATS0_START + 1)
#define NSTATS1 (0x2a - STATS1_START + 1)
const struct mac_stats *t3_vsc7323_update_stats(struct cmac *mac)
{
int ret;
u64 rx_ucast, tx_ucast;
u32 stats0[NSTATS0], stats1[NSTATS1];
ret = t3_elmr_blk_read(mac->adapter,
VSC_REG(4, mac->ext_port, STATS0_START),
stats0, NSTATS0);
if (!ret)
ret = t3_elmr_blk_read(mac->adapter,
VSC_REG(4, mac->ext_port, STATS1_START),
stats1, NSTATS1);
if (ret)
goto out;
/*
* HW counts Rx/Tx unicast frames but we want all the frames.
*/
rx_ucast = mac->stats.rx_frames - mac->stats.rx_mcast_frames -
mac->stats.rx_bcast_frames;
rx_ucast += (u64)(stats0[6 - STATS0_START] - (u32)rx_ucast);
tx_ucast = mac->stats.tx_frames - mac->stats.tx_mcast_frames -
mac->stats.tx_bcast_frames;
tx_ucast += (u64)(stats0[27 - STATS0_START] - (u32)tx_ucast);
#define RMON_UPDATE(mac, name, hw_stat) \
mac->stats.name += (u64)((hw_stat) - (u32)(mac->stats.name))
RMON_UPDATE(mac, rx_octets, stats0[4 - STATS0_START]);
RMON_UPDATE(mac, rx_frames, stats0[6 - STATS0_START]);
RMON_UPDATE(mac, rx_frames, stats0[7 - STATS0_START]);
RMON_UPDATE(mac, rx_frames, stats0[8 - STATS0_START]);
RMON_UPDATE(mac, rx_mcast_frames, stats0[7 - STATS0_START]);
RMON_UPDATE(mac, rx_bcast_frames, stats0[8 - STATS0_START]);
RMON_UPDATE(mac, rx_fcs_errs, stats0[9 - STATS0_START]);
RMON_UPDATE(mac, rx_pause, stats0[2 - STATS0_START]);
RMON_UPDATE(mac, rx_jabber, stats0[16 - STATS0_START]);
RMON_UPDATE(mac, rx_short, stats0[11 - STATS0_START]);
RMON_UPDATE(mac, rx_symbol_errs, stats0[1 - STATS0_START]);
RMON_UPDATE(mac, rx_too_long, stats0[15 - STATS0_START]);
RMON_UPDATE(mac, rx_frames_64, stats0[17 - STATS0_START]);
RMON_UPDATE(mac, rx_frames_65_127, stats0[18 - STATS0_START]);
RMON_UPDATE(mac, rx_frames_128_255, stats0[19 - STATS0_START]);
RMON_UPDATE(mac, rx_frames_256_511, stats0[20 - STATS0_START]);
RMON_UPDATE(mac, rx_frames_512_1023, stats0[21 - STATS0_START]);
RMON_UPDATE(mac, rx_frames_1024_1518, stats0[22 - STATS0_START]);
RMON_UPDATE(mac, rx_frames_1519_max, stats0[23 - STATS0_START]);
RMON_UPDATE(mac, tx_octets, stats0[26 - STATS0_START]);
RMON_UPDATE(mac, tx_frames, stats0[27 - STATS0_START]);
RMON_UPDATE(mac, tx_frames, stats0[28 - STATS0_START]);
RMON_UPDATE(mac, tx_frames, stats0[29 - STATS0_START]);
RMON_UPDATE(mac, tx_mcast_frames, stats0[28 - STATS0_START]);
RMON_UPDATE(mac, tx_bcast_frames, stats0[29 - STATS0_START]);
RMON_UPDATE(mac, tx_pause, stats0[25 - STATS0_START]);
RMON_UPDATE(mac, tx_underrun, 0);
RMON_UPDATE(mac, tx_frames_64, stats1[36 - STATS1_START]);
RMON_UPDATE(mac, tx_frames_65_127, stats1[37 - STATS1_START]);
RMON_UPDATE(mac, tx_frames_128_255, stats1[38 - STATS1_START]);
RMON_UPDATE(mac, tx_frames_256_511, stats1[39 - STATS1_START]);
RMON_UPDATE(mac, tx_frames_512_1023, stats1[40 - STATS1_START]);
RMON_UPDATE(mac, tx_frames_1024_1518, stats1[41 - STATS1_START]);
RMON_UPDATE(mac, tx_frames_1519_max, stats1[42 - STATS1_START]);
#undef RMON_UPDATE
mac->stats.rx_frames = rx_ucast + mac->stats.rx_mcast_frames +
mac->stats.rx_bcast_frames;
mac->stats.tx_frames = tx_ucast + mac->stats.tx_mcast_frames +
mac->stats.tx_bcast_frames;
out: return &mac->stats;
}

View File

@ -1,3 +1,4 @@
/**************************************************************************
Copyright (c) 2007, Chelsio Inc.
@ -128,8 +129,23 @@ int t3_mac_reset(struct cmac *mac)
xaui_serdes_reset(mac);
}
if (mac->multiport) {
t3_write_reg(adap, A_XGM_RX_MAX_PKT_SIZE + oft,
MAX_FRAME_SIZE - 4);
t3_set_reg_field(adap, A_XGM_TXFIFO_CFG + oft, 0,
F_DISPREAMBLE);
t3_set_reg_field(adap, A_XGM_RX_CFG + oft, 0, F_COPYPREAMBLE |
F_ENNON802_3PREAMBLE);
t3_set_reg_field(adap, A_XGM_TXFIFO_CFG + oft,
V_TXFIFOTHRESH(M_TXFIFOTHRESH),
V_TXFIFOTHRESH(64));
t3_write_reg(adap, A_XGM_TX_CTRL + oft, F_TXEN);
t3_write_reg(adap, A_XGM_RX_CTRL + oft, F_RXEN);
}
val = F_MAC_RESET_;
if (is_10G(adap))
if (is_10G(adap) || mac->multiport)
val |= F_PCS_RESET_;
else if (uses_xaui(adap))
val |= F_PCS_RESET_ | F_XG2G_RESET_;
@ -220,9 +236,14 @@ static void set_addr_filter(struct cmac *mac, int idx, const u8 *addr)
/* Set one of the station's unicast MAC addresses. */
int t3_mac_set_address(struct cmac *mac, unsigned int idx, u8 addr[6])
{
if (mac->multiport)
idx = mac->ext_port + idx * mac->adapter->params.nports;
if (idx >= mac->nucast)
return -EINVAL;
set_addr_filter(mac, idx, addr);
if (mac->multiport && idx < mac->adapter->params.nports)
t3_vsc7323_set_addr(mac->adapter, addr, idx);
return 0;
}
@ -231,7 +252,7 @@ int t3_mac_set_address(struct cmac *mac, unsigned int idx, u8 addr[6])
* unicast addresses. Caller should reload the unicast and multicast addresses
* after calling this.
*/
int t3_mac_set_num_ucast(struct cmac *mac, int n)
int t3_mac_set_num_ucast(struct cmac *mac, unsigned char n)
{
if (n > EXACT_ADDR_FILTERS)
return -EINVAL;
@ -239,6 +260,28 @@ int t3_mac_set_num_ucast(struct cmac *mac, int n)
return 0;
}
static void disable_exact_filters(struct cmac *mac)
{
unsigned int i, reg = mac->offset + A_XGM_RX_EXACT_MATCH_LOW_1;
for (i = 0; i < EXACT_ADDR_FILTERS; i++, reg += 8) {
u32 v = t3_read_reg(mac->adapter, reg);
t3_write_reg(mac->adapter, reg, v);
}
t3_read_reg(mac->adapter, A_XGM_RX_EXACT_MATCH_LOW_1); /* flush */
}
static void enable_exact_filters(struct cmac *mac)
{
unsigned int i, reg = mac->offset + A_XGM_RX_EXACT_MATCH_HIGH_1;
for (i = 0; i < EXACT_ADDR_FILTERS; i++, reg += 8) {
u32 v = t3_read_reg(mac->adapter, reg);
t3_write_reg(mac->adapter, reg, v);
}
t3_read_reg(mac->adapter, A_XGM_RX_EXACT_MATCH_LOW_1); /* flush */
}
/* Calculate the RX hash filter index of an Ethernet address */
static int hash_hw_addr(const u8 *addr)
{
@ -255,16 +298,18 @@ static int hash_hw_addr(const u8 *addr)
int t3_mac_set_rx_mode(struct cmac *mac, struct t3_rx_mode *rm)
{
u32 val, hash_lo, hash_hi;
u32 hash_lo, hash_hi;
adapter_t *adap = mac->adapter;
unsigned int oft = mac->offset;
val = t3_read_reg(adap, A_XGM_RX_CFG + oft) & ~F_COPYALLFRAMES;
if (promisc_rx_mode(rm))
val |= F_COPYALLFRAMES;
t3_write_reg(adap, A_XGM_RX_CFG + oft, val);
mac->promisc_map |= 1 << mac->ext_port;
else
mac->promisc_map &= ~(1 << mac->ext_port);
t3_set_reg_field(adap, A_XGM_RX_CFG + oft, F_COPYALLFRAMES,
mac->promisc_map ? F_COPYALLFRAMES : 0);
if (allmulti_rx_mode(rm))
if (allmulti_rx_mode(rm) || mac->multiport)
hash_lo = hash_hi = 0xffffffff;
else {
u8 *addr;
@ -289,7 +334,15 @@ int t3_mac_set_rx_mode(struct cmac *mac, struct t3_rx_mode *rm)
return 0;
}
int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu)
static int rx_fifo_hwm(int mtu)
{
int hwm;
hwm = max(MAC_RXFIFO_SIZE - 3 * mtu, (MAC_RXFIFO_SIZE * 38) / 100);
return min(hwm, MAC_RXFIFO_SIZE - 8192);
}
int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu)
{
int hwm, lwm;
unsigned int thres, v;
@ -300,17 +353,39 @@ int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu)
* packet size register includes header, but not FCS.
*/
mtu += 14;
if (mac->multiport)
mtu += 8; /* for preamble */
if (mtu > MAX_FRAME_SIZE - 4)
return -EINVAL;
t3_write_reg(adap, A_XGM_RX_MAX_PKT_SIZE + mac->offset, mtu);
if (mac->multiport)
return t3_vsc7323_set_mtu(adap, mtu - 4, mac->ext_port);
if (adap->params.rev == T3_REV_B2 &&
(t3_read_reg(adap, A_XGM_RX_CTRL + mac->offset) & F_RXEN)) {
disable_exact_filters(mac);
v = t3_read_reg(adap, A_XGM_RX_CFG + mac->offset);
t3_set_reg_field(adap, A_XGM_RX_CFG + mac->offset,
F_ENHASHMCAST | F_COPYALLFRAMES, F_DISBCAST);
/* drain rx FIFO */
if (t3_wait_op_done(adap,
A_XGM_RX_MAX_PKT_SIZE_ERR_CNT + mac->offset,
1 << 31, 1, 20, 5)) {
t3_write_reg(adap, A_XGM_RX_CFG + mac->offset, v);
enable_exact_filters(mac);
return -EIO;
}
t3_write_reg(adap, A_XGM_RX_MAX_PKT_SIZE + mac->offset, mtu);
t3_write_reg(adap, A_XGM_RX_CFG + mac->offset, v);
enable_exact_filters(mac);
} else
t3_write_reg(adap, A_XGM_RX_MAX_PKT_SIZE + mac->offset, mtu);
/*
* Adjust the PAUSE frame watermarks. We always set the LWM, and the
* HWM only if flow-control is enabled.
*/
hwm = max_t(unsigned int, MAC_RXFIFO_SIZE - 3 * mtu,
MAC_RXFIFO_SIZE * 38 / 100);
hwm = min(hwm, MAC_RXFIFO_SIZE - 8192);
hwm = rx_fifo_hwm(mtu);
lwm = min(3 * (int) mtu, MAC_RXFIFO_SIZE /4);
v = t3_read_reg(adap, A_XGM_RXFIFO_CFG + mac->offset);
v &= ~V_RXFIFOPAUSELWM(M_RXFIFOPAUSELWM);
@ -318,6 +393,7 @@ int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu)
if (G_RXFIFOPAUSEHWM(v))
v = (v & ~V_RXFIFOPAUSEHWM(M_RXFIFOPAUSEHWM)) |
V_RXFIFOPAUSEHWM(hwm / 8);
t3_write_reg(adap, A_XGM_RXFIFO_CFG + mac->offset, v);
/* Adjust the TX FIFO threshold based on the MTU */
@ -335,7 +411,7 @@ int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu)
*/
if (adap->params.rev > 0)
t3_write_reg(adap, A_XGM_PAUSE_TIMER + mac->offset,
(hwm-lwm) * 4 / 8);
(hwm - lwm) * 4 / 8);
t3_write_reg(adap, A_XGM_TX_PAUSE_QUANTA + mac->offset,
MAC_RXFIFO_SIZE * 4 * 8 / 512);
return 0;
@ -349,6 +425,8 @@ int t3_mac_set_speed_duplex_fc(struct cmac *mac, int speed, int duplex, int fc)
if (duplex >= 0 && duplex != DUPLEX_FULL)
return -EINVAL;
if (mac->multiport)
return t3_vsc7323_set_speed_fc(adap, speed, fc, mac->ext_port);
if (speed >= 0) {
if (speed == SPEED_10)
val = V_PORTSPEED(0);
@ -364,13 +442,14 @@ 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
val = t3_read_reg(adap, A_XGM_RXFIFO_CFG + oft);
val &= ~V_RXFIFOPAUSEHWM(M_RXFIFOPAUSEHWM);
if (fc & PAUSE_TX)
val |= V_RXFIFOPAUSEHWM(G_RXFIFOPAUSELWM(val) + 128); /* +1KB */
val |= V_RXFIFOPAUSEHWM(rx_fifo_hwm(t3_read_reg(adap,
A_XGM_RX_MAX_PKT_SIZE + oft)) / 8);
t3_write_reg(adap, A_XGM_RXFIFO_CFG + oft, val);
#endif
t3_set_reg_field(adap, A_XGM_TX_CFG + oft, F_TXPAUSEEN,
(fc & PAUSE_RX) ? F_TXPAUSEEN : 0);
return 0;
@ -383,6 +462,9 @@ int t3_mac_enable(struct cmac *mac, int which)
unsigned int oft = mac->offset;
struct mac_stats *s = &mac->stats;
if (mac->multiport)
return t3_vsc7323_enable(adap, mac->ext_port, which);
if (which & MAC_DIRECTION_TX) {
t3_write_reg(adap, A_XGM_TX_CTRL + oft, F_TXEN);
t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx);
@ -415,6 +497,9 @@ int t3_mac_disable(struct cmac *mac, int which)
adapter_t *adap = mac->adapter;
int val;
if (mac->multiport)
return t3_vsc7323_disable(adap, mac->ext_port, which);
if (which & MAC_DIRECTION_TX) {
t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset, 0);
t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx);

View File

@ -56,9 +56,13 @@ __FBSDID("$FreeBSD$");
#include <dev/pci/pcivar.h>
#ifdef CONFIG_DEFINED
#include <cxgb_include.h>
#include <cxgb_osdep.h>
#include <ulp/toecore/toedev.h>
#include <sys/mbufq.h>
#else
#include <dev/cxgb/cxgb_include.h>
#include <dev/cxgb/cxgb_osdep.h>
#include <dev/cxgb/sys/mbufq.h>
#include <dev/cxgb/ulp/toecore/toedev.h>
#endif
struct adapter;
@ -82,6 +86,7 @@ struct port_info {
uint8_t first_qset;
struct taskqueue *tq;
struct task start_task;
struct task timer_reclaim_task;
struct cdev *port_cdev;
};
@ -277,7 +282,6 @@ struct adapter {
/* Tasks */
struct task ext_intr_task;
struct task timer_reclaim_task;
struct task slow_intr_task;
struct task process_responses_task;
struct task mr_refresh_task;
@ -287,6 +291,7 @@ struct adapter {
/* Register lock for use by the hardware layer */
struct mtx mdio_lock;
struct mtx elmer_lock;
/* Bookkeeping for the hardware layer */
struct adapter_params params;
@ -319,6 +324,8 @@ struct t3_rx_mode {
#define MDIO_LOCK(adapter) mtx_lock(&(adapter)->mdio_lock)
#define MDIO_UNLOCK(adapter) mtx_unlock(&(adapter)->mdio_lock)
#define ELMR_LOCK(adapter) mtx_lock(&(adapter)->elmer_lock)
#define ELMR_UNLOCK(adapter) mtx_unlock(&(adapter)->elmer_lock)
#define PORT_LOCK(port) mtx_lock(&(port)->lock);
#define PORT_UNLOCK(port) mtx_unlock(&(port)->lock);
@ -413,7 +420,8 @@ void t3_intr_msi(void *data);
void t3_intr_msix(void *data);
int t3_encap(struct port_info *, struct mbuf **);
int t3_sge_init_sw(adapter_t *);
int t3_sge_init_adapter(adapter_t *);
int t3_sge_init_port(struct port_info *);
void t3_sge_deinit_sw(adapter_t *);
void t3_rx_eth_lro(adapter_t *adap, struct sge_rspq *rq, struct mbuf *m,

View File

@ -34,7 +34,6 @@ $FreeBSD$
#ifndef CONFIG_DEFINED
#define CONFIG_CHELSIO_T3_CORE
#define DEFAULT_JUMBO
#endif
#endif

View File

@ -87,14 +87,12 @@ __FBSDID("$FreeBSD$");
static __inline int
lro_match(struct mbuf *m, struct ip *ih, struct tcphdr *th)
{
struct ip *sih = (struct ip *)(m->m_data + IPH_OFFSET);
struct ip *sih = (struct ip *)(mtod(m, uint8_t *) + IPH_OFFSET);
struct tcphdr *sth = (struct tcphdr *) (sih + 1);
/*
* Why don't we check dest ports?
*/
return (*(uint32_t *)&th->th_sport == *(uint32_t *)&sth->th_sport &&
ih->ip_src.s_addr == ih->ip_src.s_addr &&
return (th->th_sport == sth->th_sport &&
th->th_dport == sth->th_dport &&
ih->ip_src.s_addr == sih->ip_src.s_addr &&
ih->ip_dst.s_addr == sih->ip_dst.s_addr);
}
@ -164,7 +162,7 @@ can_lro_tcpsegment(struct tcphdr *th)
static __inline void
lro_new_session_init(struct t3_lro_session *s, struct mbuf *m)
{
struct ip *ih = (struct ip *)(m->m_data + IPH_OFFSET);
struct ip *ih = (struct ip *)(mtod(m, uint8_t *) + IPH_OFFSET);
struct tcphdr *th = (struct tcphdr *) (ih + 1);
int ip_len = ntohs(ih->ip_len);
@ -183,7 +181,7 @@ lro_flush_session(struct sge_qset *qs, struct t3_lro_session *s, struct mbuf *m)
{
struct lro_state *l = &qs->lro;
struct mbuf *sm = s->head;
struct ip *ih = (struct ip *)(sm->m_data + IPH_OFFSET);
struct ip *ih = (struct ip *)(mtod(sm, uint8_t *) + IPH_OFFSET);
DPRINTF("%s(qs=%p, s=%p, ", __FUNCTION__,
@ -253,9 +251,9 @@ static __inline int
lro_update_session(struct t3_lro_session *s, struct mbuf *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);
struct cpl_rx_pkt *cpl = (struct cpl_rx_pkt *)(mtod(sm, uint8_t *) + 2);
struct cpl_rx_pkt *ncpl = (struct cpl_rx_pkt *)(mtod(m, uint8_t *) + 2);
struct ip *nih = (struct ip *)(mtod(m, uint8_t *) + IPH_OFFSET);
struct tcphdr *th, *nth = (struct tcphdr *)(nih + 1);
uint32_t seq = ntohl(nth->th_seq);
int plen, tcpiphlen, olen = (nth->th_off << 2) - sizeof (*nth);
@ -271,7 +269,7 @@ lro_update_session(struct t3_lro_session *s, struct mbuf *m)
}
MBUF_HEADER_CHECK(sm);
th = (struct tcphdr *)(sm->m_data + IPH_OFFSET + sizeof (struct ip));
th = (struct tcphdr *)(mtod(sm, uint8_t *) + IPH_OFFSET + sizeof (struct ip));
if (olen) {
uint32_t *ptr = (uint32_t *)(th + 1);
@ -338,7 +336,7 @@ 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)
{
struct sge_qset *qs = rspq_to_qset(rq);
struct cpl_rx_pkt *cpl = (struct cpl_rx_pkt *)(m->m_data + ethpad);
struct cpl_rx_pkt *cpl = (struct cpl_rx_pkt *)(mtod(m, uint8_t *) + ethpad);
struct ether_header *eh = (struct ether_header *)(cpl + 1);
struct ip *ih;
struct tcphdr *th;

View File

@ -83,6 +83,7 @@ __FBSDID("$FreeBSD$");
#endif
static int cxgb_setup_msix(adapter_t *, int);
static void cxgb_teardown_msix(adapter_t *);
static void cxgb_init(void *);
static void cxgb_init_locked(struct port_info *);
static void cxgb_stop_locked(struct port_info *);
@ -158,6 +159,17 @@ static driver_t cxgb_port_driver = {
};
static d_ioctl_t cxgb_extension_ioctl;
static d_open_t cxgb_extension_open;
static d_close_t cxgb_extension_close;
static struct cdevsw cxgb_cdevsw = {
.d_version = D_VERSION,
.d_flags = 0,
.d_open = cxgb_extension_open,
.d_close = cxgb_extension_close,
.d_ioctl = cxgb_extension_ioctl,
.d_name = "cxgb",
};
static devclass_t cxgb_port_devclass;
DRIVER_MODULE(cxgb, cxgbc, cxgb_port_driver, cxgb_port_devclass, 0, 0);
@ -230,6 +242,7 @@ struct cxgb_ident {
{PCI_VENDOR_ID_CHELSIO, 0x0030, 2, "T3B10"},
{PCI_VENDOR_ID_CHELSIO, 0x0031, 3, "T3B20"},
{PCI_VENDOR_ID_CHELSIO, 0x0032, 1, "T3B02"},
{PCI_VENDOR_ID_CHELSIO, 0x0033, 4, "T3B04"},
{0, 0, 0, NULL}
};
@ -267,17 +280,19 @@ cxgb_controller_probe(device_t dev)
{
const struct adapter_info *ai;
char *ports, buf[80];
int nports;
ai = cxgb_get_adapter_info(dev);
if (ai == NULL)
return (ENXIO);
if (ai->nports == 1)
nports = ai->nports0 + ai->nports1;
if (nports == 1)
ports = "port";
else
ports = "ports";
snprintf(buf, sizeof(buf), "%s RNIC, %d %s", ai->desc, ai->nports, ports);
snprintf(buf, sizeof(buf), "%s RNIC, %d %s", ai->desc, nports, ports);
device_set_desc_copy(dev, buf);
return (BUS_PROBE_DEFAULT);
}
@ -341,7 +356,6 @@ cxgb_controller_attach(device_t dev)
}
pci_enable_busmaster(dev);
/*
* Allocate the registers and make them available to the driver.
* The registers that we care about for NIC mode are in BAR 0
@ -356,6 +370,7 @@ cxgb_controller_attach(device_t dev)
mtx_init(&sc->sge.reg_lock, "SGE reg lock", NULL, MTX_DEF);
mtx_init(&sc->lock, "cxgb controller lock", NULL, MTX_DEF);
mtx_init(&sc->mdio_lock, "cxgb mdio", NULL, MTX_DEF);
mtx_init(&sc->elmer_lock, "cxgb elmer", NULL, MTX_DEF);
sc->bt = rman_get_bustag(sc->regs_res);
sc->bh = rman_get_bushandle(sc->regs_res);
@ -363,10 +378,10 @@ cxgb_controller_attach(device_t dev)
ai = cxgb_get_adapter_info(dev);
if (t3_prep_adapter(sc, ai, 1) < 0) {
printf("prep adapter failed\n");
error = ENODEV;
goto out;
}
/* Allocate the BAR for doing MSI-X. If it succeeds, try to allocate
* enough messages for the queue sets. If that fails, try falling
* back to MSI. If that fails, then try falling back to the legacy
@ -478,7 +493,7 @@ cxgb_controller_attach(device_t dev)
sc->params.stats_update_period = 1;
/* initialize sge private state */
t3_sge_init_sw(sc);
t3_sge_init_adapter(sc);
t3_led_ready(sc);
@ -554,12 +569,13 @@ cxgb_free(struct adapter *sc)
}
bus_generic_detach(sc->dev);
#ifdef notyet
if (is_offload(sc)) {
cxgb_adapter_unofld(sc);
if (isset(&sc->open_device_map, OFFLOAD_DEVMAP_BIT))
offload_close(&sc->tdev);
}
#endif
t3_free_sge_resources(sc);
t3_sge_free(sc);
@ -616,6 +632,28 @@ setup_sge_qsets(adapter_t *sc)
return (0);
}
static void
cxgb_teardown_msix(adapter_t *sc)
{
int i, nqsets;
for (nqsets = i = 0; i < (sc)->params.nports; i++)
nqsets += sc->port[i].nqsets;
for (i = 0; i < nqsets; 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;
}
}
}
static int
cxgb_setup_msix(adapter_t *sc, int msix_count)
{
@ -637,9 +675,9 @@ cxgb_setup_msix(adapter_t *sc, int msix_count)
device_printf(sc->dev, "Cannot set up interrupt\n");
return (EINVAL);
}
for (i = 0, k = 0; i < (sc)->params.nports; ++i) {
for (i = k = 0; i < (sc)->params.nports; i++) {
nqsets = sc->port[i].nqsets;
for (j = 0; j < nqsets; ++j, k++) {
for (j = 0; j < nqsets; j++, k++) {
struct sge_qset *qs = &sc->sge.qs[k];
rid = k + 2;
@ -653,7 +691,7 @@ cxgb_setup_msix(adapter_t *sc, int msix_count)
return (EINVAL);
}
sc->msix_irq_rid[k] = rid;
if (bus_setup_intr(sc->dev, sc->msix_irq_res[j],
if (bus_setup_intr(sc->dev, sc->msix_irq_res[k],
INTR_MPSAFE|INTR_TYPE_NET,
#ifdef INTR_FILTERS
NULL,
@ -687,17 +725,9 @@ cxgb_port_probe(device_t dev)
static int
cxgb_makedev(struct port_info *pi)
{
struct cdevsw *cxgb_cdevsw;
if ((cxgb_cdevsw = malloc(sizeof(struct cdevsw), M_DEVBUF, M_NOWAIT|M_ZERO)) == NULL)
return (ENOMEM);
cxgb_cdevsw->d_version = D_VERSION;
cxgb_cdevsw->d_name = strdup(pi->ifp->if_xname, M_DEVBUF);
cxgb_cdevsw->d_ioctl = cxgb_extension_ioctl;
pi->port_cdev = make_dev(cxgb_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600,
pi->ifp->if_xname);
pi->port_cdev = make_dev(&cxgb_cdevsw, pi->ifp->if_dunit,
UID_ROOT, GID_WHEEL, 0600, if_name(pi->ifp));
if (pi->port_cdev == NULL)
return (ENOMEM);
@ -726,8 +756,7 @@ cxgb_port_attach(device_t dev)
{
struct port_info *p;
struct ifnet *ifp;
int media_flags;
int err;
int err, media_flags;
char buf[64];
p = device_get_softc(dev);
@ -762,7 +791,6 @@ cxgb_port_attach(device_t dev)
ifp->if_capabilities |= CXGB_CAP;
ifp->if_capenable |= CXGB_CAP_ENABLE;
ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP | CSUM_IP | CSUM_TSO);
ifp->if_baudrate = 100000000;
ether_ifattach(ifp, p->hw_addr);
#ifdef DEFAULT_JUMBO
@ -774,21 +802,36 @@ cxgb_port_attach(device_t dev)
}
ifmedia_init(&p->media, IFM_IMASK, cxgb_media_change,
cxgb_media_status);
if (!strcmp(p->port_type->desc, "10GBASE-CX4"))
media_flags = IFM_ETHER | IFM_10G_CX4;
else if (!strcmp(p->port_type->desc, "10GBASE-SR"))
media_flags = IFM_ETHER | IFM_10G_SR;
else if (!strcmp(p->port_type->desc, "10GBASE-XR"))
media_flags = IFM_ETHER | IFM_10G_LR;
else {
if (!strcmp(p->port_type->desc, "10GBASE-CX4")) {
media_flags = IFM_ETHER | IFM_10G_CX4 | IFM_FDX;
} else if (!strcmp(p->port_type->desc, "10GBASE-SR")) {
media_flags = IFM_ETHER | IFM_10G_SR | IFM_FDX;
} else if (!strcmp(p->port_type->desc, "10GBASE-XR")) {
media_flags = IFM_ETHER | IFM_10G_LR | IFM_FDX;
} else if (!strcmp(p->port_type->desc, "10/100/1000BASE-T")) {
ifmedia_add(&p->media, IFM_ETHER | IFM_10_T, 0, NULL);
ifmedia_add(&p->media, IFM_ETHER | IFM_10_T | IFM_FDX,
0, NULL);
ifmedia_add(&p->media, IFM_ETHER | IFM_100_TX,
0, NULL);
ifmedia_add(&p->media, IFM_ETHER | IFM_100_TX | IFM_FDX,
0, NULL);
ifmedia_add(&p->media, IFM_ETHER | IFM_1000_T | IFM_FDX,
0, NULL);
media_flags = 0;
} else {
printf("unsupported media type %s\n", p->port_type->desc);
return (ENXIO);
}
ifmedia_add(&p->media, media_flags, 0, NULL);
ifmedia_add(&p->media, IFM_ETHER | IFM_AUTO, 0, NULL);
ifmedia_set(&p->media, media_flags);
if (media_flags) {
ifmedia_add(&p->media, media_flags, 0, NULL);
ifmedia_set(&p->media, media_flags);
} else {
ifmedia_add(&p->media, IFM_ETHER | IFM_AUTO, 0, NULL);
ifmedia_set(&p->media, IFM_ETHER | IFM_AUTO);
}
snprintf(buf, sizeof(buf), "cxgb_port_taskq%d", p->port);
#ifdef TASKQUEUE_CURRENT
@ -800,8 +843,7 @@ cxgb_port_attach(device_t dev)
p->tq = taskqueue_create_fast(buf, M_NOWAIT,
taskqueue_thread_enqueue, &p->tq);
#endif
if (p->tq == NULL) {
device_printf(dev, "failed to allocate port task queue\n");
return (ENOMEM);
@ -810,7 +852,8 @@ cxgb_port_attach(device_t dev)
device_get_nameunit(dev));
TASK_INIT(&p->start_task, 0, cxgb_start_proc, ifp);
t3_sge_init_port(p);
return (0);
}
@ -822,7 +865,8 @@ cxgb_port_detach(device_t dev)
p = device_get_softc(dev);
PORT_LOCK(p);
cxgb_stop_locked(p);
if (p->ifp->if_drv_flags & IFF_DRV_RUNNING)
cxgb_stop_locked(p);
PORT_UNLOCK(p);
mtx_destroy(&p->lock);
@ -835,9 +879,9 @@ cxgb_port_detach(device_t dev)
ether_ifdetach(p->ifp);
if_free(p->ifp);
destroy_dev(p->port_cdev);
if (p->port_cdev != NULL)
destroy_dev(p->port_cdev);
return (0);
}
@ -1007,7 +1051,7 @@ cxgb_link_start(struct port_info *p)
t3_init_rx_mode(&rm, p);
t3_mac_reset(mac);
t3_mac_set_mtu(mac, ifp->if_mtu + ETHER_HDR_LEN);
t3_mac_set_mtu(mac, ifp->if_mtu + ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN);
t3_mac_set_address(mac, 0, p->hw_addr);
t3_mac_set_rx_mode(mac, &rm);
t3_link_start(&p->phy, mac, &p->link_config);
@ -1060,7 +1104,7 @@ offload_tx(struct toedev *tdev, struct mbuf *m)
critical_enter();
ret = t3_offload_tx(tdev, m);
critical_exit();
return ret;
return (ret);
}
static int
@ -1135,9 +1179,6 @@ bind_qsets(adapter_t *sc)
{
int i, j;
if (singleq)
return;
for (i = 0; i < (sc)->params.nports; ++i) {
const struct port_info *pi = adap2pinfo(sc, i);
@ -1229,23 +1270,13 @@ static void
cxgb_down(struct adapter *sc)
{
int i;
t3_sge_stop(sc);
ADAPTER_LOCK(sc);
t3_intr_disable(sc);
ADAPTER_UNLOCK(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;
@ -1257,10 +1288,17 @@ cxgb_down(struct adapter *sc)
sc->irq_res);
sc->irq_res = NULL;
}
if (sc->flags & USING_MSIX)
cxgb_teardown_msix(sc);
callout_drain(&sc->sge_timer_ch);
taskqueue_drain(sc->tq, &sc->slow_intr_task);
taskqueue_drain(sc->tq, &sc->timer_reclaim_task);
if (sc->tq != NULL)
taskqueue_drain(sc->tq, &sc->slow_intr_task);
for (i = 0; i < sc->params.nports; i++)
if (sc->port[i].tq != NULL)
taskqueue_drain(sc->port[i].tq, &sc->port[i].timer_reclaim_task);
}
static int
@ -1315,7 +1353,7 @@ offload_close(struct toedev *tdev)
struct adapter *adapter = tdev2adap(tdev);
if (!isset(&adapter->open_device_map, OFFLOAD_DEVMAP_BIT))
return 0;
return (0);
/* Call back all registered clients */
cxgb_remove_clients(tdev);
@ -1330,7 +1368,7 @@ offload_close(struct toedev *tdev)
ADAPTER_UNLOCK(adapter);
cxgb_offload_deactivate(adapter);
return 0;
return (0);
}
static void
@ -1363,8 +1401,8 @@ cxgb_init_locked(struct port_info *p)
t3_intr_clear(sc);
setbit(&p->adapter->open_device_map, p->port);
ADAPTER_UNLOCK(p->adapter);
if (is_offload(sc) && !ofld_disable) {
err = offload_open(p);
if (err)
@ -1372,6 +1410,9 @@ cxgb_init_locked(struct port_info *p)
"Could not initialize offload capabilities\n");
}
cxgb_link_start(p);
t3_link_changed(sc, p->port);
ifp->if_baudrate = p->link_config.speed * 1000000;
t3_port_intr_enable(sc, p->port);
callout_reset(&sc->cxgb_tick_ch, sc->params.stats_update_period * hz,
@ -1388,7 +1429,7 @@ cxgb_set_rxmode(struct port_info *p)
struct cmac *mac = &p->mac;
mtx_assert(&p->lock, MA_OWNED);
t3_init_rx_mode(&rm, p);
t3_mac_set_rx_mode(mac, &rm);
}
@ -1400,13 +1441,11 @@ cxgb_stop_locked(struct port_info *p)
mtx_assert(&p->lock, MA_OWNED);
mtx_assert(&p->adapter->lock, MA_NOTOWNED);
ifp = p->ifp;
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);
@ -1420,6 +1459,27 @@ cxgb_stop_locked(struct port_info *p)
ADAPTER_UNLOCK(p->adapter);
}
static int
cxgb_set_mtu(struct port_info *p, int mtu)
{
struct ifnet *ifp = p->ifp;
int error = 0;
if ((mtu < ETHERMIN) || (mtu > ETHER_MAX_LEN_JUMBO))
error = EINVAL;
else if (ifp->if_mtu != mtu) {
PORT_LOCK(p);
ifp->if_mtu = mtu;
if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
callout_stop(&p->adapter->cxgb_tick_ch);
cxgb_stop_locked(p);
cxgb_init_locked(p);
}
PORT_UNLOCK(p);
}
return (error);
}
static int
cxgb_ioctl(struct ifnet *ifp, unsigned long command, caddr_t data)
{
@ -1434,30 +1494,23 @@ cxgb_ioctl(struct ifnet *ifp, unsigned long command, caddr_t data)
*/
switch (command) {
case SIOCSIFMTU:
if ((ifr->ifr_mtu < ETHERMIN) ||
(ifr->ifr_mtu > ETHER_MAX_LEN_JUMBO))
error = EINVAL;
else if (ifp->if_mtu != ifr->ifr_mtu) {
PORT_LOCK(p);
ifp->if_mtu = ifr->ifr_mtu;
t3_mac_set_mtu(&p->mac, ifp->if_mtu + ETHER_HDR_LEN);
PORT_UNLOCK(p);
}
error = cxgb_set_mtu(p, ifr->ifr_mtu);
break;
case SIOCSIFADDR:
case SIOCGIFADDR:
PORT_LOCK(p);
if (ifa->ifa_addr->sa_family == AF_INET) {
ifp->if_flags |= IFF_UP;
if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
cxgb_init(p);
}
if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
cxgb_init_locked(p);
arp_ifinit(ifp, ifa);
} else
error = ether_ioctl(ifp, command, data);
PORT_UNLOCK(p);
break;
case SIOCSIFFLAGS:
PORT_LOCK(p);
if (ifp->if_flags & IFF_UP) {
PORT_LOCK(p);
if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
flags = p->if_flags;
if (((ifp->if_flags ^ flags) & IFF_PROMISC) ||
@ -1467,10 +1520,8 @@ cxgb_ioctl(struct ifnet *ifp, unsigned long command, caddr_t data)
} else
cxgb_init_locked(p);
p->if_flags = ifp->if_flags;
PORT_UNLOCK(p);
} else {
callout_drain(&p->adapter->cxgb_tick_ch);
PORT_LOCK(p);
callout_stop(&p->adapter->cxgb_tick_ch);
if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
cxgb_stop_locked(p);
} else {
@ -1479,10 +1530,8 @@ cxgb_ioctl(struct ifnet *ifp, unsigned long command, caddr_t data)
sc->params.stats_update_period * hz,
cxgb_tick, sc);
}
PORT_UNLOCK(p);
}
PORT_UNLOCK(p);
break;
case SIOCSIFMEDIA:
case SIOCGIFMEDIA:
@ -1527,7 +1576,6 @@ cxgb_ioctl(struct ifnet *ifp, unsigned long command, caddr_t data)
error = ether_ioctl(ifp, command, data);
break;
}
return (error);
}
@ -1539,7 +1587,7 @@ cxgb_start_tx(struct ifnet *ifp, uint32_t txmax)
struct port_info *p = ifp->if_softc;
struct mbuf *m0, *m = NULL;
int err, in_use_init;
if (!p->link_config.link_ok)
return (ENXIO);
@ -1598,13 +1646,12 @@ cxgb_start_tx(struct ifnet *ifp, uint32_t txmax)
IFQ_UNLOCK(&ifp->if_snd);
}
}
if (err == 0 && m == NULL) {
return (ENOBUFS);
}
if ((err == 0) && (txq->size <= txq->in_use + TX_MAX_DESC) &&
if (err == 0 && m == NULL)
err = ENOBUFS;
else if ((err == 0) && (txq->size <= txq->in_use + TX_MAX_DESC) &&
(ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) {
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
return (ENOSPC);
err = ENOSPC;
}
return (err);
}
@ -1616,18 +1663,18 @@ cxgb_start_proc(void *arg, int ncount)
struct port_info *pi = ifp->if_softc;
struct sge_qset *qs;
struct sge_txq *txq;
int error = 0;
int error;
qs = &pi->adapter->sge.qs[pi->first_qset];
txq = &qs->txq[TXQ_ETH];
while (error == 0) {
do {
if (desc_reclaimable(txq) > TX_CLEAN_MAX_DESC)
taskqueue_enqueue(pi->adapter->tq,
&pi->adapter->timer_reclaim_task);
&pi->timer_reclaim_task);
error = cxgb_start_tx(ifp, TX_START_MAX_DESC);
}
} while (error == 0);
}
static void
@ -1643,7 +1690,7 @@ cxgb_start(struct ifnet *ifp)
if (desc_reclaimable(txq) > TX_CLEAN_MAX_DESC)
taskqueue_enqueue(pi->adapter->tq,
&pi->adapter->timer_reclaim_task);
&pi->timer_reclaim_task);
err = cxgb_start_tx(ifp, TX_START_MAX_DESC);
@ -1672,6 +1719,18 @@ cxgb_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
ifmr->ifm_status |= IFM_ACTIVE;
switch (p->link_config.speed) {
case 10:
ifmr->ifm_active |= IFM_10_T;
break;
case 100:
ifmr->ifm_active |= IFM_100_TX;
break;
case 1000:
ifmr->ifm_active |= IFM_1000_T;
break;
}
if (p->link_config.duplex)
ifmr->ifm_active |= IFM_FDX;
else
@ -1718,8 +1777,9 @@ check_link_status(adapter_t *sc)
for (i = 0; i < (sc)->params.nports; ++i) {
struct port_info *p = &sc->port[i];
if (!(p->port_type->caps & SUPPORTED_IRQ))
if (!(p->port_type->caps & SUPPORTED_IRQ))
t3_link_changed(sc, i);
p->ifp->if_baudrate = p->link_config.speed * 1000000;
}
}
@ -1745,7 +1805,8 @@ check_t3b2_mac(struct adapter *adapter)
else if (status == 2) {
struct cmac *mac = &p->mac;
t3_mac_set_mtu(mac, ifp->if_mtu + ETHER_HDR_LEN);
t3_mac_set_mtu(mac, ifp->if_mtu + ETHER_HDR_LEN
+ ETHER_VLAN_ENCAP_LEN);
t3_mac_set_address(mac, 0, p->hw_addr);
cxgb_set_rxmode(p);
t3_link_start(&p->phy, mac, &p->link_config);
@ -1773,9 +1834,9 @@ cxgb_tick(void *arg)
* port lock
*/
ADAPTER_UNLOCK(sc);
if (p->rev == T3_REV_B2)
check_t3b2_mac(sc);
}
static int
@ -1784,6 +1845,18 @@ in_range(int val, int lo, int hi)
return val < 0 || (val <= hi && val >= lo);
}
static int
cxgb_extension_open(struct cdev *dev, int flags, int fmp, d_thread_t *td)
{
return (0);
}
static int
cxgb_extension_close(struct cdev *dev, int flags, int fmt, d_thread_t *td)
{
return (0);
}
static int
cxgb_extension_ioctl(struct cdev *dev, unsigned long cmd, caddr_t data,
int fflag, struct thread *td)

View File

@ -720,8 +720,14 @@ static int
do_hwtid_rpl(struct toedev *dev, struct mbuf *m)
{
union opcode_tid *p = cplhdr(m);
unsigned int hwtid = G_TID(ntohl(p->opcode_tid));
unsigned int hwtid;
struct toe_tid_entry *toe_tid;
printf("do_hwtid_rpl m=%p\n", m);
return (0);
hwtid = G_TID(ntohl(p->opcode_tid));
toe_tid = lookup_tid(&(TOE_DATA(dev))->tid_maps, hwtid);
if (toe_tid->ctx && toe_tid->client->handlers &&
@ -1115,7 +1121,7 @@ process_rx(struct toedev *dev, struct mbuf **m, int n)
{
while (n--) {
struct mbuf *m0 = *m++;
unsigned int opcode = G_OPCODE(ntohl(m0->m_pkthdr.csum_data));
unsigned int opcode = G_OPCODE(ntohl(m0->m_pkthdr.csum_data));
int ret = cpl_handlers[opcode] (dev, m0);
#if VALIDATE_TID

View File

@ -130,7 +130,7 @@ typedef int (*cpl_handler_func)(struct toedev *dev, struct mbuf *m);
*/
static inline void *cplhdr(struct mbuf *m)
{
return m->m_data;
return mtod(m, uint8_t *);
}
void t3_register_cpl_handler(unsigned int opcode, cpl_handler_func h);

View File

@ -307,7 +307,7 @@ get_imm_packet(adapter_t *sc, const struct rsp_desc *resp, struct mbuf *m, void
switch (sopeop) {
case RSPQ_SOP_EOP:
m->m_len = m->m_pkthdr.len = len;
memcpy(m->m_data, resp->imm_data, len);
memcpy(mtod(m, uint8_t *), resp->imm_data, len);
break;
case RSPQ_EOP:
memcpy(cl, resp->imm_data, len);
@ -666,6 +666,7 @@ static void
sge_timer_cb(void *arg)
{
adapter_t *sc = arg;
struct port_info *p;
struct sge_qset *qs;
struct sge_txq *txq;
int i, j;
@ -680,11 +681,11 @@ sge_timer_cb(void *arg)
refill_rx = ((qs->fl[0].credits < qs->fl[0].size) ||
(qs->fl[1].credits < qs->fl[1].size));
if (reclaim_eth || reclaim_ofl || refill_rx) {
taskqueue_enqueue(sc->tq, &sc->timer_reclaim_task);
goto done;
p = &sc->port[i];
taskqueue_enqueue(p->tq, &p->timer_reclaim_task);
break;
}
}
done:
callout_reset(&sc->sge_timer_ch, TX_RECLAIM_PERIOD, sge_timer_cb, sc);
}
@ -694,24 +695,31 @@ done:
*
*/
int
t3_sge_init_sw(adapter_t *sc)
t3_sge_init_adapter(adapter_t *sc)
{
callout_init(&sc->sge_timer_ch, CALLOUT_MPSAFE);
callout_reset(&sc->sge_timer_ch, TX_RECLAIM_PERIOD, sge_timer_cb, sc);
TASK_INIT(&sc->timer_reclaim_task, 0, sge_timer_reclaim, sc);
TASK_INIT(&sc->slow_intr_task, 0, sge_slow_intr_handler, sc);
return (0);
}
int
t3_sge_init_port(struct port_info *p)
{
TASK_INIT(&p->timer_reclaim_task, 0, sge_timer_reclaim, p);
}
void
t3_sge_deinit_sw(adapter_t *sc)
{
int i;
callout_drain(&sc->sge_timer_ch);
if (sc->tq) {
taskqueue_drain(sc->tq, &sc->timer_reclaim_task);
if (sc->tq)
taskqueue_drain(sc->tq, &sc->slow_intr_task);
}
for (i = 0; i < sc->params.nports; i++)
if (sc->port[i].tq != NULL)
taskqueue_drain(sc->port[i].tq, &sc->port[i].timer_reclaim_task);
}
/**
@ -736,38 +744,34 @@ refill_rspq(adapter_t *sc, const struct sge_rspq *q, u_int credits)
static void
sge_timer_reclaim(void *arg, int ncount)
{
adapter_t *sc = arg;
int i, nqsets = 0;
struct port_info *p = arg;
int i, nqsets = p->nqsets;
adapter_t *sc = p->adapter;
struct sge_qset *qs;
struct sge_txq *txq;
struct mtx *lock;
struct mbuf *m_vec[TX_CLEAN_MAX_DESC];
int n, reclaimable;
/*
* XXX assuming these quantities are allowed to change during operation
*/
for (i = 0; i < sc->params.nports; i++)
nqsets += sc->port[i].nqsets;
for (i = 0; i < nqsets; i++) {
qs = &sc->sge.qs[i];
txq = &qs->txq[TXQ_ETH];
reclaimable = desc_reclaimable(txq);
if (reclaimable > 0) {
mtx_lock(&txq->lock);
mtx_lock(&txq->lock);
n = reclaim_completed_tx(sc, txq, TX_CLEAN_MAX_DESC, m_vec);
mtx_unlock(&txq->lock);
for (i = 0; i < n; i++) {
for (i = 0; i < n; i++)
m_freem_vec(m_vec[i]);
}
if (qs->port->ifp->if_drv_flags & IFF_DRV_OACTIVE &&
if (p->ifp->if_drv_flags & IFF_DRV_OACTIVE &&
txq->size - txq->in_use >= TX_START_MAX_DESC) {
qs->port->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
taskqueue_enqueue(qs->port->tq, &qs->port->start_task);
p->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
taskqueue_enqueue(p->tq, &p->start_task);
}
}
}
txq = &qs->txq[TXQ_OFLD];
reclaimable = desc_reclaimable(txq);
if (reclaimable > 0) {
@ -775,9 +779,8 @@ sge_timer_reclaim(void *arg, int ncount)
n = reclaim_completed_tx(sc, txq, TX_CLEAN_MAX_DESC, m_vec);
mtx_unlock(&txq->lock);
for (i = 0; i < n; i++) {
for (i = 0; i < n; i++)
m_freem_vec(m_vec[i]);
}
}
lock = (sc->flags & USING_MSIX) ? &qs->rspq.lock :
@ -1149,7 +1152,7 @@ t3_encap(struct port_info *p, struct mbuf **m)
pkthdr = &tmp[0];
m_copydata(m0, 0, TCPPKTHDRSIZE, pkthdr);
} else {
pkthdr = m0->m_data;
pkthdr = mtod(m0, uint8_t *);
}
if (__predict_false(m0->m_flags & M_VLANTAG)) {
@ -1178,7 +1181,7 @@ t3_encap(struct port_info *p, struct mbuf **m)
m_set_priority(m0, txqs.pidx);
if (m0->m_len == m0->m_pkthdr.len)
memcpy(&txd->flit[2], m0->m_data, mlen);
memcpy(&txd->flit[2], mtod(m0, uint8_t *), mlen);
else
m_copydata(m0, 0, mlen, (caddr_t)&txd->flit[2]);
@ -1343,7 +1346,7 @@ static int
ctrl_xmit(adapter_t *adap, struct sge_txq *q, struct mbuf *m)
{
int ret;
struct work_request_hdr *wrp = (struct work_request_hdr *)m->m_data;
struct work_request_hdr *wrp = mtod(m, struct work_request_hdr *);
if (__predict_false(!immediate(m))) {
m_freem(m);
@ -1547,6 +1550,9 @@ t3_sge_stop(adapter_t *sc)
int i;
t3_set_reg_field(sc, A_SG_CONTROL, F_GLOBALENABLE, 0);
if (sc->tq == NULL)
return;
for (i = 0; i < SGE_QSETS; ++i) {
struct sge_qset *qs = &sc->sge.qs[i];
@ -2105,12 +2111,12 @@ err:
void
t3_rx_eth(struct port_info *pi, struct sge_rspq *rq, struct mbuf *m, int ethpad)
{
struct cpl_rx_pkt *cpl = (struct cpl_rx_pkt *)(m->m_data + ethpad);
struct cpl_rx_pkt *cpl = (struct cpl_rx_pkt *)(mtod(m, uint8_t *) + ethpad);
struct ifnet *ifp = pi->ifp;
DPRINTF("rx_eth m=%p m->m_data=%p p->iff=%d\n", m, m->m_data, cpl->iff);
DPRINTF("rx_eth m=%p m->m_data=%p p->iff=%d\n", m, mtod(m, uint8_t *), cpl->iff);
if (&pi->adapter->port[cpl->iff] != pi)
panic("bad port index %d m->m_data=%p\n", cpl->iff, m->m_data);
panic("bad port index %d m->m_data=%p\n", cpl->iff, mtod(m, uint8_t *));
if ((ifp->if_capenable & IFCAP_RXCSUM) && !cpl->fragment &&
cpl->csum_valid && cpl->csum == 0xffff) {
@ -2130,7 +2136,7 @@ t3_rx_eth(struct port_info *pi, struct sge_rspq *rq, struct mbuf *m, int ethpad)
#endif
m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.header = m->m_data + sizeof(*cpl) + ethpad;
m->m_pkthdr.header = mtod(m, uint8_t *) + sizeof(*cpl) + ethpad;
m_explode(m);
/*
* adjust after conversion to mbuf chain
@ -2215,7 +2221,6 @@ done:
return (ret);
}
/**
* handle_rsp_cntrl_info - handles control information in a response
* @qs: the queue set corresponding to the response
@ -2239,7 +2244,7 @@ handle_rsp_cntrl_info(struct sge_qset *qs, uint32_t flags)
qs->txq[TXQ_ETH].processed += credits;
if (desc_reclaimable(&qs->txq[TXQ_ETH]) > TX_START_MAX_DESC)
taskqueue_enqueue(qs->port->adapter->tq,
&qs->port->adapter->timer_reclaim_task);
&qs->port->timer_reclaim_task);
}
credits = G_RSPD_TXQ2_CR(flags);
@ -2361,8 +2366,8 @@ process_responses(adapter_t *adap, struct sge_qset *qs, int budget)
}
if (eop) {
prefetch(rspq->m->m_data);
prefetch(rspq->m->m_data + L1_CACHE_BYTES);
prefetch(mtod(rspq->m, uint8_t *));
prefetch(mtod(rspq->m, uint8_t *) + L1_CACHE_BYTES);
if (eth) {
t3_rx_eth_lro(adap, rspq, rspq->m, ethpad,
@ -2388,7 +2393,6 @@ process_responses(adapter_t *adap, struct sge_qset *qs, int budget)
}
--budget_left;
}
deliver_partial_bundle(&adap->tdev, rspq, offload_mbufs, ngathered);
t3_lro_flush(adap, qs, &qs->lro);
@ -2520,9 +2524,8 @@ t3_lro_enable(SYSCTL_HANDLER_ARGS)
enabled = sc->sge.qs[0].lro.enabled;
err = sysctl_handle_int(oidp, &enabled, arg2, req);
if (err != 0) {
if (err != 0)
return (err);
}
if (enabled == sc->sge.qs[0].lro.enabled)
return (0);
@ -2530,9 +2533,8 @@ t3_lro_enable(SYSCTL_HANDLER_ARGS)
for (j = 0; j < sc->port[i].nqsets; j++)
nqsets++;
for (i = 0; i < nqsets; i++) {
for (i = 0; i < nqsets; i++)
sc->sge.qs[i].lro.enabled = enabled;
}
return (0);
}

View File

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

View File

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

View File

@ -5,22 +5,22 @@ 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+= cxgb_offload.c cxgb_l2t.c
SRCS+= cxgb_xgmac.c cxgb_vsc7323.c cxgb_t3_hw.c cxgb_main.c
SRCS+= cxgb_sge.c cxgb_lro.c 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 -I${CXGB}
#CFLAGS+= -DINVARIANT_SUPPORT -DINVARIANTS -DDEBUG
CFLAGS+= -DCONFIG_CHELSIO_T3_CORE -g -DCONFIG_DEFINED -DDEFAULT_JUMBO -I${CXGB}
#CFLAGS+= -DINVARIANT_SUPPORT -DINVARIANTS
.if ${MACHINE_ARCH} != "ia64"
# ld is broken on ia64
t3fw-4.0.0.bin: ${CXGB}/t3fw-4.0.0.bin.gz.uu
uudecode -p < ${CXGB}/t3fw-4.0.0.bin.gz.uu \
t3fw-4.1.0.bin: ${CXGB}/t3fw-4.1.0.bin.gz.uu
uudecode -p < ${CXGB}/t3fw-4.1.0.bin.gz.uu \
| gzip -dc > ${.TARGET}
FIRMWS= t3fw-4.0.0.bin:t3fw400
CLEANFILES+= t3fw-4.0.0.bin
FIRMWS= t3fw-4.1.0.bin:t3fw410
CLEANFILES+= t3fw-4.1.0.bin
.endif