Skip to contentSkip to conversation

skge update (for 2.6.24)

PATCH In review Stephen Hemminger 2 participants 10 messages Nov 26, 2007 – Dec 1, 2007

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

cover skge update (for 2.6.24)

This resolves the skge problems that show up on dual ported and fiber attached boards. These fixes have been validated by the users that reported regressions with earlier patches.

Signature · 1 line
Stephen Hemminger <[email protected]>
#1 lore raw

PATCH 1/6 skge: FIFO Ram calculation error

The calculation of usable FIFO RAM is wrong in the skge driver. First, is doesn't take into account the reserved area on the original SysKonnect Genesis boards. Second it has an off-by-one error because hw->ports is either 1 or 2.

drivers/net/skge.c +2 -2
@@ -2619,8 +2619,8 @@ static int skge_up(struct net_device *de
 		yukon_mac_init(hw, port);
 	spin_unlock_bh(&hw->phy_lock);
 
-	/* Configure RAMbuffers */
-	chunk = hw->ram_size / ((hw->ports + 1)*2);
+	/* Configure RAMbuffers - equally between ports and tx/rx */
+	chunk = (hw->ram_size  - hw->ram_offset) / (hw->ports * 2);
 	ram_addr = hw->ram_offset + 2 * chunk * port;
 
 	skge_ramset(hw, rxqaddr[port], ram_addr, chunk);
Signature · 1 line
Stephen Hemminger <[email protected]>
#2 lore raw

Re: [PATCH 1/6] skge: FIFO Ram calculation error

applied 1-6 and additional 1-2

#3 lore raw

PATCH 2/6 skge: receive flush logic

In reply to Stephen Hemminger

Receive FIFO overrun is not catastrophic condition, so don't flush when it happens.

drivers/net/skge.c +2 -7
@@ -1801,11 +1801,6 @@ static void genesis_mac_intr(struct skge
 		xm_write32(hw, port, XM_MODE, XM_MD_FTF);
 		++dev->stats.tx_fifo_errors;
 	}
-
-	if (status & XM_IS_RXF_OV) {
-		xm_write32(hw, port, XM_MODE, XM_MD_FRF);
-		++dev->stats.rx_fifo_errors;
-	}
 }
 
 static void genesis_link_up(struct skge_port *skge)
