PERFORCE change 162496 for review

Hans Petter Selasky hselasky at FreeBSD.org
Fri May 22 09:21:09 UTC 2009


http://perforce.freebsd.org/chv.cgi?CH=162496

Change 162496 by hselasky at hselasky_laptop001 on 2009/05/22 09:20:52

	
	IFC @ 162495

Affected files ...

.. //depot/projects/usb/src/sys/conf/files.powerpc#23 integrate
.. //depot/projects/usb/src/sys/dev/ata/ata-usb.c#42 integrate
.. //depot/projects/usb/src/sys/dev/cxgb/common/cxgb_ael1002.c#10 integrate
.. //depot/projects/usb/src/sys/dev/cxgb/common/cxgb_common.h#10 integrate
.. //depot/projects/usb/src/sys/dev/cxgb/common/cxgb_t3_hw.c#12 integrate
.. //depot/projects/usb/src/sys/dev/cxgb/cxgb_adapter.h#10 integrate
.. //depot/projects/usb/src/sys/dev/cxgb/cxgb_main.c#16 integrate
.. //depot/projects/usb/src/sys/dev/cxgb/cxgb_sge.c#13 integrate
.. //depot/projects/usb/src/sys/dev/if_ndis/if_ndis_usb.c#17 integrate
.. //depot/projects/usb/src/sys/dev/iwi/if_iwi.c#14 integrate
.. //depot/projects/usb/src/sys/dev/iwi/if_iwivar.h#8 integrate
.. //depot/projects/usb/src/sys/dev/mpt/mpt_raid.c#9 integrate
.. //depot/projects/usb/src/sys/dev/nge/if_nge.c#7 integrate
.. //depot/projects/usb/src/sys/dev/nge/if_ngereg.h#4 integrate
.. //depot/projects/usb/src/sys/dev/sound/usb/uaudio.c#42 integrate
.. //depot/projects/usb/src/sys/dev/usb/controller/at91dci.c#19 integrate
.. //depot/projects/usb/src/sys/dev/usb/controller/at91dci.h#7 integrate
.. //depot/projects/usb/src/sys/dev/usb/controller/atmegadci.c#29 integrate
.. //depot/projects/usb/src/sys/dev/usb/controller/atmegadci.h#13 integrate
.. //depot/projects/usb/src/sys/dev/usb/controller/ehci.c#25 integrate
.. //depot/projects/usb/src/sys/dev/usb/controller/musb_otg.c#17 integrate
.. //depot/projects/usb/src/sys/dev/usb/controller/musb_otg.h#5 integrate
.. //depot/projects/usb/src/sys/dev/usb/controller/ohci.c#20 integrate
.. //depot/projects/usb/src/sys/dev/usb/controller/uhci.c#18 integrate
.. //depot/projects/usb/src/sys/dev/usb/controller/usb_controller.c#17 integrate
.. //depot/projects/usb/src/sys/dev/usb/controller/uss820dci.c#19 integrate
.. //depot/projects/usb/src/sys/dev/usb/controller/uss820dci.h#9 integrate
.. //depot/projects/usb/src/sys/dev/usb/input/uhid.c#10 integrate
.. //depot/projects/usb/src/sys/dev/usb/input/ukbd.c#12 integrate
.. //depot/projects/usb/src/sys/dev/usb/input/ums.c#13 integrate
.. //depot/projects/usb/src/sys/dev/usb/misc/udbp.c#9 integrate
.. //depot/projects/usb/src/sys/dev/usb/net/if_aue.c#9 integrate
.. //depot/projects/usb/src/sys/dev/usb/net/if_axe.c#10 integrate
.. //depot/projects/usb/src/sys/dev/usb/net/if_cdce.c#12 integrate
.. //depot/projects/usb/src/sys/dev/usb/net/if_cue.c#9 integrate
.. //depot/projects/usb/src/sys/dev/usb/net/if_kue.c#9 integrate
.. //depot/projects/usb/src/sys/dev/usb/net/if_rue.c#9 integrate
.. //depot/projects/usb/src/sys/dev/usb/net/if_udav.c#9 integrate
.. //depot/projects/usb/src/sys/dev/usb/serial/u3g.c#13 integrate
.. //depot/projects/usb/src/sys/dev/usb/serial/ubsa.c#7 integrate
.. //depot/projects/usb/src/sys/dev/usb/serial/ubser.c#10 integrate
.. //depot/projects/usb/src/sys/dev/usb/serial/uchcom.c#7 integrate
.. //depot/projects/usb/src/sys/dev/usb/serial/uftdi.c#8 integrate
.. //depot/projects/usb/src/sys/dev/usb/serial/uipaq.c#8 integrate
.. //depot/projects/usb/src/sys/dev/usb/serial/ulpt.c#11 integrate
.. //depot/projects/usb/src/sys/dev/usb/serial/umct.c#10 integrate
.. //depot/projects/usb/src/sys/dev/usb/serial/umodem.c#12 integrate
.. //depot/projects/usb/src/sys/dev/usb/serial/umoscom.c#7 integrate
.. //depot/projects/usb/src/sys/dev/usb/serial/uplcom.c#9 integrate
.. //depot/projects/usb/src/sys/dev/usb/serial/usb_serial.c#5 integrate
.. //depot/projects/usb/src/sys/dev/usb/serial/uslcom.c#7 integrate
.. //depot/projects/usb/src/sys/dev/usb/serial/uvisor.c#9 integrate
.. //depot/projects/usb/src/sys/dev/usb/serial/uvscom.c#7 integrate
.. //depot/projects/usb/src/sys/dev/usb/storage/umass.c#19 integrate
.. //depot/projects/usb/src/sys/dev/usb/storage/urio.c#10 integrate
.. //depot/projects/usb/src/sys/dev/usb/storage/ustorage_fs.c#17 integrate
.. //depot/projects/usb/src/sys/dev/usb/usb_core.h#21 integrate
.. //depot/projects/usb/src/sys/dev/usb/usb_debug.c#6 integrate
.. //depot/projects/usb/src/sys/dev/usb/usb_debug.h#5 integrate
.. //depot/projects/usb/src/sys/dev/usb/usb_dev.c#22 integrate
.. //depot/projects/usb/src/sys/dev/usb/usb_device.c#33 integrate
.. //depot/projects/usb/src/sys/dev/usb/usb_generic.c#17 integrate
.. //depot/projects/usb/src/sys/dev/usb/usb_hid.c#34 integrate
.. //depot/projects/usb/src/sys/dev/usb/usb_hub.c#21 integrate
.. //depot/projects/usb/src/sys/dev/usb/usb_process.c#5 integrate
.. //depot/projects/usb/src/sys/dev/usb/usb_request.c#16 integrate
.. //depot/projects/usb/src/sys/dev/usb/usb_transfer.c#150 integrate
.. //depot/projects/usb/src/sys/dev/usb/usbdevs#60 integrate
.. //depot/projects/usb/src/sys/dev/usb/wlan/if_rum.c#13 integrate
.. //depot/projects/usb/src/sys/dev/usb/wlan/if_uath.c#10 integrate
.. //depot/projects/usb/src/sys/dev/usb/wlan/if_upgt.c#7 integrate
.. //depot/projects/usb/src/sys/dev/usb/wlan/if_ural.c#13 integrate
.. //depot/projects/usb/src/sys/dev/usb/wlan/if_zyd.c#13 integrate
.. //depot/projects/usb/src/sys/dev/wi/if_wi.c#12 integrate
.. //depot/projects/usb/src/sys/fs/nfsserver/nfs_nfsdport.c#3 integrate
.. //depot/projects/usb/src/sys/fs/nfsserver/nfs_nfsdstate.c#4 integrate
.. //depot/projects/usb/src/sys/kern/kern_conf.c#16 integrate
.. //depot/projects/usb/src/sys/kern/tty_inq.c#4 integrate
.. //depot/projects/usb/src/sys/kern/vfs_bio.c#20 integrate
.. //depot/projects/usb/src/sys/modules/wlan/Makefile#8 integrate
.. //depot/projects/usb/src/sys/netinet/ip_output.c#18 integrate
.. //depot/projects/usb/src/sys/netinet6/mld6.c#15 integrate
.. //depot/projects/usb/src/sys/powerpc/booke/clock.c#4 integrate
.. //depot/projects/usb/src/sys/powerpc/booke/locore.S#7 integrate
.. //depot/projects/usb/src/sys/powerpc/booke/machdep.c#11 integrate
.. //depot/projects/usb/src/sys/powerpc/booke/mp_cpudep.c#1 branch
.. //depot/projects/usb/src/sys/powerpc/booke/platform_bare.c#2 integrate
.. //depot/projects/usb/src/sys/powerpc/booke/pmap.c#11 integrate
.. //depot/projects/usb/src/sys/powerpc/booke/trap_subr.S#5 integrate
.. //depot/projects/usb/src/sys/powerpc/booke/vm_machdep.c#5 integrate
.. //depot/projects/usb/src/sys/powerpc/include/mutex.h#2 integrate
.. //depot/projects/usb/src/sys/powerpc/include/pcpu.h#9 integrate
.. //depot/projects/usb/src/sys/powerpc/include/spr.h#10 integrate
.. //depot/projects/usb/src/sys/powerpc/mpc85xx/ocpbus.c#7 integrate
.. //depot/projects/usb/src/sys/powerpc/mpc85xx/ocpbus.h#3 integrate
.. //depot/projects/usb/src/sys/powerpc/powerpc/busdma_machdep.c#3 integrate
.. //depot/projects/usb/src/sys/powerpc/powerpc/genassym.c#9 integrate
.. //depot/projects/usb/src/sys/powerpc/powerpc/mp_machdep.c#7 integrate
.. //depot/projects/usb/src/sys/powerpc/powerpc/openpic.c#7 integrate
.. //depot/projects/usb/src/sys/sparc64/conf/GENERIC#18 integrate

