JS20 kernel

Jake Moilanen moilanen at austin.ibm.com
Fri Aug 13 05:56:26 EST 2004


>
> Should I expect mainline 2.6 to work on an IBM JS20?  Should I start
> with pSeries_defconfig?
>

The mainline should work w/ everything except the broadcom adapter.  It
seems that the tg3 driver got regressed somewhere in the following
patch.  Brian Rzycki is working on getting the correct fix.

Thanks,
Jake

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.1722.162.1 -> 1.1722.162.2
#	   drivers/net/tg3.h	1.42    -> 1.43
#	   drivers/net/tg3.c	1.184   -> 1.185
#
# --------------------------------------------
# 04/07/02	davem at nuts.davemloft.net	1.1722.162.2
# [TG3]: Fibre PHY fixes from Sun.
#
# - Support HW autoneg on 5704.
# - On serdes, no MII reg ioctl support.
# --------------------------------------------
#
diff -Nru a/drivers/net/tg3.c b/drivers/net/tg3.c
--- a/drivers/net/tg3.c	Mon Jul 19 11:05:33 2004
+++ b/drivers/net/tg3.c	Mon Jul 19 11:05:33 2004
@@ -1,8 +1,9 @@
 /*
  * tg3.c: Broadcom Tigon3 ethernet driver.
  *
- * Copyright (C) 2001, 2002, 2003 David S. Miller (davem at redhat.com)
+ * Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem at redhat.com)
  * Copyright (C) 2001, 2002, 2003 Jeff Garzik (jgarzik at pobox.com)
+ * Copyright (C) 2004 Sun Microsystems Inc.
  */

 #include <linux/config.h>
@@ -1961,6 +1962,67 @@
 	return ret;
 }

