svn commit: r193539 - in stable/7/sys: . conf contrib/pf
dev/ath/ath_hal dev/cxgb dev/cxgb/common modules/cxgb/cxgb_t3fw
George V. Neville-Neil
gnn at FreeBSD.org
Fri Jun 5 22:23:34 UTC 2009
Author: gnn
Date: Fri Jun 5 22:23:33 2009
New Revision: 193539
URL: http://svn.freebsd.org/changeset/base/193539
Log:
MFC of 189643
Update the Chelsio driver to the latest bits from Chelsio
Firmware upgraded to 7.1.0 (from 5.0.0).
T3C EEPROM and SRAM added; Code to update eeprom/sram fixed.
fl_empty and rx_fifo_ovfl counters can be observed via sysctl.
Two new cxgbtool commands to get uP logic analyzer info and uP IOQs
Synced up with Chelsio's "common code" (as of 03/03/09)
Added:
stable/7/sys/dev/cxgb/t3c_protocol_sram.h
- copied unchanged from r189643, head/sys/dev/cxgb/t3c_protocol_sram.h
stable/7/sys/dev/cxgb/t3c_tp_eeprom.h
- copied unchanged from r189643, head/sys/dev/cxgb/t3c_tp_eeprom.h
Modified:
stable/7/sys/ (props changed)
stable/7/sys/conf/kern.pre.mk
stable/7/sys/contrib/pf/ (props changed)
stable/7/sys/dev/ath/ath_hal/ (props changed)
stable/7/sys/dev/cxgb/ (props changed)
stable/7/sys/dev/cxgb/common/cxgb_ael1002.c
stable/7/sys/dev/cxgb/common/cxgb_common.h
stable/7/sys/dev/cxgb/common/cxgb_t3_cpl.h
stable/7/sys/dev/cxgb/common/cxgb_t3_hw.c
stable/7/sys/dev/cxgb/common/cxgb_xgmac.c
stable/7/sys/dev/cxgb/cxgb_adapter.h
stable/7/sys/dev/cxgb/cxgb_ioctl.h
stable/7/sys/dev/cxgb/cxgb_main.c
stable/7/sys/dev/cxgb/cxgb_sge.c
stable/7/sys/dev/cxgb/cxgb_t3fw.c
stable/7/sys/dev/cxgb/cxgb_t3fw.h
stable/7/sys/modules/cxgb/cxgb_t3fw/Makefile
Modified: stable/7/sys/conf/kern.pre.mk
==============================================================================
--- stable/7/sys/conf/kern.pre.mk Fri Jun 5 22:21:10 2009 (r193538)
+++ stable/7/sys/conf/kern.pre.mk Fri Jun 5 22:23:33 2009 (r193539)
@@ -80,6 +80,9 @@ INCLUDES+= -I$S/gnu/fs/xfs/FreeBSD -I$S/
# ... and OpenSolaris
INCLUDES+= -I$S/contrib/opensolaris/compat
+# ... and the same for cxgb
+INCLUDES+= -I$S/dev/cxgb
+
.endif
CFLAGS= ${COPTFLAGS} ${C_DIALECT} ${DEBUG} ${CWARNFLAGS}
Modified: stable/7/sys/dev/cxgb/common/cxgb_ael1002.c
==============================================================================
--- stable/7/sys/dev/cxgb/common/cxgb_ael1002.c Fri Jun 5 22:21:10 2009 (r193538)
+++ stable/7/sys/dev/cxgb/common/cxgb_ael1002.c Fri Jun 5 22:23:33 2009 (r193539)
@@ -1,6 +1,6 @@
/**************************************************************************
-Copyright (c) 2007-2008, Chelsio Inc.
+Copyright (c) 2007-2009, Chelsio Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -64,7 +64,17 @@ enum {
enum { edc_none, edc_sr, edc_twinax };
/* PHY module I2C device address */
-#define MODULE_DEV_ADDR 0xa0
+enum {
+ MODULE_DEV_ADDR = 0xa0,
+ SFF_DEV_ADDR = 0xa2,
+};
+
+/* PHY transceiver type */
+enum {
+ phy_transtype_unknown = 0,
+ phy_transtype_sfp = 3,
+ phy_transtype_xfp = 6,
+};
#define AEL2005_MODDET_IRQ 4
@@ -75,73 +85,7 @@ struct reg_val {
unsigned short set_bits;
};
-static int ael2005_i2c_rd(struct cphy *phy, int dev_addr, int word_addr);
-
-static int get_module_type (struct cphy *phy, int hint)
-{
- int v;
-
- v = hint ? hint : ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 0);
- if (v < 0)
- return v;
-
- if (v == 0x3) {
- /* SFP: see SFF-8472 for below */
- v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 3);
- if (v < 0)
- return v;
-
- if (v == 0x1)
- return phy_modtype_twinax;
- if (v == 0x10)
- return phy_modtype_sr;
- if (v == 0x20)
- return phy_modtype_lr;
- if (v == 0x40)
- return phy_modtype_lrm;
-
- v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 6);
- if (v < 0)
- return v;
- if (v != 4)
- return phy_modtype_unknown;
-
- v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 10);
- if (v < 0)
- return v;
-
- if (v & 0x80) {
- v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 0x12);
- if (v < 0)
- return v;
- return v > 10 ? phy_modtype_twinax_long :
- phy_modtype_twinax;
- }
- } else if (v == 0x6) {
- /* XFP: See INF-8077i for details. */
-
- v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 127);
- if (v < 0)
- return v;
-
- if (v != 1) {
- /* XXX: set page select to table 1 yourself */
- return phy_modtype_unknown;
- }
-
- v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 131);
- if (v < 0)
- return v;
- if (v == 0x10)
- return phy_modtype_lrm;
- if (v == 0x40)
- return phy_modtype_lr;
- if (v == 0x80)
- return phy_modtype_sr;
- }
-
- return phy_modtype_unknown;
-}
+static int get_module_type(struct cphy *phy);
static int set_phy_regs(struct cphy *phy, const struct reg_val *rv)
{
@@ -168,6 +112,110 @@ static void ael100x_txon(struct cphy *ph
msleep(30);
}
+static int ael_i2c_rd(struct cphy *phy, int dev_addr, int word_addr)
+{
+ int i, err;
+ unsigned int stat, data;
+
+ err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL_I2C_CTRL,
+ (dev_addr << 8) | (1 << 8) | word_addr);
+ if (err)
+ return err;
+
+ for (i = 0; i < 200; i++) {
+ msleep(1);
+ err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_STAT, &stat);
+ if (err)
+ return err;
+ if ((stat & 3) == 1) {
+ err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_DATA,
+ &data);
+ if (err)
+ return err;
+ return data >> 8;
+ }
+ }
+ CH_WARN(phy->adapter, "PHY %u I2C read of addr %u timed out\n",
+ phy->addr, word_addr);
+ return -ETIMEDOUT;
+}
+
+static int ael_i2c_wr(struct cphy *phy, int dev_addr, int word_addr, int data)
+{
+ int i, err;
+ unsigned int stat;
+
+ err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL_I2C_DATA, data);
+ if (err)
+ return err;
+
+ err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL_I2C_CTRL,
+ (dev_addr << 8) | word_addr);
+ if (err)
+ return err;
+
+ for (i = 0; i < 200; i++) {
+ msleep(1);
+ err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_STAT, &stat);
+ if (err)
+ return err;
+ if ((stat & 3) == 1)
+ return 0;
+ }
+ CH_WARN(phy->adapter, "PHY %u I2C Write of addr %u timed out\n",
+ phy->addr, word_addr);
+ return -ETIMEDOUT;
+}
+
+static int get_phytrans_type(struct cphy *phy)
+{
+ int v;
+
+ v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 0);
+ if (v < 0)
+ return phy_transtype_unknown;
+
+ return v;
+}
+
+static int ael_laser_down(struct cphy *phy, int enable)
+{
+ int v, dev_addr;
+
+ v = get_phytrans_type(phy);
+ if (v < 0)
+ return v;
+
+ if (v == phy_transtype_sfp) {
+ /* Check SFF Soft TX disable is supported */
+ v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 93);
+ if (v < 0)
+ return v;
+
+ v &= 0x40;
+ if (!v)
+ return v;
+
+ dev_addr = SFF_DEV_ADDR;
+ } else if (v == phy_transtype_xfp)
+ dev_addr = MODULE_DEV_ADDR;
+ else
+ return v;
+
+ v = ael_i2c_rd(phy, dev_addr, 110);
+ if (v < 0)
+ return v;
+
+ if (enable)
+ v |= 0x40;
+ else
+ v &= ~0x40;
+
+ v = ael_i2c_wr(phy, dev_addr, 110, v);
+
+ return v;
+}
+
static int ael1002_power_down(struct cphy *phy, int enable)
{
int err;
@@ -186,9 +234,9 @@ static int ael1002_get_module_type(struc
if (delay_ms)
msleep(delay_ms);
- v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 0);
+ v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 0);
- return v == -ETIMEDOUT ? phy_modtype_none : get_module_type(phy, v);
+ return v == -ETIMEDOUT ? phy_modtype_none : get_module_type(phy);
}
static int ael1002_reset(struct cphy *phy, int wait)
@@ -277,6 +325,7 @@ int t3_ael1002_phy_prep(struct cphy *phy
SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE,
"10GBASE-R");
ael100x_txon(phy);
+ ael_laser_down(phy, 0);
err = ael1002_get_module_type(phy, 0);
if (err >= 0)
@@ -287,31 +336,38 @@ int t3_ael1002_phy_prep(struct cphy *phy
static int ael1006_reset(struct cphy *phy, int wait)
{
- u32 gpio_out;
- t3_phy_reset(phy, MDIO_DEV_PMA_PMD, wait);
- /* Hack to reset the phy correctly */
- /* Read out the current value */
- gpio_out = t3_read_reg(phy->adapter, A_T3DBG_GPIO_EN);
- /* Reset the phy */
- gpio_out &= ~F_GPIO6_OUT_VAL;
- t3_write_reg(phy->adapter, A_T3DBG_GPIO_EN, gpio_out);
+ int err;
+
+ err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, wait);
+ if (err)
+ return err;
+
+ t3_set_reg_field(phy->adapter, A_T3DBG_GPIO_EN,
+ F_GPIO6_OUT_VAL, 0);
+
+ msleep(125);
+
+ t3_set_reg_field(phy->adapter, A_T3DBG_GPIO_EN,
+ F_GPIO6_OUT_VAL, F_GPIO6_OUT_VAL);
+
+ msleep(125);
+
+ err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, wait);
+ if (err)
+ return err;
+
msleep(125);
- /* Take the phy out of reset */
- gpio_out |= F_GPIO6_OUT_VAL;
- t3_write_reg(phy->adapter, A_T3DBG_GPIO_EN, gpio_out);
+
+ err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, 1, 1);
+ if (err)
+ return err;
+
msleep(125);
- t3_phy_reset(phy, MDIO_DEV_PMA_PMD, wait);
- /* Phy loopback work around for ael1006 */
- /* Soft reset phy by toggling loopback */
- msleep(125);
- /* Put phy into local loopback */
- t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, 0, 1);
- msleep(125);
- /* Take phy out of local loopback */
- t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, 1, 0);
+ err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, 1, 0);
- return 0;
+ return err;
+
}
static int ael1006_power_down(struct cphy *phy, int enable)
@@ -1051,53 +1107,71 @@ static int ael2005_setup_twinax_edc(stru
return err;
}
-static int ael2005_i2c_rd(struct cphy *phy, int dev_addr, int word_addr)
+static int get_module_type(struct cphy *phy)
{
- int i, err;
- unsigned int stat, data;
+ int v;
- err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL_I2C_CTRL,
- (dev_addr << 8) | (1 << 8) | word_addr);
- if (err)
- return err;
+ v = get_phytrans_type(phy);
+ if (v == phy_transtype_sfp) {
+ /* SFP: see SFF-8472 for below */
- for (i = 0; i < 5; i++) {
- msleep(1);
- err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_STAT, &stat);
- if (err)
- return err;
- if ((stat & 3) == 1) {
- err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_DATA,
- &data);
- if (err)
- return err;
- return data >> 8;
- }
- }
- CH_WARN(phy->adapter, "PHY %u I2C read of addr %u timed out\n",
- phy->addr, word_addr);
- return -ETIMEDOUT;
-}
+ v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 3);
+ if (v < 0)
+ return v;
-static int ael2005_get_module_type(struct cphy *phy, int delay_ms)
-{
- int v;
- unsigned int stat;
+ if (v == 0x1)
+ return phy_modtype_twinax;
+ if (v == 0x10)
+ return phy_modtype_sr;
+ if (v == 0x20)
+ return phy_modtype_lr;
+ if (v == 0x40)
+ return phy_modtype_lrm;
- v = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, &stat);
- if (v)
- return v;
+ v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 6);
+ if (v < 0)
+ return v;
+ if (v != 4)
+ return phy_modtype_unknown;
- if (stat & (1 << 8)) /* module absent */
- return phy_modtype_none;
+ v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 10);
+ if (v < 0)
+ return v;
- if (delay_ms)
- msleep(delay_ms);
+ if (v & 0x80) {
+ v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 0x12);
+ if (v < 0)
+ return v;
+ return v > 10 ? phy_modtype_twinax_long :
+ phy_modtype_twinax;
+ }
+ } else if (v == phy_transtype_xfp) {
+ /* XFP: See INF-8077i for details. */
+
+ v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 127);
+ if (v < 0)
+ return v;
+
+ if (v != 1) {
+ /* XXX: set page select to table 1 yourself */
+ return phy_modtype_unknown;
+ }
- return get_module_type(phy, 0);
+ v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 131);
+ if (v < 0)
+ return v;
+ if (v == 0x10)
+ return phy_modtype_lrm;
+ if (v == 0x40)
+ return phy_modtype_lr;
+ if (v == 0x80)
+ return phy_modtype_sr;
+ }
+ return phy_modtype_unknown;
}
+
static int ael2005_intr_enable(struct cphy *phy)
{
int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x200);
@@ -1116,6 +1190,24 @@ static int ael2005_intr_clear(struct cph
return err ? err : t3_phy_lasi_intr_clear(phy);
}
+static int ael2005_get_module_type(struct cphy *phy, int delay_ms)
+{
+ int v;
+ unsigned int stat;
+
+ v = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, &stat);
+ if (v)
+ return v;
+
+ if (stat & (1 << 8)) /* module absent */
+ return phy_modtype_none;
+
+ if (delay_ms)
+ msleep(delay_ms);
+
+ return get_module_type(phy);
+}
+
static int ael2005_reset(struct cphy *phy, int wait)
{
static struct reg_val regs0[] = {
@@ -1211,7 +1303,13 @@ static int ael2005_intr_handler(struct c
}
ret = t3_phy_lasi_intr_handler(phy);
- return ret < 0 ? ret : ret + cause;
+ if (ret < 0)
+ return ret;
+
+ ret |= cause;
+ if (!ret)
+ ret |= cphy_cause_link_change;
+ return ret;
}
#ifdef C99_NOT_SUPPORTED
@@ -1249,6 +1347,7 @@ int t3_ael2005_phy_prep(struct cphy *phy
SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE |
SUPPORTED_IRQ, "10GBASE-R");
msleep(125);
+ ael_laser_down(phy, 0);
err = ael2005_get_module_type(phy, 0);
if (err >= 0)
@@ -1339,7 +1438,7 @@ static int xaui_direct_get_link_status(s
{
if (link_ok) {
unsigned int status;
-
+
status = t3_read_reg(phy->adapter,
XGM_REG(A_XGM_SERDES_STAT0, phy->addr)) |
t3_read_reg(phy->adapter,
Modified: stable/7/sys/dev/cxgb/common/cxgb_common.h
==============================================================================
--- stable/7/sys/dev/cxgb/common/cxgb_common.h Fri Jun 5 22:21:10 2009 (r193538)
+++ stable/7/sys/dev/cxgb/common/cxgb_common.h Fri Jun 5 22:23:33 2009 (r193539)
@@ -1,6 +1,6 @@
/**************************************************************************
-Copyright (c) 2007-2008, Chelsio Inc.
+Copyright (c) 2007-2009, Chelsio Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -96,12 +96,22 @@ enum {
(((x) >> S_TP_VERSION_MICRO) & M_TP_VERSION_MICRO)
enum {
- FW_VERSION_MAJOR = 5,
- FW_VERSION_MINOR = 0,
+ FW_VERSION_MAJOR = 7,
+ FW_VERSION_MINOR = 1,
FW_VERSION_MICRO = 0
};
enum {
+ LA_CTRL = 0x80,
+ LA_DATA = 0x84,
+ LA_ENTRIES = 512
+};
+
+enum {
+ IOQ_ENTRIES = 7
+};
+
+enum {
SGE_QSETS = 8, /* # of SGE Tx/Rx/RspQ sets */
SGE_RXQ_PER_SET = 2, /* # of Rx queues per set */
SGE_TXQ_PER_SET = 3 /* # of Tx queues per set */
@@ -147,8 +157,6 @@ struct adapter_info {
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:1;
- unsigned char mdiinv:1;
unsigned int gpio_out; /* GPIO output settings */
unsigned char gpio_intr[MAX_PHYINTRS]; /* GPIO PHY IRQ pins */
unsigned long caps; /* adapter capabilities */
@@ -235,6 +243,8 @@ struct mac_stats {
unsigned long num_toggled; /* # times toggled TxEn due to stuck TX */
unsigned long num_resets; /* # times reset due to stuck TX */
+
+ unsigned long link_faults; /* # detected link faults */
};
struct tp_mib_stats {
@@ -349,6 +359,14 @@ struct vpd_params {
unsigned short xauicfg[2];
};
+struct generic_vpd {
+ u32 offset;
+ u32 len;
+ u8 *data;
+};
+
+enum { MAX_VPD_BYTES = 32000 };
+
struct pci_params {
unsigned int vpd_cap_addr;
unsigned int pcie_cap_addr;
@@ -682,6 +700,8 @@ int t3_phy_lasi_intr_handler(struct cphy
void t3_intr_enable(adapter_t *adapter);
void t3_intr_disable(adapter_t *adapter);
void t3_intr_clear(adapter_t *adapter);
+void t3_xgm_intr_enable(adapter_t *adapter, int idx);
+void t3_xgm_intr_disable(adapter_t *adapter, int idx);
void t3_port_intr_enable(adapter_t *adapter, int idx);
void t3_port_intr_disable(adapter_t *adapter, int idx);
void t3_port_intr_clear(adapter_t *adapter, int idx);
@@ -689,29 +709,34 @@ int t3_slow_intr_handler(adapter_t *adap
int t3_phy_intr_handler(adapter_t *adapter);
void t3_link_changed(adapter_t *adapter, int port_id);
+void t3_link_fault(adapter_t *adapter, int port_id);
int t3_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc);
const struct adapter_info *t3_get_adapter_info(unsigned int board_id);
int t3_seeprom_read(adapter_t *adapter, u32 addr, u32 *data);
int t3_seeprom_write(adapter_t *adapter, u32 addr, u32 data);
int t3_seeprom_wp(adapter_t *adapter, int enable);
+int t3_get_vpd_len(adapter_t *adapter, struct generic_vpd *vpd);
+int t3_read_vpd(adapter_t *adapter, struct generic_vpd *vpd);
int t3_read_flash(adapter_t *adapter, unsigned int addr, unsigned int nwords,
u32 *data, int byte_oriented);
int t3_get_tp_version(adapter_t *adapter, u32 *vers);
-int t3_check_tpsram_version(adapter_t *adapter, int *must_load);
+int t3_check_tpsram_version(adapter_t *adapter);
int t3_check_tpsram(adapter_t *adapter, const 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 *must_load);
+int t3_check_fw_version(adapter_t *adapter);
int t3_load_boot(adapter_t *adapter, u8 *fw_data, unsigned int size);
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);
int t3_reinit_adapter(adapter_t *adap);
void t3_led_ready(adapter_t *adapter);
void t3_fatal_err(adapter_t *adapter);
void t3_set_vlan_accel(adapter_t *adapter, unsigned int ports, int on);
void t3_enable_filters(adapter_t *adap);
+void t3_disable_filters(adapter_t *adap);
void t3_tp_set_offload_mode(adapter_t *adap, int enable);
void t3_config_rss(adapter_t *adapter, unsigned int rss_config, const u8 *cpus,
const u16 *rspq);
@@ -728,6 +753,8 @@ int t3_mc7_bd_read(struct mc7 *mc7, unsi
int t3_mac_reset(struct cmac *mac);
void t3b_pcs_reset(struct cmac *mac);
+void t3_mac_disable_exact_filters(struct cmac *mac);
+void t3_mac_enable_exact_filters(struct cmac *mac);
int t3_mac_enable(struct cmac *mac, int which);
int t3_mac_disable(struct cmac *mac, int which);
int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu);
@@ -758,6 +785,8 @@ void t3_get_cong_cntl_tab(adapter_t *ada
unsigned short incr[NMTUS][NCCTRL_WIN]);
void t3_config_trace_filter(adapter_t *adapter, const struct trace_params *tp,
int filter_index, int invert, int enable);
+void t3_query_trace_filter(adapter_t *adapter, struct trace_params *tp,
+ int filter_index, int *inverted, int *enabled);
int t3_config_sched(adapter_t *adap, unsigned int kbps, int sched);
int t3_set_sched_ipg(adapter_t *adap, int sched, unsigned int ipg);
void t3_get_tx_sched(adapter_t *adap, unsigned int sched, unsigned int *kbps,
@@ -767,6 +796,10 @@ void t3_set_pace_tbl(adapter_t *adap, un
unsigned int start, unsigned int n);
#endif
+int t3_get_up_la(adapter_t *adapter, u32 *stopped, u32 *index,
+ u32 *size, void *data);
+int t3_get_up_ioqs(adapter_t *adapter, u32 *size, void *data);
+
void t3_sge_prep(adapter_t *adap, struct sge_params *p);
void t3_sge_init(adapter_t *adap, struct sge_params *p);
int t3_sge_init_ecntxt(adapter_t *adapter, unsigned int id, int gts_enable,
@@ -803,6 +836,11 @@ int t3_vsc7323_enable(adapter_t *adap, i
int t3_vsc7323_disable(adapter_t *adap, int port, int which);
const struct mac_stats *t3_vsc7323_update_stats(struct cmac *mac);
+int t3_mi1_read(adapter_t *adapter, int phy_addr, int mmd_addr, int reg_addr,
+ unsigned int *valp);
+int t3_mi1_write(adapter_t *adapter, int phy_addr, int mmd_addr, int reg_addr,
+ unsigned int val);
+
int t3_mv88e1xxx_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr,
const struct mdio_ops *mdio_ops);
int t3_vsc8211_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr,
Modified: stable/7/sys/dev/cxgb/common/cxgb_t3_cpl.h
==============================================================================
--- stable/7/sys/dev/cxgb/common/cxgb_t3_cpl.h Fri Jun 5 22:21:10 2009 (r193538)
+++ stable/7/sys/dev/cxgb/common/cxgb_t3_cpl.h Fri Jun 5 22:23:33 2009 (r193539)
@@ -1,6 +1,6 @@
/**************************************************************************
-Copyright (c) 2007, Chelsio Inc.
+Copyright (c) 2007-2009 Chelsio Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -273,6 +273,14 @@ struct work_request_hdr {
#define V_WR_FLUSH(x) ((x) << S_WR_FLUSH)
#define F_WR_FLUSH V_WR_FLUSH(1U)
+#define S_WR_CHN 18
+#define V_WR_CHN(x) ((x) << S_WR_CHN)
+#define F_WR_CHN V_WR_CHN(1U)
+
+#define S_WR_CHN_VLD 19
+#define V_WR_CHN_VLD(x) ((x) << S_WR_CHN_VLD)
+#define F_WR_CHN_VLD V_WR_CHN_VLD(1U)
+
#define S_WR_DATATYPE 20
#define V_WR_DATATYPE(x) ((x) << S_WR_DATATYPE)
#define F_WR_DATATYPE V_WR_DATATYPE(1U)
Modified: stable/7/sys/dev/cxgb/common/cxgb_t3_hw.c
==============================================================================
--- stable/7/sys/dev/cxgb/common/cxgb_t3_hw.c Fri Jun 5 22:21:10 2009 (r193538)
+++ stable/7/sys/dev/cxgb/common/cxgb_t3_hw.c Fri Jun 5 22:23:33 2009 (r193539)
@@ -1,6 +1,6 @@
/**************************************************************************
-Copyright (c) 2007, Chelsio Inc.
+Copyright (c) 2007-2009, Chelsio Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -197,21 +197,18 @@ int t3_mc7_bd_read(struct mc7 *mc7, unsi
static void mi1_init(adapter_t *adap, const struct adapter_info *ai)
{
u32 clkdiv = adap->params.vpd.cclk / (2 * adap->params.vpd.mdc) - 1;
- u32 val = F_PREEN | V_MDIINV(ai->mdiinv) | V_MDIEN(ai->mdien) |
- V_CLKDIV(clkdiv);
+ u32 val = F_PREEN | V_CLKDIV(clkdiv);
- if (!(ai->caps & SUPPORTED_10000baseT_Full))
- val |= V_ST(1);
t3_write_reg(adap, A_MI1_CFG, val);
}
#define MDIO_ATTEMPTS 20
/*
- * MI1 read/write operations for direct-addressed PHYs.
+ * MI1 read/write operations for clause 22 PHYs.
*/
-static int mi1_read(adapter_t *adapter, int phy_addr, int mmd_addr,
- int reg_addr, unsigned int *valp)
+int t3_mi1_read(adapter_t *adapter, int phy_addr, int mmd_addr,
+ int reg_addr, unsigned int *valp)
{
int ret;
u32 addr = V_REGADDR(reg_addr) | V_PHYADDR(phy_addr);
@@ -220,6 +217,7 @@ static int mi1_read(adapter_t *adapter,
return -EINVAL;
MDIO_LOCK(adapter);
+ t3_set_reg_field(adapter, A_MI1_CFG, V_ST(M_ST), V_ST(1));
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, 10);
@@ -229,8 +227,8 @@ static int mi1_read(adapter_t *adapter,
return ret;
}
-static int mi1_write(adapter_t *adapter, int phy_addr, int mmd_addr,
- int reg_addr, unsigned int val)
+int t3_mi1_write(adapter_t *adapter, int phy_addr, int mmd_addr,
+ int reg_addr, unsigned int val)
{
int ret;
u32 addr = V_REGADDR(reg_addr) | V_PHYADDR(phy_addr);
@@ -239,6 +237,7 @@ static int mi1_write(adapter_t *adapter,
return -EINVAL;
MDIO_LOCK(adapter);
+ t3_set_reg_field(adapter, A_MI1_CFG, V_ST(M_ST), V_ST(1));
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));
@@ -248,12 +247,12 @@ static int mi1_write(adapter_t *adapter,
}
static struct mdio_ops mi1_mdio_ops = {
- mi1_read,
- mi1_write
+ t3_mi1_read,
+ t3_mi1_write
};
/*
- * MI1 read/write operations for indirect-addressed PHYs.
+ * MI1 read/write operations for clause 45 PHYs.
*/
static int mi1_ext_read(adapter_t *adapter, int phy_addr, int mmd_addr,
int reg_addr, unsigned int *valp)
@@ -262,6 +261,7 @@ static int mi1_ext_read(adapter_t *adapt
u32 addr = V_REGADDR(mmd_addr) | V_PHYADDR(phy_addr);
MDIO_LOCK(adapter);
+ t3_set_reg_field(adapter, A_MI1_CFG, V_ST(M_ST), 0);
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));
@@ -284,6 +284,7 @@ static int mi1_ext_write(adapter_t *adap
u32 addr = V_REGADDR(mmd_addr) | V_PHYADDR(phy_addr);
MDIO_LOCK(adapter);
+ t3_set_reg_field(adapter, A_MI1_CFG, V_ST(M_ST), 0);
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));
@@ -488,32 +489,32 @@ int t3_phy_lasi_intr_handler(struct cphy
}
static struct adapter_info t3_adap_info[] = {
- { 1, 1, 0, 0, 0,
+ { 1, 1, 0,
F_GPIO2_OEN | F_GPIO4_OEN |
F_GPIO2_OUT_VAL | F_GPIO4_OUT_VAL, { S_GPIO3, S_GPIO5 }, 0,
&mi1_mdio_ops, "Chelsio PE9000" },
- { 1, 1, 0, 0, 0,
+ { 1, 1, 0,
F_GPIO2_OEN | F_GPIO4_OEN |
F_GPIO2_OUT_VAL | F_GPIO4_OUT_VAL, { S_GPIO3, S_GPIO5 }, 0,
&mi1_mdio_ops, "Chelsio T302" },
- { 1, 0, 0, 0, 0,
+ { 1, 0, 0,
F_GPIO1_OEN | F_GPIO6_OEN | F_GPIO7_OEN | F_GPIO10_OEN |
F_GPIO11_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" },
- { 1, 1, 0, 0, 0,
+ { 1, 1, 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,
{ S_GPIO9, S_GPIO3 }, SUPPORTED_10000baseT_Full | SUPPORTED_AUI,
&mi1_mdio_ext_ops, "Chelsio T320" },
- { 4, 0, 0, 0, 0,
+ { 4, 0, 0,
F_GPIO5_OEN | F_GPIO6_OEN | F_GPIO7_OEN | F_GPIO5_OUT_VAL |
F_GPIO6_OUT_VAL | F_GPIO7_OUT_VAL,
{ S_GPIO1, S_GPIO2, S_GPIO3, S_GPIO4 }, SUPPORTED_AUI,
&mi1_mdio_ops, "Chelsio T304" },
{ 0 },
- { 1, 0, 0, 0, 0,
+ { 1, 0, 0,
F_GPIO1_OEN | F_GPIO2_OEN | F_GPIO4_OEN | F_GPIO6_OEN | F_GPIO7_OEN |
F_GPIO10_OEN | F_GPIO1_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL,
{ S_GPIO9 }, SUPPORTED_10000baseT_Full | SUPPORTED_AUI,
@@ -750,16 +751,17 @@ enum {
SF_ERASE_SECTOR = 0xd8, /* erase sector */
FW_FLASH_BOOT_ADDR = 0x70000, /* start address of FW in flash */
- OLD_FW_VERS_ADDR = 0x77ffc, /* flash address holding FW version */
FW_VERS_ADDR = 0x7fffc, /* flash address holding FW version */
+ FW_VERS_ADDR_PRE8 = 0x77ffc,/* flash address holding FW version pre8 */
FW_MIN_SIZE = 8, /* at least version and csum */
FW_MAX_SIZE = FW_VERS_ADDR - FW_FLASH_BOOT_ADDR,
+ FW_MAX_SIZE_PRE8 = FW_VERS_ADDR_PRE8 - FW_FLASH_BOOT_ADDR,
BOOT_FLASH_BOOT_ADDR = 0x0,/* start address of boot image in flash */
BOOT_SIGNATURE = 0xaa55, /* signature of BIOS boot ROM */
BOOT_SIZE_INC = 512, /* image size measured in 512B chunks */
BOOT_MIN_SIZE = sizeof(boot_header_t), /* at least basic header */
- BOOT_MAX_SIZE = 0xff*BOOT_SIZE_INC /* 1 byte * length increment */
+ BOOT_MAX_SIZE = 1024*BOOT_SIZE_INC /* 1 byte * length increment */
};
/**
@@ -888,7 +890,7 @@ int t3_read_flash(adapter_t *adapter, un
* at the given address.
* If @byte_oriented is set the write data is stored as a 32-bit
* big-endian array, otherwise in the processor's native endianess.
- *
+ *
*/
static int t3_write_flash(adapter_t *adapter, unsigned int addr,
unsigned int n, const u8 *data,
@@ -949,7 +951,7 @@ int t3_get_tp_version(adapter_t *adapter
1, 1, 5, 1);
if (ret)
return ret;
-
+
*vers = t3_read_reg(adapter, A_TP_EMBED_OP_FIELD1);
return 0;
@@ -960,7 +962,7 @@ int t3_get_tp_version(adapter_t *adapter
* @adapter: the adapter
*
*/
-int t3_check_tpsram_version(adapter_t *adapter, int *must_load)
+int t3_check_tpsram_version(adapter_t *adapter)
{
int ret;
u32 vers;
@@ -969,26 +971,19 @@ int t3_check_tpsram_version(adapter_t *a
if (adapter->params.rev == T3_REV_A)
return 0;
- *must_load = 1;
ret = t3_get_tp_version(adapter, &vers);
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)
+ if (major == TP_VERSION_MAJOR && minor == TP_VERSION_MINOR)
return 0;
-
- if (major != TP_VERSION_MAJOR)
- CH_ERR(adapter, "found wrong TP version (%u.%u), "
- "driver needs version %d.%d\n", major, minor,
- TP_VERSION_MAJOR, TP_VERSION_MINOR);
else {
- *must_load = 0;
CH_ERR(adapter, "found wrong TP version (%u.%u), "
"driver compiled for version %d.%d\n", major, minor,
TP_VERSION_MAJOR, TP_VERSION_MINOR);
@@ -997,7 +992,7 @@ int t3_check_tpsram_version(adapter_t *a
}
/**
- * t3_check_tpsram - check if provided protocol SRAM
+ * t3_check_tpsram - check if provided protocol SRAM
* is compatible with this driver
* @adapter: the adapter
* @tp_sram: the firmware image to write
@@ -1034,16 +1029,17 @@ enum fw_version_type {
* @adapter: the adapter
* @vers: where to place the version
*
- * Reads the FW version from flash.
+ * Reads the FW version from flash. Note that we had to move the version
+ * due to FW size. If we don't find a valid FW version in the new location
+ * we fall back and read the old location.
*/
int t3_get_fw_version(adapter_t *adapter, u32 *vers)
{
int ret = t3_read_flash(adapter, FW_VERS_ADDR, 1, vers, 0);
-
if (!ret && *vers != 0xffffffff)
return 0;
else
- return t3_read_flash(adapter, OLD_FW_VERS_ADDR, 1, vers, 0);
+ return t3_read_flash(adapter, FW_VERS_ADDR_PRE8, 1, vers, 0);
}
/**
@@ -1053,13 +1049,12 @@ int t3_get_fw_version(adapter_t *adapter
* Checks if an adapter's FW is compatible with the driver. Returns 0
* if the versions are compatible, a negative error otherwise.
*/
-int t3_check_fw_version(adapter_t *adapter, int *must_load)
+int t3_check_fw_version(adapter_t *adapter)
{
int ret;
u32 vers;
unsigned int type, major, minor;
- *must_load = 1;
ret = t3_get_fw_version(adapter, &vers);
if (ret)
return ret;
@@ -1072,16 +1067,11 @@ int t3_check_fw_version(adapter_t *adapt
minor == FW_VERSION_MINOR)
return 0;
- if (major != FW_VERSION_MAJOR)
- CH_ERR(adapter, "found wrong FW version(%u.%u), "
- "driver needs version %u.%u\n", major, minor,
- FW_VERSION_MAJOR, FW_VERSION_MINOR);
- else if ((int)minor < FW_VERSION_MINOR) {
- *must_load = 0;
+ else if (major != FW_VERSION_MAJOR || minor < FW_VERSION_MINOR)
CH_WARN(adapter, "found old FW minor version(%u.%u), "
"driver compiled for version %u.%u\n", major, minor,
FW_VERSION_MAJOR, FW_VERSION_MINOR);
- } else {
+ else {
CH_WARN(adapter, "found newer FW version(%u.%u), "
"driver compiled for version %u.%u\n", major, minor,
FW_VERSION_MAJOR, FW_VERSION_MINOR);
@@ -1126,7 +1116,7 @@ static int t3_flash_erase_sectors(adapte
*/
int t3_load_fw(adapter_t *adapter, const u8 *fw_data, unsigned int size)
{
- u32 csum;
+ u32 version, csum, fw_version_addr;
unsigned int i;
const u32 *p = (const u32 *)fw_data;
int ret, addr, fw_sector = FW_FLASH_BOOT_ADDR >> 16;
@@ -1136,6 +1126,16 @@ int t3_load_fw(adapter_t *adapter, const
if (size - 8 > FW_MAX_SIZE)
return -EFBIG;
+ version = ntohl(*(const u32 *)(fw_data + size - 8));
+ if (G_FW_VERSION_MAJOR(version) < 8) {
+
+ fw_version_addr = FW_VERS_ADDR_PRE8;
+
+ if (size - 8 > FW_MAX_SIZE_PRE8)
+ return -EFBIG;
+ } else
+ fw_version_addr = FW_VERS_ADDR;
+
for (csum = 0, i = 0; i < size / sizeof(csum); i++)
csum += ntohl(p[i]);
if (csum != 0xffffffff) {
@@ -1161,7 +1161,7 @@ int t3_load_fw(adapter_t *adapter, const
size -= chunk_size;
}
- ret = t3_write_flash(adapter, FW_VERS_ADDR, 4, fw_data, 1);
+ ret = t3_write_flash(adapter, fw_version_addr, 4, fw_data, 1);
out:
if (ret)
CH_ERR(adapter, "firmware download failed, error %d\n", ret);
@@ -1255,6 +1255,39 @@ int t3_cim_ctl_blk_read(adapter_t *adap,
return ret;
}
+static void t3_gate_rx_traffic(struct cmac *mac, u32 *rx_cfg,
+ u32 *rx_hash_high, u32 *rx_hash_low)
+{
+ /* stop Rx unicast traffic */
+ t3_mac_disable_exact_filters(mac);
+
+ /* stop broadcast, multicast, promiscuous mode traffic */
+ *rx_cfg = t3_read_reg(mac->adapter, A_XGM_RX_CFG);
+ t3_set_reg_field(mac->adapter, A_XGM_RX_CFG,
+ F_ENHASHMCAST | F_DISBCAST | F_COPYALLFRAMES,
+ F_DISBCAST);
+
+ *rx_hash_high = t3_read_reg(mac->adapter, A_XGM_RX_HASH_HIGH);
+ t3_write_reg(mac->adapter, A_XGM_RX_HASH_HIGH, 0);
+
+ *rx_hash_low = t3_read_reg(mac->adapter, A_XGM_RX_HASH_LOW);
+ t3_write_reg(mac->adapter, A_XGM_RX_HASH_LOW, 0);
+
+ /* Leave time to drain max RX fifo */
+ msleep(1);
+}
+
+static void t3_open_rx_traffic(struct cmac *mac, u32 rx_cfg,
+ u32 rx_hash_high, u32 rx_hash_low)
+{
+ t3_mac_enable_exact_filters(mac);
+ t3_set_reg_field(mac->adapter, A_XGM_RX_CFG,
+ F_ENHASHMCAST | F_DISBCAST | F_COPYALLFRAMES,
+ rx_cfg);
+ t3_write_reg(mac->adapter, A_XGM_RX_HASH_HIGH, rx_hash_high);
+ t3_write_reg(mac->adapter, A_XGM_RX_HASH_LOW, rx_hash_low);
+}
+
/**
* t3_link_changed - handle interface link changes
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-stable-7
mailing list