Differences ...

==== //depot/projects/usb/src/sys/conf/files.powerpc#23 (text+ko) ====

@@ -1,7 +1,7 @@
 # This file tells config what files go into building a kernel,
 # files marked standard are always included.
 #
-# $FreeBSD: src/sys/conf/files.powerpc,v 1.100 2009/05/14 00:34:26 nwhitehorn Exp $
+# $FreeBSD: src/sys/conf/files.powerpc,v 1.101 2009/05/21 11:43:37 raj Exp $
 #
 # The long compile-with and dependency lines are required because of
 # limitations in config: backslash-newline doesn't work in strings, and
@@ -91,6 +91,7 @@
 powerpc/booke/interrupt.c	optional	e500
 powerpc/booke/locore.S		optional	e500 no-obj
 powerpc/booke/machdep.c		optional	e500
+powerpc/booke/mp_cpudep.c	optional	e500 smp
 powerpc/booke/platform_bare.c	optional	mpc85xx
 powerpc/booke/pmap.c		optional	e500
 powerpc/booke/swtch.S		optional	e500

==== //depot/projects/usb/src/sys/dev/ata/ata-usb.c#42 (text) ====

@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/ata/ata-usb.c,v 1.14 2009/03/02 05:37:05 thompsa Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/ata/ata-usb.c,v 1.15 2009/05/21 02:09:12 thompsa Exp $");
 
 #include "usbdevs.h"
 #include <dev/usb/usb.h>

==== //depot/projects/usb/src/sys/dev/cxgb/common/cxgb_ael1002.c#10 (text+ko) ====