+static int fiber_autoneg(struct tg3 *tp, u32 *flags)
+{
+	int res = 0;
+
+	if (tp->tg3_flags2 & TG3_FLG2_HW_AUTONEG) {
+		u32 dig_status;
+
+		dig_status = tr32(SG_DIG_STATUS);
+		*flags = 0;
+		if (dig_status & SG_DIG_PARTNER_ASYM_PAUSE)
+			*flags |= MR_LP_ADV_ASYM_PAUSE;
+		if (dig_status & SG_DIG_PARTNER_PAUSE_CAPABLE)
+			*flags |= MR_LP_ADV_SYM_PAUSE;
+
+		if ((dig_status & SG_DIG_AUTONEG_COMPLETE) &&
+		    !(dig_status & (SG_DIG_AUTONEG_ERROR |
+				    SG_DIG_PARTNER_FAULT_MASK)))
+			res = 1;
+	} else {
+		struct tg3_fiber_aneginfo aninfo;
+		int status = ANEG_FAILED;
+		unsigned int tick;
+		u32 tmp;
+
+		tw32_f(MAC_TX_AUTO_NEG, 0);
+
+		tmp = tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK;
+		tw32_f(MAC_MODE, tmp | MAC_MODE_PORT_MODE_GMII);
+		udelay(40);
+
+		tw32_f(MAC_MODE, tp->mac_mode | MAC_MODE_SEND_CONFIGS);
+		udelay(40);
+
+		memset(&aninfo, 0, sizeof(aninfo));
+		aninfo.flags |= MR_AN_ENABLE;
+		aninfo.state = ANEG_STATE_UNKNOWN;
+		aninfo.cur_time = 0;
+		tick = 0;
+		while (++tick < 195000) {
+			status = tg3_fiber_aneg_smachine(tp, &aninfo);
+			if (status == ANEG_DONE || status == ANEG_FAILED)
+				break;
+
+			udelay(1);
+		}
+
+		tp->mac_mode &= ~MAC_MODE_SEND_CONFIGS;
+		tw32_f(MAC_MODE, tp->mac_mode);
+		udelay(40);
+
+		*flags = aninfo.flags;
+
+		if (status == ANEG_DONE &&
+		    (aninfo.flags & (MR_AN_COMPLETE | MR_LINK_OK |
+				     MR_LP_ADV_FULL_DUPLEX)))
+			res = 1;
+	}
+
+	return res;
+}
+
 static int tg3_setup_fiber_phy(struct tg3 *tp, int force_reset)
 {
 	u32 orig_pause_cfg;
@@ -1980,6 +2042,20 @@
 	tw32_f(MAC_MODE, tp->mac_mode);
 	udelay(40);

+	if (tp->tg3_flags2 & TG3_FLG2_HW_AUTONEG) {
+		/* Allow time for the hardware to auto-negotiate (195ms) */
+		unsigned int tick = 0;
+
+		while (++tick < 195000) {
+			if (tr32(SG_DIG_STATUS) & SG_DIG_AUTONEG_COMPLETE)
+				break;
+			udelay(1);
+		}
+		if (tick >= 195000)
+			printk(KERN_INFO PFX "%s: HW autoneg failed !\n",
+			    tp->dev->name);
+	}
+
 	/* Reset when initting first time or we have a link. */
 	if (!(tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) ||
 	    (tr32(MAC_STATUS) & MAC_STATUS_PCS_SYNCED)) {
@@ -2031,53 +2107,18 @@
 	udelay(40);

 	current_link_up = 0;
-	if (tr32(MAC_STATUS) & MAC_STATUS_PCS_SYNCED) {
-		if (tp->link_config.autoneg == AUTONEG_ENABLE &&
-		    !(tp->tg3_flags & TG3_FLAG_GOT_SERDES_FLOWCTL)) {
-			struct tg3_fiber_aneginfo aninfo;
-			int status = ANEG_FAILED;
-			unsigned int tick;
-			u32 tmp;
-
-			memset(&aninfo, 0, sizeof(aninfo));
-			aninfo.flags |= (MR_AN_ENABLE);
-
-			tw32(MAC_TX_AUTO_NEG, 0);
-
-			tmp = tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK;
-			tw32_f(MAC_MODE, tmp | MAC_MODE_PORT_MODE_GMII);
-			udelay(40);
-
-			tw32_f(MAC_MODE, tp->mac_mode | MAC_MODE_SEND_CONFIGS);
-			udelay(40);
-
-			aninfo.state = ANEG_STATE_UNKNOWN;
-			aninfo.cur_time = 0;
-			tick = 0;
-			while (++tick < 195000) {
-				status = tg3_fiber_aneg_smachine(tp, &aninfo);
-				if (status == ANEG_DONE ||
-				    status == ANEG_FAILED)
-					break;
-
-				udelay(1);
-			}
-
-			tp->mac_mode &= ~MAC_MODE_SEND_CONFIGS;
-			tw32_f(MAC_MODE, tp->mac_mode);
-			udelay(40);
-
-			if (status == ANEG_DONE &&
-			    (aninfo.flags &
-			     (MR_AN_COMPLETE | MR_LINK_OK |
-			      MR_LP_ADV_FULL_DUPLEX))) {
+ 	if (tr32(MAC_STATUS) & MAC_STATUS_PCS_SYNCED) {
+		if (tp->link_config.autoneg == AUTONEG_ENABLE) {
+			u32 flags;
+
+			if (fiber_autoneg(tp, &flags)) {
 				u32 local_adv, remote_adv;

 				local_adv = ADVERTISE_PAUSE_CAP;
 				remote_adv = 0;
-				if (aninfo.flags & MR_LP_ADV_SYM_PAUSE)
-					remote_adv |= LPA_PAUSE_CAP;
-				if (aninfo.flags & MR_LP_ADV_ASYM_PAUSE)
+				if (flags & MR_LP_ADV_SYM_PAUSE)
+  					remote_adv |= LPA_PAUSE_CAP;
+				if (flags & MR_LP_ADV_ASYM_PAUSE)
 					remote_adv |= LPA_PAUSE_ASYM;

 				tg3_setup_flow_control(tp, local_adv, remote_adv);
@@ -2104,8 +2145,10 @@
 		} else {
 			/* Forcing 1000FD link up. */
 			current_link_up = 1;
+			tp->tg3_flags |= TG3_FLAG_GOT_SERDES_FLOWCTL;
 		}
-	}
+	} else
+		tp->tg3_flags &= ~TG3_FLAG_GOT_SERDES_FLOWCTL;

 	tp->mac_mode &= ~MAC_MODE_LINK_POLARITY;
 	tw32_f(MAC_MODE, tp->mac_mode);
@@ -5203,6 +5246,26 @@
 	 */
 	tw32_f(MAC_LOW_WMARK_MAX_RX_FRAME, 2);

+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 &&
+	    tp->phy_id == PHY_ID_SERDES) {
+		/* Enable hardware link auto-negotiation */
+		u32 digctrl, txctrl;
+
+		digctrl = SG_DIG_USING_HW_AUTONEG | SG_DIG_CRC16_CLEAR_N |
+		    SG_DIG_LOCAL_DUPLEX_STATUS | SG_DIG_LOCAL_LINK_STATUS |
+		    (2 << SG_DIG_SPEED_STATUS_SHIFT) | SG_DIG_FIBER_MODE |
+		    SG_DIG_GBIC_ENABLE;
+
+		txctrl = tr32(MAC_SERDES_CFG);
+		tw32_f(MAC_SERDES_CFG, txctrl | MAC_SERDES_CFG_EDGE_SELECT);
+		tw32_f(SG_DIG_CTRL, digctrl | SG_DIG_SOFT_RESET);
+		tr32(SG_DIG_CTRL);
+		udelay(5);
+		tw32_f(SG_DIG_CTRL, digctrl);
+
+		tp->tg3_flags2 |= TG3_FLG2_HW_AUTONEG;
+	}
+
 	err = tg3_setup_phy(tp, 1);
 	if (err)
 		return err;
@@ -6536,6 +6599,9 @@
 	case SIOCGMIIREG: {
 		u32 mii_regval;

+		if (tp->phy_id == PHY_ID_SERDES)
+			break;			/* We have no PHY */
+
 		spin_lock_irq(&tp->lock);
 		err = tg3_readphy(tp, data->reg_num & 0x1f, &mii_regval);
 		spin_unlock_irq(&tp->lock);
@@ -6546,6 +6612,9 @@
 	}

 	case SIOCSMIIREG:
+		if (tp->phy_id == PHY_ID_SERDES)
+			break;			/* We have no PHY */
+
 		if (!capable(CAP_NET_ADMIN))
 			return -EPERM;

diff -Nru a/drivers/net/tg3.h b/drivers/net/tg3.h
--- a/drivers/net/tg3.h	Mon Jul 19 11:05:33 2004
+++ b/drivers/net/tg3.h	Mon Jul 19 11:05:33 2004
@@ -1,8 +1,9 @@
 /* $Id: tg3.h,v 1.37.2.32 2002/03/11 12:18:18 davem Exp $
  * tg3.h: Definitions for Broadcom Tigon3 ethernet driver.
  *
- * Copyright (C) 2001, 2002 David S. Miller (davem at redhat.com)
+ * Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem at redhat.com)
  * Copyright (C) 2001 Jeff Garzik (jgarzik at pobox.com)
+ * Copyright (C) 2004 Sun Microsystems Inc.
  */

 #ifndef _T3_H
@@ -116,6 +117,7 @@
 #define  CHIPREV_ID_5704_A0		 0x2000
 #define  CHIPREV_ID_5704_A1		 0x2001
 #define  CHIPREV_ID_5704_A2		 0x2002
+#define  CHIPREV_ID_5704_A3		 0x2003
 #define  CHIPREV_ID_5705_A0		 0x3000
 #define  CHIPREV_ID_5705_A1		 0x3001
 #define  CHIPREV_ID_5705_A2		 0x3002
@@ -518,8 +520,50 @@
 #define MAC_EXTADDR_11_HIGH		0x00000588
 #define MAC_EXTADDR_11_LOW		0x0000058c
 #define MAC_SERDES_CFG			0x00000590
+#define  MAC_SERDES_CFG_EDGE_SELECT	 0x00001000
 #define MAC_SERDES_STAT			0x00000594
-/* 0x598 --> 0x600 unused */
+/* 0x598 --> 0x5b0 unused */
+#define SG_DIG_CTRL			0x000005b0
+#define  SG_DIG_USING_HW_AUTONEG	 0x80000000
+#define  SG_DIG_SOFT_RESET		 0x40000000
+#define  SG_DIG_DISABLE_LINKRDY		 0x20000000
+#define  SG_DIG_CRC16_CLEAR_N		 0x01000000
+#define  SG_DIG_EN10B			 0x00800000
+#define  SG_DIG_CLEAR_STATUS		 0x00400000
+#define  SG_DIG_LOCAL_DUPLEX_STATUS	 0x00200000
+#define  SG_DIG_LOCAL_LINK_STATUS	 0x00100000
+#define  SG_DIG_SPEED_STATUS_MASK	 0x000c0000
+#define  SG_DIG_SPEED_STATUS_SHIFT	 18
+#define  SG_DIG_JUMBO_PACKET_DISABLE	 0x00020000
+#define  SG_DIG_RESTART_AUTONEG		 0x00010000
+#define  SG_DIG_FIBER_MODE		 0x00008000
+#define  SG_DIG_REMOTE_FAULT_MASK	 0x00006000
+#define  SG_DIG_PAUSE_MASK		 0x00001800
+#define  SG_DIG_GBIC_ENABLE		 0x00000400
+#define  SG_DIG_CHECK_END_ENABLE	 0x00000200
+#define  SG_DIG_SGMII_AUTONEG_TIMER	 0x00000100
+#define  SG_DIG_CLOCK_PHASE_SELECT	 0x00000080
+#define  SG_DIG_GMII_INPUT_SELECT	 0x00000040
+#define  SG_DIG_MRADV_CRC16_SELECT	 0x00000020
+#define  SG_DIG_COMMA_DETECT_ENABLE	 0x00000010
+#define  SG_DIG_AUTONEG_TIMER_REDUCE	 0x00000008
+#define  SG_DIG_AUTONEG_LOW_ENABLE	 0x00000004
+#define  SG_DIG_REMOTE_LOOPBACK		 0x00000002
+#define  SG_DIG_LOOPBACK		 0x00000001
+#define SG_DIG_STATUS			0x000005b4
+#define  SG_DIG_CRC16_BUS_MASK		 0xffff0000
+#define  SG_DIG_PARTNER_FAULT_MASK	 0x00600000 /* If !MRADV_CRC16_SELECT */
+#define  SG_DIG_PARTNER_ASYM_PAUSE	 0x00100000 /* If !MRADV_CRC16_SELECT */
+#define  SG_DIG_PARTNER_PAUSE_CAPABLE	 0x00080000 /* If !MRADV_CRC16_SELECT */
+#define  SG_DIG_PARTNER_HALF_DUPLEX	 0x00040000 /* If !MRADV_CRC16_SELECT */
+#define  SG_DIG_PARTNER_FULL_DUPLEX	 0x00020000 /* If !MRADV_CRC16_SELECT */
+#define  SG_DIG_PARTNER_NEXT_PAGE	 0x00010000 /* If !MRADV_CRC16_SELECT */
+#define  SG_DIG_AUTONEG_STATE_MASK	 0x00000ff0
+#define  SG_DIG_COMMA_DETECTOR		 0x00000008
+#define  SG_DIG_MAC_ACK_STATUS		 0x00000004
+#define  SG_DIG_AUTONEG_COMPLETE	 0x00000002
+#define  SG_DIG_AUTONEG_ERROR		 0x00000001
+/* 0x5b8 --> 0x600 unused */
 #define MAC_TX_MAC_STATE_BASE		0x00000600 /* 16 bytes */
 #define MAC_RX_MAC_STATE_BASE		0x00000610 /* 20 bytes */
 /* 0x624 --> 0x800 unused */
@@ -2044,6 +2088,7 @@
 #define TG3_FLG2_PHY_BER_BUG		0x00000100
 #define TG3_FLG2_PCI_EXPRESS		0x00000200
 #define TG3_FLG2_ASF_NEW_HANDSHAKE	0x00000400
+#define TG3_FLG2_HW_AUTONEG		0x00000800

 	u32				split_mode_max_reqs;
 #define SPLIT_MODE_5704_MAX_REQ		3

** Sent via the linuxppc64-dev mail list. See http://lists.linuxppc.org/





More information about the Linuxppc64-dev mailing list