@@ -1862,9 +1857,9 @@ static void genesis_link_up(struct skge_
 
 	xm_write32(hw, port, XM_MODE, mode);
 
-	/* Turn on detection of Tx underrun, Rx overrun */
+	/* Turn on detection of Tx underrun */
 	msk = xm_read16(hw, port, XM_IMSK);
-	msk &= ~(XM_IS_RXF_OV | XM_IS_TXF_UR);
+	msk &= ~XM_IS_TXF_UR;
 	xm_write16(hw, port, XM_IMSK, msk);
 
 	xm_read16(hw, port, XM_ISRC);
Signature · 1 line
Stephen Hemminger <[email protected]>
#4 lore raw

PATCH 3/6 skge: retry on MAC shutdown

In reply to Stephen Hemminger

Make sure and retry when shutting down the MAC. This code is copied from sk98lin driver.

drivers/net/skge.c +8 -11
@@ -1713,7 +1713,7 @@ static void genesis_stop(struct skge_por
 {
 	struct skge_hw *hw = skge->hw;
 	int port = skge->port;
-	u32 reg;
+	unsigned retries = 1000;
 
 	genesis_reset(hw, port);
 
@@ -1721,20 +1721,17 @@ static void genesis_stop(struct skge_por
 	skge_write16(hw, B3_PA_CTRL,
 		     port == 0 ? PA_CLR_TO_TX1 : PA_CLR_TO_TX2);
 
-	/*
-	 * If the transfer sticks at the MAC the STOP command will not
-	 * terminate if we don't flush the XMAC's transmit FIFO !
-	 */
-	xm_write32(hw, port, XM_MODE,
-			xm_read32(hw, port, XM_MODE)|XM_MD_FTF);
-
-
 	/* Reset the MAC */
-	skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_SET_MAC_RST);
+	skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_CLR_MAC_RST);
+	do {
+		skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_SET_MAC_RST);
+		if (!(skge_read16(hw, SK_REG(port, TX_MFF_CTRL1)) & MFF_SET_MAC_RST))
+			break;
+	} while (--retries > 0);
 
 	/* For external PHYs there must be special handling */
 	if (hw->phy_type != SK_PHY_XMAC) {
-		reg = skge_read32(hw, B2_GP_IO);
+		u32 reg = skge_read32(hw, B2_GP_IO);
 		if (port == 0) {
 			reg |= GP_DIR_0;
 			reg &= ~GP_IO_0;
Signature · 1 line
Stephen Hemminger <[email protected]>
#5 lore raw

PATCH 4/6 skge: fiber link up/down fix

In reply to Stephen Hemminger

The driver would not work over fibre if other end when down then came back up (would require reloading driver). The correct way to manage the link the same way for both TP and fibre.

Resloves problem described in: http://lkml.org/lkml/2007/11/6/395

drivers/net/skge.c +12 -7
@@ -1095,16 +1095,9 @@ static void xm_link_down(struct skge_hw 
 {
 	struct net_device *dev = hw->dev[port];
 	struct skge_port *skge = netdev_priv(dev);
-	u16 cmd = xm_read16(hw, port, XM_MMU_CMD);
 
 	xm_write16(hw, port, XM_IMSK, XM_IMSK_DISABLE);
 
-	cmd &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX);
-	xm_write16(hw, port, XM_MMU_CMD, cmd);
-
-	/* dummy read to ensure writing */
-	xm_read16(hw, port, XM_MMU_CMD);
-
 	if (netif_carrier_ok(dev))
 		skge_link_down(skge);
 }
@@ -1194,6 +1187,7 @@ static void genesis_init(struct skge_hw 
 static void genesis_reset(struct skge_hw *hw, int port)
 {
 	const u8 zero[8]  = { 0 };
+	u32 reg;
 
 	skge_write8(hw, SK_REG(port, GMAC_IRQ_MSK), 0);
 
@@ -1209,6 +1203,11 @@ static void genesis_reset(struct skge_hw
 		xm_write16(hw, port, PHY_BCOM_INT_MASK, 0xffff);
 
 	xm_outhash(hw, port, XM_HSM, zero);
+
+	/* Flush TX and RX fifo */
+	reg = xm_read32(hw, port, XM_MODE);
+	xm_write32(hw, port, XM_MODE, reg | XM_MD_FTF);
+	xm_write32(hw, port, XM_MODE, reg | XM_MD_FRF);
 }
 
 
@@ -1714,6 +1713,12 @@ static void genesis_stop(struct skge_por
 	struct skge_hw *hw = skge->hw;
 	int port = skge->port;
 	unsigned retries = 1000;
+	u16 cmd;
+
+ 	/* Disable Tx and Rx */
+	cmd = xm_read16(hw, port, XM_MMU_CMD);
+	cmd &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX);
+	xm_write16(hw, port, XM_MMU_CMD, cmd);
 
 	genesis_reset(hw, port);
 
Signature · 1 line
Stephen Hemminger <[email protected]>
#6 lore raw

PATCH 5/6 skge: increase TX threshold for Jumbo

In reply to Stephen Hemminger

Need to increase TX threshold when doing Jumbo frames on dual port board to avoid underruns. (Code from sk98lin).

drivers/net/skge.c +5 -6
@@ -1633,15 +1633,14 @@ static void genesis_mac_init(struct skge
 	}
 	xm_write16(hw, port, XM_RX_CMD, r);
 
-
 	/* We want short frames padded to 60 bytes. */
 	xm_write16(hw, port, XM_TX_CMD, XM_TX_AUTO_PAD);
 
-	/*
-	 * Bump up the transmit threshold. This helps hold off transmit
-	 * underruns when we're blasting traffic from both ports at once.
-	 */
-	xm_write16(hw, port, XM_TX_THR, 512);
+	/* Increase threshold for jumbo frames on dual port */
+	if (hw->ports > 1 && jumbo)
+		xm_write16(hw, port, XM_TX_THR, 1020);
+	else
+		xm_write16(hw, port, XM_TX_THR, 512);
 
 	/*
 	 * Enable the reception of all error frames. This is is
Signature · 1 line
Stephen Hemminger <[email protected]>
#8 lore raw

PATCH 1/2 skge: serial mode register values

For compatiablity with sk98lin, make sure and set same values in serial mode register.

---
Please apply for 2.6.24 (upstream-fixes) after the previous group of skge patches (1.13)

drivers/net/skge.c +6 -3
@@ -2190,9 +2190,12 @@ static void yukon_mac_init(struct skge_h
 			 TX_JAM_IPG_VAL(TX_JAM_IPG_DEF) |
 			 TX_IPG_JAM_DATA(TX_IPG_JAM_DEF));
 
-	/* serial mode register */
-	reg = GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF);
-	if (hw->dev[port]->mtu > 1500)
+	/* configure the Serial Mode Register */
+	reg = DATA_BLIND_VAL(DATA_BLIND_DEF)
+		| GM_SMOD_VLAN_ENA
+		| IPG_DATA_VAL(IPG_DATA_DEF);
+
+	if (hw->dev[port]->mtu > ETH_DATA_LEN)
 		reg |= GM_SMOD_JUMBO_ENA;
 
 	gma_write16(hw, port, GM_SERIAL_MODE, reg);
#9 lore raw

PATCH 2/2 skge: MTU changing fix

The code to change MTU doesn't correctly handle all the chip variations and requirements for restarting. On Genesis chips changing MTU would just cause receiver to hang.
Use a simpler approach of just taking link down/up if needed.

---

Please apply to 2.6.24 (upstream-fixes).

drivers/net/skge.c +2 -33
@@ -2896,11 +2896,7 @@ static void skge_tx_timeout(struct net_d
 
 static int skge_change_mtu(struct net_device *dev, int new_mtu)
 {
-	struct skge_port *skge = netdev_priv(dev);
-	struct skge_hw *hw = skge->hw;
-	int port = skge->port;
 	int err;
-	u16 ctl, reg;
 
 	if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU)
 		return -EINVAL;
@@ -2910,40 +2906,13 @@ static int skge_change_mtu(struct net_de
 		return 0;
 	}
 
-	skge_write32(hw, B0_IMSK, 0);
-	dev->trans_start = jiffies;	/* prevent tx timeout */
-	netif_stop_queue(dev);
-	napi_disable(&skge->napi);
-
-	ctl = gma_read16(hw, port, GM_GP_CTRL);
-	gma_write16(hw, port, GM_GP_CTRL, ctl & ~GM_GPCR_RX_ENA);
-
-	skge_rx_clean(skge);
-	skge_rx_stop(hw, port);
+	skge_down(dev);
 
 	dev->mtu = new_mtu;
 
-	reg = GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF);
-	if (new_mtu > 1500)
-		reg |= GM_SMOD_JUMBO_ENA;
-	gma_write16(hw, port, GM_SERIAL_MODE, reg);
-
-	skge_write8(hw, RB_ADDR(rxqaddr[port], RB_CTRL), RB_ENA_OP_MD);
-
-	err = skge_rx_fill(dev);
-	wmb();
-	if (!err)
-		skge_write8(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_START | CSR_IRQ_CL_F);
-	skge_write32(hw, B0_IMSK, hw->intr_mask);
-
+	err = skge_up(dev);
 	if (err)
 		dev_close(dev);
-	else {
-		gma_write16(hw, port, GM_GP_CTRL, ctl);
-
-		napi_enable(&skge->napi);
-		netif_wake_queue(dev);
-	}
 
 	return err;
 }