@@ -28,7 +28,7 @@
 ***************************************************************************/
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/cxgb/common/cxgb_ael1002.c,v 1.12 2009/03/10 19:22:45 gnn Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/cxgb/common/cxgb_ael1002.c,v 1.13 2009/05/21 15:08:03 gnn Exp $");
 
 #include <cxgb_include.h>
 
@@ -1156,6 +1156,7 @@
 		v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 131);
 		if (v < 0)
 			return v;
+		v &= 0xf0;
 		if (v == 0x10)
 			return phy_modtype_lrm;
 		if (v == 0x40)
@@ -1245,7 +1246,9 @@
 		return err;
 	phy->modtype = (u8)err;
 
-	if (err == phy_modtype_twinax || err == phy_modtype_twinax_long)
+	if (err == phy_modtype_none || err == phy_modtype_unknown)
+		err = 0;
+	else if (err == phy_modtype_twinax || err == phy_modtype_twinax_long)
 		err = ael2005_setup_twinax_edc(phy, err);
 	else
 		err = ael2005_setup_sr_edc(phy);

==== //depot/projects/usb/src/sys/dev/cxgb/common/cxgb_common.h#10 (text+ko) ====

@@ -25,7 +25,7 @@
 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 POSSIBILITY OF SUCH DAMAGE.
 
-$FreeBSD: src/sys/dev/cxgb/common/cxgb_common.h,v 1.14 2009/03/10 19:22:45 gnn Exp $
+$FreeBSD: src/sys/dev/cxgb/common/cxgb_common.h,v 1.15 2009/05/21 15:08:03 gnn Exp $
 
 ***************************************************************************/
 #ifndef __CHELSIO_COMMON_H
@@ -701,7 +701,6 @@
 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);

==== //depot/projects/usb/src/sys/dev/cxgb/common/cxgb_t3_hw.c#12 (text+ko) ====

@@ -28,7 +28,7 @@
 ***************************************************************************/
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/cxgb/common/cxgb_t3_hw.c,v 1.18 2009/03/10 19:22:45 gnn Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/cxgb/common/cxgb_t3_hw.c,v 1.19 2009/05/21 15:08:03 gnn Exp $");
 
 
 #include <cxgb_include.h>
@@ -1285,6 +1285,49 @@
 	t3_write_reg(mac->adapter, A_XGM_RX_HASH_LOW, rx_hash_low);
 }
 
+static int t3_detect_link_fault(adapter_t *adapter, int port_id)
+{
+	struct port_info *pi = adap2pinfo(adapter, port_id);
+	struct cmac *mac = &pi->mac;
+	uint32_t rx_cfg, rx_hash_high, rx_hash_low;
+	int link_fault;
+
+	/* stop rx */
+	t3_gate_rx_traffic(mac, &rx_cfg, &rx_hash_high, &rx_hash_low);
+	t3_write_reg(adapter, A_XGM_RX_CTRL + mac->offset, 0);
+
+	/* clear status and make sure intr is enabled */
+	(void) t3_read_reg(adapter, A_XGM_INT_STATUS + mac->offset);
+	t3_xgm_intr_enable(adapter, port_id);
+
+	/* restart rx */
+	t3_write_reg(adapter, A_XGM_RX_CTRL + mac->offset, F_RXEN);
+	t3_open_rx_traffic(mac, rx_cfg, rx_hash_high, rx_hash_low);
+
+	link_fault = t3_read_reg(adapter, A_XGM_INT_STATUS + mac->offset);
+	return (link_fault & F_LINKFAULTCHANGE ? 1 : 0);
+}
+
+static void t3_clear_faults(adapter_t *adapter, int port_id)
+{
+	struct port_info *pi = adap2pinfo(adapter, port_id);
+	struct cmac *mac = &pi->mac;
+
+	t3_set_reg_field(adapter, A_XGM_TXFIFO_CFG + mac->offset,
+			 F_ENDROPPKT, 0);
+	t3_mac_enable(mac, MAC_DIRECTION_TX | MAC_DIRECTION_RX);
+	t3_set_reg_field(adapter, A_XGM_STAT_CTRL + mac->offset, F_CLRSTATS, 1);
+
+	if (adapter->params.nports <= 2) {
+		t3_xgm_intr_disable(adapter, pi->port_id);
+		t3_read_reg(adapter, A_XGM_INT_STATUS + mac->offset);
+		t3_write_reg(adapter, A_XGM_INT_CAUSE + mac->offset, F_XGM_INT);
+		t3_set_reg_field(adapter, A_XGM_INT_ENABLE + mac->offset,
+				 F_XGM_INT, F_XGM_INT);
+		t3_xgm_intr_enable(adapter, pi->port_id);
+	}
+}
+
 /**
  *	t3_link_changed - handle interface link changes
  *	@adapter: the adapter
@@ -1296,34 +1339,47 @@
  */
 void t3_link_changed(adapter_t *adapter, int port_id)
 {
-	int link_ok, speed, duplex, fc;
+	int link_ok, speed, duplex, fc, link_fault, link_change;
 	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;
-	int force_link_down = 0;
+
+	link_ok = lc->link_ok;
+	speed = lc->speed;
+	duplex = lc->duplex;
+	fc = lc->fc;
+	link_fault = 0;
 
 	phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc);
 
