Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 10 Mar 2009 19:22:45 +0000 (UTC)
From:      "George V. Neville-Neil" <gnn@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r189643 - in head: sys/dev/cxgb sys/dev/cxgb/common usr.sbin/cxgbtool
Message-ID:  <200903101922.n2AJMja9071422@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gnn
Date: Tue Mar 10 19:22:45 2009
New Revision: 189643
URL: http://svn.freebsd.org/changeset/base/189643

Log:
  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)
  
  Submitted by:	 Navdeep Parhar at Chelsio
  Reviewed by:	gnn
  MFC after:	2 weeks

Added:
  head/sys/dev/cxgb/t3c_protocol_sram.h   (contents, props changed)
  head/sys/dev/cxgb/t3c_tp_eeprom.h   (contents, props changed)
Modified:
  head/sys/dev/cxgb/bin2h.pl
  head/sys/dev/cxgb/common/cxgb_ael1002.c
  head/sys/dev/cxgb/common/cxgb_common.h
  head/sys/dev/cxgb/common/cxgb_t3_cpl.h
  head/sys/dev/cxgb/common/cxgb_t3_hw.c
  head/sys/dev/cxgb/common/cxgb_xgmac.c
  head/sys/dev/cxgb/cxgb_adapter.h
  head/sys/dev/cxgb/cxgb_ioctl.h
  head/sys/dev/cxgb/cxgb_main.c
  head/sys/dev/cxgb/cxgb_sge.c
  head/sys/dev/cxgb/cxgb_t3fw.c
  head/sys/dev/cxgb/cxgb_t3fw.h
  head/usr.sbin/cxgbtool/cxgbtool.c
  head/usr.sbin/cxgbtool/version.h

Modified: head/sys/dev/cxgb/bin2h.pl
==============================================================================
--- head/sys/dev/cxgb/bin2h.pl	Tue Mar 10 19:18:11 2009	(r189642)
+++ head/sys/dev/cxgb/bin2h.pl	Tue Mar 10 19:22:45 2009	(r189643)
@@ -22,7 +22,7 @@ unless ($success) {
 my $license = <<END;
 /**************************************************************************
 
-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

Modified: head/sys/dev/cxgb/common/cxgb_ael1002.c
==============================================================================
--- head/sys/dev/cxgb/common/cxgb_ael1002.c	Tue Mar 10 19:18:11 2009	(r189642)
+++ head/sys/dev/cxgb/common/cxgb_ael1002.c	Tue Mar 10 19:22:45 2009	(r189643)
@@ -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
@@ -60,7 +60,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
 
@@ -71,73 +81,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)
 {
@@ -164,6 +108,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;
@@ -182,9 +230,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)
@@ -273,6 +321,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)
@@ -283,31 +332,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)
@@ -1047,53 +1103,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);
@@ -1112,6 +1186,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[] = {
@@ -1207,7 +1299,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
@@ -1245,6 +1343,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)
@@ -1335,7 +1434,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: head/sys/dev/cxgb/common/cxgb_common.h
==============================================================================
--- head/sys/dev/cxgb/common/cxgb_common.h	Tue Mar 10 19:18:11 2009	(r189642)
+++ head/sys/dev/cxgb/common/cxgb_common.h	Tue Mar 10 19:22:45 2009	(r189643)
@@ -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
@@ -92,12 +92,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 */
@@ -143,8 +153,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 */
@@ -231,6 +239,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 {
@@ -345,6 +355,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;
@@ -674,6 +692,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);
@@ -681,29 +701,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);
@@ -720,6 +745,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);
@@ -750,6 +777,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,
@@ -759,6 +788,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,
@@ -795,6 +828,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: head/sys/dev/cxgb/common/cxgb_t3_cpl.h
==============================================================================
--- head/sys/dev/cxgb/common/cxgb_t3_cpl.h	Tue Mar 10 19:18:11 2009	(r189642)
+++ head/sys/dev/cxgb/common/cxgb_t3_cpl.h	Tue Mar 10 19:22:45 2009	(r189643)
@@ -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: head/sys/dev/cxgb/common/cxgb_t3_hw.c
==============================================================================
--- head/sys/dev/cxgb/common/cxgb_t3_hw.c	Tue Mar 10 19:18:11 2009	(r189642)
+++ head/sys/dev/cxgb/common/cxgb_t3_hw.c	Tue Mar 10 19:22:45 2009	(r189643)
@@ -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
@@ -194,21 +194,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);
@@ -217,6 +214,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);
@@ -226,8 +224,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);
@@ -236,6 +234,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));
@@ -245,12 +244,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)
@@ -259,6 +258,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));
@@ -281,6 +281,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));
@@ -485,32 +486,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,
@@ -747,16 +748,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  */
 };
 
 /**
@@ -885,7 +887,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,
@@ -946,7 +948,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;
@@ -957,7 +959,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;
@@ -966,26 +968,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);
@@ -994,7 +989,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
@@ -1031,16 +1026,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);
 }
 
 /**
@@ -1050,13 +1046,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;
@@ -1069,16 +1064,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);
@@ -1123,7 +1113,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;
@@ -1133,6 +1123,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) {
@@ -1158,7 +1158,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);
@@ -1252,6 +1252,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
  *	@adapter: the adapter

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200903101922.n2AJMja9071422>