-	if (!lc->link_ok && link_ok && adapter->params.nports <= 2) {
-		u32 rx_cfg, rx_hash_high, rx_hash_low;
-		u32 status;
+	/*
+	 * Check for link faults if any of these is true:
+	 * a) A link fault is suspected, and PHY says link ok
+	 * b) PHY link transitioned from down -> up
+	 */
+	if (adapter->params.nports <= 2 &&
+	    ((pi->link_fault && link_ok) || (!lc->link_ok && link_ok))) {
 
-		t3_xgm_intr_enable(adapter, port_id);
-		t3_gate_rx_traffic(mac, &rx_cfg, &rx_hash_high, &rx_hash_low);
-		t3_write_reg(adapter, A_XGM_RX_CTRL + mac->offset, 0);
-		t3_mac_enable(mac, MAC_DIRECTION_RX);
+		link_fault = t3_detect_link_fault(adapter, port_id);
+		if (link_fault) {
+			if (pi->link_fault != LF_YES) {
+				mac->stats.link_faults++;
+				pi->link_fault = LF_YES;
+			}
 
-		status = t3_read_reg(adapter, A_XGM_INT_STATUS + mac->offset);
-		if (status & F_LINKFAULTCHANGE) {
-			mac->stats.link_faults++;
-			force_link_down = 1;
-		}
-		t3_open_rx_traffic(mac, rx_cfg, rx_hash_high, rx_hash_low);
+			/* Don't report link up or any other change */
+			link_ok = 0;
+			speed = lc->speed;
+			duplex = lc->duplex;
+			fc = lc->fc;
+		} else {
+			/* clear faults here if this was a false alarm. */
+			if (pi->link_fault == LF_MAYBE &&
+			    link_ok && lc->link_ok)
+				t3_clear_faults(adapter, port_id);
 
-		if (force_link_down) {
-			t3_os_link_fault_handler(adapter, port_id);
-			return;
+			pi->link_fault = LF_NO;
 		}
 	}
 
@@ -1336,75 +1392,65 @@
 	    duplex == lc->duplex && fc == lc->fc)
 		return;                            /* nothing changed */
 
-	if (link_ok != lc->link_ok && adapter->params.rev > 0 &&
-	    uses_xaui(adapter)) {
-		if (link_ok)
-			t3b_pcs_reset(mac);
-		t3_write_reg(adapter, A_XGM_XAUI_ACT_CTRL + mac->offset,
-			     link_ok ? F_TXACTENABLE | F_RXEN : 0);
-	}
+	link_change = link_ok != lc->link_ok;
 	lc->link_ok = (unsigned char)link_ok;
 	lc->speed = speed < 0 ? SPEED_INVALID : speed;
 	lc->duplex = duplex < 0 ? DUPLEX_INVALID : duplex;
 
-	if (link_ok && speed >= 0 && lc->autoneg == AUTONEG_ENABLE) {
-		/* Set MAC speed, duplex, and flow control to match PHY. */
-		t3_mac_set_speed_duplex_fc(mac, speed, duplex, fc);
-		lc->fc = (unsigned char)fc;
-	}
+	if (link_ok) {
 
-	t3_os_link_changed(adapter, port_id, link_ok, speed, duplex, fc);
-}
+		/* down -> up, or up -> up with changed settings */
 
-void t3_link_fault(adapter_t *adapter, int port_id)
-{
-	struct port_info *pi = adap2pinfo(adapter, port_id);
-	struct cmac *mac = &pi->mac;
-	struct cphy *phy = &pi->phy;
-	struct link_config *lc = &pi->link_config;
-	int link_ok, speed, duplex, fc, link_fault;
-	u32 rx_cfg, rx_hash_high, rx_hash_low;
+		if (link_change && adapter->params.rev > 0 &&
+		    uses_xaui(adapter)) {
+			t3b_pcs_reset(mac);
+			t3_write_reg(adapter, A_XGM_XAUI_ACT_CTRL + mac->offset,
+				     F_TXACTENABLE | F_RXEN);
+		}
 
-	if (!pi->link_fault)
-		return; /* nothing to do */
+		if (speed >= 0 && lc->autoneg == AUTONEG_ENABLE) {
+			/* Set MAC settings to match PHY. */
+			t3_mac_set_speed_duplex_fc(mac, speed, duplex, fc);
+			lc->fc = (unsigned char)fc;
+		}
 
-	t3_gate_rx_traffic(mac, &rx_cfg, &rx_hash_high, &rx_hash_low);
+		t3_clear_faults(adapter, port_id);
 
-	if (adapter->params.rev > 0 && uses_xaui(adapter))
-		t3_write_reg(adapter, A_XGM_XAUI_ACT_CTRL + mac->offset, 0);
+	} else {
 
-	t3_write_reg(adapter, A_XGM_RX_CTRL + mac->offset, 0);
-	t3_mac_enable(mac, MAC_DIRECTION_RX);
+		/* up -> down */
 
-	t3_open_rx_traffic(mac, rx_cfg, rx_hash_high, rx_hash_low);
+		if (adapter->params.rev > 0 && uses_xaui(adapter)) {
+			t3_write_reg(adapter,
+				     A_XGM_XAUI_ACT_CTRL + mac->offset, 0);
+		}
 
-	link_fault = t3_read_reg(adapter,
-				 A_XGM_INT_STATUS + mac->offset);
-	link_fault &= F_LINKFAULTCHANGE;
+		t3_xgm_intr_disable(adapter, pi->port_id);
+		if (adapter->params.nports <= 2) {
+			t3_set_reg_field(adapter,
+					 A_XGM_INT_ENABLE + mac->offset,
+					 F_XGM_INT, 0);
+		}
 
-	phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc);
+		if (!link_fault) {
+			if (is_10G(adapter))
+				pi->phy.ops->power_down(&pi->phy, 1);
+			t3_mac_disable(mac, MAC_DIRECTION_RX);
+			t3_link_start(phy, mac, lc);
+		}
 
-	if (link_fault) {
-		lc->link_ok = 0;
-		lc->speed = SPEED_INVALID;
-		lc->duplex = DUPLEX_INVALID;
+		/*
+		 * Make sure Tx FIFO continues to drain, even as rxen is left
+		 * high to help detect and indicate remote faults.
+		 */
+		t3_set_reg_field(adapter, A_XGM_TXFIFO_CFG + mac->offset, 0,
+				 F_ENDROPPKT);
+		t3_write_reg(adapter, A_XGM_RX_CTRL + mac->offset, 0);
+		t3_write_reg(adapter, A_XGM_TX_CTRL + mac->offset, F_TXEN);
+		t3_write_reg(adapter, A_XGM_RX_CTRL + mac->offset, F_RXEN);
+	}
 
-		t3_os_link_fault(adapter, port_id, 0);
-
-		/* Account link faults only when the phy reports a link up */
-		if (link_ok)
-			mac->stats.link_faults++;
-	} else {
-		if (link_ok)
-			t3_write_reg(adapter, A_XGM_XAUI_ACT_CTRL + mac->offset,
-			     	     F_TXACTENABLE | F_RXEN);
-
-		pi->link_fault = 0;
-		lc->link_ok = (unsigned char)link_ok;
-		lc->speed = speed < 0 ? SPEED_INVALID : speed;
-		lc->duplex = duplex < 0 ? DUPLEX_INVALID : duplex;
-		t3_os_link_fault(adapter, port_id, link_ok);
-	}
+	t3_os_link_changed(adapter, port_id, link_ok, speed, duplex, fc);
 }
 
 /**
@@ -1901,10 +1947,12 @@
 static int mac_intr_handler(adapter_t *adap, unsigned int idx)
 {
 	u32 cause;
+	struct port_info *pi;
 	struct cmac *mac;
 
 	idx = idx == 0 ? 0 : adapter_info(adap)->nports0; /* MAC idx -> port */
-	mac = &adap2pinfo(adap, idx)->mac;
+	pi = adap2pinfo(adap, idx);
+	mac = &pi->mac;
 
 	/*
 	 * We mask out interrupt causes for which we're not taking interrupts.
@@ -1937,9 +1985,9 @@
 		t3_set_reg_field(adap,
 				 A_XGM_INT_ENABLE + mac->offset,
 				 F_XGM_INT, 0);
-		mac->stats.link_faults++;
 
-		t3_os_link_fault_handler(adap, idx);
+		/* link fault suspected */
+		pi->link_fault = LF_MAYBE;
 	}
 
 	t3_write_reg(adap, A_XGM_INT_CAUSE + mac->offset, cause);

==== //depot/projects/usb/src/sys/dev/cxgb/cxgb_adapter.h#10 (text+ko) ====

@@ -25,7 +25,7 @@
 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 POSSIBILITY OF SUCH DAMAGE.
 
-$FreeBSD: src/sys/dev/cxgb/cxgb_adapter.h,v 1.44 2009/03/10 19:22:45 gnn Exp $
+$FreeBSD: src/sys/dev/cxgb/cxgb_adapter.h,v 1.45 2009/05/21 15:08:03 gnn Exp $
 
 ***************************************************************************/
 
@@ -100,6 +100,12 @@
 #define SX_DESTROY sx_destroy
 #endif
 
+enum {
+	LF_NO = 0,
+	LF_MAYBE,
+	LF_YES
+};
+
 struct port_info {
 	struct adapter	*adapter;
 	struct ifnet	*ifp;
@@ -123,7 +129,6 @@
 
 	uint8_t		hw_addr[ETHER_ADDR_LEN];
 	struct task	timer_reclaim_task;
-	struct task	link_fault_task;
 	struct cdev     *port_cdev;
 
 #define PORT_LOCK_NAME_LEN 32
@@ -393,6 +398,7 @@
 	device_t		portdev[MAX_NPORTS];
 	struct t3cdev           tdev;
 	char                    fw_version[64];
+	char                    port_types[MAX_NPORTS + 1];
 	uint32_t                open_device_map;
 	uint32_t                registered_device_map;
 #ifdef USE_SX
@@ -435,6 +441,7 @@
 #define ADAPTER_LOCK_INIT(adap, name)      SX_INIT(&(adap)->lock, name)
 #define ADAPTER_LOCK_DEINIT(adap)          SX_DESTROY(&(adap)->lock)
 #define ADAPTER_LOCK_ASSERT_NOTOWNED(adap) sx_assert(&(adap)->lock, SA_UNLOCKED)
+#define ADAPTER_LOCK_ASSERT_OWNED(adap) sx_assert(&(adap)->lock, SA_LOCKED)
 #else
 #define PORT_LOCK(port)		     mtx_lock(&(port)->lock);
 #define PORT_UNLOCK(port)	     mtx_unlock(&(port)->lock);
@@ -446,7 +453,8 @@
 #define ADAPTER_UNLOCK(adap)	mtx_unlock(&(adap)->lock);
 #define ADAPTER_LOCK_INIT(adap, name) mtx_init(&(adap)->lock, name, 0, MTX_DEF)
 #define ADAPTER_LOCK_DEINIT(adap) mtx_destroy(&(adap)->lock)
-#define ADAPTER_LOCK_ASSERT_NOTOWNED(adap) mtx_assert(&(adap)->lock, MO_NOTOWNED)
+#define ADAPTER_LOCK_ASSERT_NOTOWNED(adap) mtx_assert(&(adap)->lock, MA_NOTOWNED)
+#define ADAPTER_LOCK_ASSERT_OWNED(adap) mtx_assert(&(adap)->lock, MA_OWNED)
 #endif
 
 
@@ -530,8 +538,6 @@
 void t3_os_link_changed(adapter_t *adapter, int port_id, int link_status,
 			int speed, int duplex, int fc);
 void t3_os_phymod_changed(struct adapter *adap, int port_id);
-void t3_os_link_fault(adapter_t *adapter, int port_id, int state);
-void t3_os_link_fault_handler(adapter_t *adapter, int port_id);
 void t3_sge_err_intr_handler(adapter_t *adapter);
 int t3_offload_tx(struct t3cdev *, struct mbuf *);
 void t3_os_ext_intr_handler(adapter_t *adapter);

==== //depot/projects/usb/src/sys/dev/cxgb/cxgb_main.c#16 (text+ko) ====

@@ -28,7 +28,7 @@
 ***************************************************************************/
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/cxgb/cxgb_main.c,v 1.82 2009/05/20 17:29:21 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/cxgb/cxgb_main.c,v 1.84 2009/05/21 15:08:03 gnn Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -115,7 +115,7 @@
 static void touch_bars(device_t dev);
 static int offload_close(struct t3cdev *tdev);
 static void cxgb_link_start(struct port_info *p);
-static void cxgb_link_fault(void *arg, int ncount);
+int t3_detect_link_fault(adapter_t *adapter, int port_id);
 
 static device_method_t cxgb_controller_methods[] = {
 	DEVMETHOD(device_probe,		cxgb_controller_probe),
@@ -392,6 +392,31 @@
 	return (status);	
 }
 
+/*
+ * The cxgb_controller_attach function is responsible for the initial
+ * bringup of the device.  Its responsibilities include:
+ *
+ *  1. Determine if the device supports MSI or MSI-X.
+ *  2. Allocate bus resources so that we can access the Base Address Register
+ *  3. Create and initialize mutexes for the controller and its control
+ *     logic such as SGE and MDIO.
+ *  4. Call hardware specific setup routine for the adapter as a whole.
+ *  5. Allocate the BAR for doing MSI-X.
+ *  6. Setup the line interrupt iff MSI-X is not supported.
+ *  7. Create the driver's taskq.
+ *  8. Start the task queue threads.
+ *  9. Update the firmware if required.
+ * 10. Create a child device for each MAC (port)
+ * 11. Initialize T3 private state.
+ * 12. Trigger the LED
+ * 13. Setup offload iff supported.
+ * 14. Reset/restart the tick callout.
+ * 15. Attach sysctls
+ *
+ * NOTE: Any modification or deviation from this list MUST be reflected in
+ * the above comment.  Failure to do so will result in problems on various
+ * error conditions including link flapping.
+ */
 static int
 cxgb_controller_attach(device_t dev)
 {
@@ -625,6 +650,10 @@
 		 sc->params.vpd.ec, sc->params.vpd.sn);
 	device_set_desc_copy(dev, buf);
 
+	snprintf(&sc->port_types[0], sizeof(sc->port_types), "%x%x%x%x",
+		 sc->params.vpd.port_type[0], sc->params.vpd.port_type[1],
+		 sc->params.vpd.port_type[2], sc->params.vpd.port_type[3]);
+
 	device_printf(sc->dev, "Firmware Version %s\n", &sc->fw_version[0]);
 	callout_reset(&sc->cxgb_tick_ch, CXGB_TICKS(sc), cxgb_tick, sc);
 	t3_add_attach_sysctls(sc);
@@ -635,6 +664,11 @@
 	return (error);
 }
 
+/*
+ * The cxgb_controlller_detach routine is called with the device is
+ * unloaded from the system.
+ */
+
 static int
 cxgb_controller_detach(device_t dev)
 {
@@ -647,6 +681,24 @@
 	return (0);
 }
 
+/*
+ * The cxgb_free() is called by the cxgb_controller_detach() routine
+ * to tear down the structures that were built up in
+ * cxgb_controller_attach(), and should be the final piece of work
+ * done when fullly unloading the driver.
+ * 
+ *
+ *  1. Shutting down the threads started by the cxgb_controller_attach()
+ *     routine.
+ *  2. Stopping the lower level device and all callouts (cxgb_down_locked()).
+ *  3. Detaching all of the port devices created during the
+ *     cxgb_controller_attach() routine.
+ *  4. Removing the device children created via cxgb_controller_attach().
+ *  5. Releaseing PCI resources associated with the device.
+ *  6. Turning off the offload support, iff it was turned on.
+ *  7. Destroying the mutexes created in cxgb_controller_attach().
+ *
+ */
 static void
 cxgb_free(struct adapter *sc)
 {
@@ -655,14 +707,27 @@
 	ADAPTER_LOCK(sc);
 	sc->flags |= CXGB_SHUTDOWN;
 	ADAPTER_UNLOCK(sc);
+
 	cxgb_pcpu_shutdown_threads(sc);
+
 	ADAPTER_LOCK(sc);
-
-/*
- * drops the lock
- */
 	cxgb_down_locked(sc);
+	ADAPTER_UNLOCK(sc);
+	
+	t3_sge_deinit_sw(sc);
+	/*
+	 * Wait for last callout
+	 */
 	
+	DELAY(hz*100);
+
+	bus_generic_detach(sc->dev);
+
+	for (i = 0; i < (sc)->params.nports; i++) {
+		if (device_delete_child(sc->dev, sc->portdev[i]) != 0)
+			device_printf(sc->dev, "failed to delete child port\n");
+	}
+
 #ifdef MSI_SUPPORTED
 	if (sc->flags & (USING_MSI | USING_MSIX)) {
 		device_printf(sc->dev, "releasing msi message(s)\n");
@@ -676,19 +741,6 @@
 		    sc->msix_regs_res);
 	}
 
-	t3_sge_deinit_sw(sc);
-	/*
-	 * Wait for last callout
-	 */
-	
-	DELAY(hz*100);
-
-	for (i = 0; i < (sc)->params.nports; ++i) {
-		if (sc->portdev[i] != NULL)
-			device_delete_child(sc->dev, sc->portdev[i]);
-	}
-		
-	bus_generic_detach(sc->dev);
 	if (sc->tq != NULL) {
 		taskqueue_free(sc->tq);
 		sc->tq = NULL;
@@ -957,6 +1009,7 @@
 	}
 
 	ether_ifattach(ifp, p->hw_addr);
+
 #ifdef IFNET_MULTIQUEUE
 	ifp->if_transmit = cxgb_pcpu_transmit;
 #endif
@@ -1020,40 +1073,104 @@
 	bcopy(IF_LLADDR(p->ifp), p->hw_addr, ETHER_ADDR_LEN);
 	t3_sge_init_port(p);
 
-	TASK_INIT(&p->link_fault_task, 0, cxgb_link_fault, p);
+	/* If it's MSI or INTx, allocate a single interrupt for everything */
+	if ((sc->flags & USING_MSIX) == 0) {
+		if ((sc->irq_res = bus_alloc_resource_any(sc->dev, SYS_RES_IRQ,
+		   &sc->irq_rid, RF_SHAREABLE | RF_ACTIVE)) == NULL) {
+			device_printf(sc->dev, "Cannot allocate interrupt rid=%d\n",
+			    sc->irq_rid);
+			err = EINVAL;
+			goto out;
+		}
+		device_printf(sc->dev, "allocated irq_res=%p\n", sc->irq_res);
+
+		if (bus_setup_intr(sc->dev, sc->irq_res, INTR_MPSAFE|INTR_TYPE_NET,
+#ifdef INTR_FILTERS
+			NULL,
+#endif			
+			sc->cxgb_intr, sc, &sc->intr_tag)) {
+			device_printf(sc->dev, "Cannot set up interrupt\n");
+			err = EINVAL;
+			goto irq_err;
+		}
+	} else {
+		cxgb_setup_msix(sc, sc->msi_count);
+	}
 
 #if defined(LINK_ATTACH)	
 	cxgb_link_start(p);
 	t3_link_changed(sc, p->port_id);
 #endif
-	return (0);
+out:
+	return (err);
+irq_err:
+	CH_ERR(sc, "request_irq failed, err %d\n", err);
+	goto out;
 }
 
+/*
+ * cxgb_port_detach() is called via the device_detach methods when
+ * cxgb_free() calls the bus_generic_detach.  It is responsible for 
+ * removing the device from the view of the kernel, i.e. from all 
+ * interfaces lists etc.  This routine is only called when the driver is 
+ * being unloaded, not when the link goes down.
+ * 
+ */
 static int
 cxgb_port_detach(device_t dev)
 {
 	struct port_info *p;
+	struct adapter *sc;
 
 	p = device_get_softc(dev);
+	sc = p->adapter;
+
+	if (p->port_cdev != NULL)
+		destroy_dev(p->port_cdev);
+	
+	ether_ifdetach(p->ifp);
+	printf("waiting for callout to stop ...");
+	printf("done\n");
 
 	PORT_LOCK(p);
 	if (p->ifp->if_drv_flags & IFF_DRV_RUNNING) 
 		cxgb_stop_locked(p);
 	PORT_UNLOCK(p);
 	
-	ether_ifdetach(p->ifp);
-	printf("waiting for callout to stop ...");
-	DELAY(1000000);
-	printf("done\n");
+	if (sc->intr_tag != NULL) {
+		bus_teardown_intr(sc->dev, sc->irq_res, sc->intr_tag);
+		sc->intr_tag = NULL;
+	}
+	if (sc->irq_res != NULL) {
+		device_printf(sc->dev, "de-allocating interrupt irq_rid=%d irq_res=%p\n",
+		    sc->irq_rid, sc->irq_res);
+		bus_release_resource(sc->dev, SYS_RES_IRQ, sc->irq_rid,
+		    sc->irq_res);
+		sc->irq_res = NULL;
+	}
+	
+	if (sc->flags & USING_MSIX) 
+		cxgb_teardown_msix(sc);
+	
+	callout_drain(&sc->cxgb_tick_ch);
+	callout_drain(&sc->sge_timer_ch);
+	
+	if (sc->tq != NULL) {
+		printf("draining slow intr\n");
+		
+		taskqueue_drain(sc->tq, &sc->slow_intr_task);
+			printf("draining ext intr\n");	
+		taskqueue_drain(sc->tq, &sc->ext_intr_task);
+		printf("draining tick task\n");
+		taskqueue_drain(sc->tq, &sc->tick_task);
+	}
+
 	/*
 	 * the lock may be acquired in ifdetach
 	 */
 	PORT_LOCK_DEINIT(p);
 	if_free(p->ifp);
 	
-	if (p->port_cdev != NULL)
-		destroy_dev(p->port_cdev);
-	
 	return (0);
 }
 
@@ -1142,32 +1259,6 @@
 	return (0);
 }
 
-void t3_os_link_fault(struct adapter *adap, int port_id, int state)
-{
-	struct port_info *pi = &adap->port[port_id];
-
-	if (!state) {
-		if_link_state_change(pi->ifp, LINK_STATE_DOWN);
-		return;
-	}
-
-	if (adap->params.nports <= 2) {
-		struct cmac *mac = &pi->mac;
-
-		/* Clear local faults */
-		t3_xgm_intr_disable(adap, port_id);
-		t3_read_reg(adap, A_XGM_INT_STATUS + pi->mac.offset);
-		t3_write_reg(adap, A_XGM_INT_CAUSE + pi->mac.offset, F_XGM_INT);
-				
-		t3_set_reg_field(adap, A_XGM_INT_ENABLE + pi->mac.offset,
-				 F_XGM_INT, F_XGM_INT);
-		t3_xgm_intr_enable(adap, pi->port_id);
-		t3_mac_enable(mac, MAC_DIRECTION_TX);
-	}
-
-	if_link_state_change(pi->ifp, LINK_STATE_UP);
-}
-
 /**
  *	t3_os_link_changed - handle link status changes
  *	@adapter: the adapter associated with the link change
@@ -1186,48 +1277,12 @@
      int duplex, int fc)
 {
 	struct port_info *pi = &adapter->port[port_id];
-	struct cmac *mac = &adapter->port[port_id].mac;
 
 	if (link_status) {
-		DELAY(10);
-		t3_mac_enable(mac, MAC_DIRECTION_RX | MAC_DIRECTION_TX);
-		/* Clear errors created by MAC enable */
-		t3_set_reg_field(adapter, A_XGM_STAT_CTRL + pi->mac.offset,
-				 F_CLRSTATS, 1);
-
-		if (adapter->params.nports <= 2) {
-			/* Clear local faults */
-			t3_xgm_intr_disable(adapter, pi->port_id);
-			t3_read_reg(adapter, A_XGM_INT_STATUS + pi->mac.offset);
-			t3_write_reg(adapter, A_XGM_INT_CAUSE + pi->mac.offset,
-				     F_XGM_INT); 
-
-			t3_set_reg_field(adapter,
-					 A_XGM_INT_ENABLE + pi->mac.offset,
-					 F_XGM_INT, F_XGM_INT);
-			t3_xgm_intr_enable(adapter, pi->port_id);
-		}
-
+		pi->ifp->if_baudrate = IF_Mbps(speed);
 		if_link_state_change(pi->ifp, LINK_STATE_UP);
-	} else {
-		t3_xgm_intr_disable(adapter, pi->port_id);
-		t3_read_reg(adapter, A_XGM_INT_STATUS + pi->mac.offset);
-		if (adapter->params.nports <= 2) {
-			t3_set_reg_field(adapter,
-					 A_XGM_INT_ENABLE + pi->mac.offset,
-					 F_XGM_INT, 0);
-		}
-
-		/* PR 5666. We shouldn't power down 1G phys */
-		if (is_10G(adapter))
-			pi->phy.ops->power_down(&pi->phy, 1);
-
-		t3_read_reg(adapter, A_XGM_INT_STATUS + pi->mac.offset);
-		t3_mac_disable(mac, MAC_DIRECTION_RX);
-		t3_link_start(&pi->phy, mac, &pi->link_config);
-
+	} else
 		if_link_state_change(pi->ifp, LINK_STATE_DOWN);
-	}
 }
 
 /**
@@ -1280,22 +1335,6 @@
 	ADAPTER_UNLOCK(sc);
 }
 
-static void
-cxgb_link_fault(void *arg, int ncount)
-{
-	struct port_info *pi = arg;
-
-	t3_link_fault(pi->adapter, pi->port_id);
-}
-
-void t3_os_link_fault_handler(struct adapter *sc, int port_id)
-{
-	struct port_info *pi = &sc->port[port_id];
-
-	pi->link_fault = 1;
-	taskqueue_enqueue(sc->tq, &pi->link_fault_task);
-}
-
 void
 t3_os_set_hw_addr(adapter_t *adapter, int port_idx, u8 hw_addr[])
 {
@@ -1705,30 +1744,6 @@
 
 	t3_intr_clear(sc);
 
-	/* If it's MSI or INTx, allocate a single interrupt for everything */
-	if ((sc->flags & USING_MSIX) == 0) {
-		if ((sc->irq_res = bus_alloc_resource_any(sc->dev, SYS_RES_IRQ,
-		   &sc->irq_rid, RF_SHAREABLE | RF_ACTIVE)) == NULL) {
-			device_printf(sc->dev, "Cannot allocate interrupt rid=%d\n",
-			    sc->irq_rid);
-			err = EINVAL;
-			goto out;
-		}
-		device_printf(sc->dev, "allocated irq_res=%p\n", sc->irq_res);
-
-		if (bus_setup_intr(sc->dev, sc->irq_res, INTR_MPSAFE|INTR_TYPE_NET,
-#ifdef INTR_FILTERS
-			NULL,
-#endif			
-			sc->cxgb_intr, sc, &sc->intr_tag)) {
-			device_printf(sc->dev, "Cannot set up interrupt\n");
-			err = EINVAL;
-			goto irq_err;
-		}
-	} else {
-		cxgb_setup_msix(sc, sc->msi_count);
-	}
-
 	t3_sge_start(sc);
 	t3_intr_enable(sc);
 
@@ -1749,9 +1764,6 @@
 	}
 out:
 	return (err);
-irq_err:
-	CH_ERR(sc, "request_irq failed, err %d\n", err);
-	goto out;
 }
 
 
@@ -1765,36 +1777,8 @@
 	t3_sge_stop(sc);
 	t3_intr_disable(sc);
 
-	if (sc->intr_tag != NULL) {
-		bus_teardown_intr(sc->dev, sc->irq_res, sc->intr_tag);
-		sc->intr_tag = NULL;
-	}
-	if (sc->irq_res != NULL) {
-		device_printf(sc->dev, "de-allocating interrupt irq_rid=%d irq_res=%p\n",
-		    sc->irq_rid, sc->irq_res);
-		bus_release_resource(sc->dev, SYS_RES_IRQ, sc->irq_rid,
-		    sc->irq_res);
-		sc->irq_res = NULL;
-	}
-	
-	if (sc->flags & USING_MSIX) 
-		cxgb_teardown_msix(sc);
-	
 	callout_stop(&sc->cxgb_tick_ch);
 	callout_stop(&sc->sge_timer_ch);
-	callout_drain(&sc->cxgb_tick_ch);
-	callout_drain(&sc->sge_timer_ch);
-	
-	if (sc->tq != NULL) {
-		printf("draining slow intr\n");
-		
-		taskqueue_drain(sc->tq, &sc->slow_intr_task);
-			printf("draining ext intr\n");	
-		taskqueue_drain(sc->tq, &sc->ext_intr_task);
-		printf("draining tick task\n");
-		taskqueue_drain(sc->tq, &sc->tick_task);
-	}
-	ADAPTER_UNLOCK(sc);
 }
 
 static int
@@ -1861,8 +1845,9 @@
 	ADAPTER_LOCK(adapter);
 	if (!adapter->open_device_map)
 		cxgb_down_locked(adapter);
-	else
-		ADAPTER_UNLOCK(adapter);

>>> TRUNCATED FOR MAIL (1000 lines) <<<


More information about the p4-projects mailing list