[patch 08/16] skge: fix ram buffer size calculation

!MAILaRCHIVE_VOTE_RePLACE
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
To: <linux-kernel@...>, <stable@...>
Cc: Justin Forbes <jmforbes@...>, Zwane Mwaikambo <zwane@...>, Theodore Ts'o <tytso@...>, Randy Dunlap <rdunlap@...>, Dave Jones <davej@...>, Chuck Wolber <chuckw@...>, Chris Wedgwood <reviews@...>, Michael Krufky <mkrufky@...>, Chuck Ebbert <cebbert@...>, Domenico Andreoli <cavokz@...>, <torvalds@...>, <akpm@...>, <alan@...>, Stephen Hemminger <shemminger@...>, Jeff Garzik <jeff@...>
Date: Thursday, November 15, 2007 - 2:40 am

-stable review patch.  If anyone has any objections, please let us know.

------------------
From: Stephen Hemminger <shemminger@linux-foundation.org>

patch 7fb7ac241162dc51ec0f7644d4a97b2855213c32 in mainline.

This fixes problems with transmit hangs on older fiber based SysKonnect boards.

Adjust ram buffer sizing calculation to make it correct on all boards
and make it like the code in sky2 driver.

Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: Jeff Garzik <jeff@garzik.org>

---
 drivers/net/skge.c |   51 ++++++++++++++++++++++++---------------------------
 1 file changed, 24 insertions(+), 27 deletions(-)

--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -2400,32 +2400,31 @@ static int skge_ioctl(struct net_device 
 	return err;
 }
 
-static void skge_ramset(struct skge_hw *hw, u16 q, u32 start, size_t len)
+/* Assign Ram Buffer allocation to queue */
+static void skge_ramset(struct skge_hw *hw, u16 q, u32 start, u32 space)
 {
 	u32 end;
 
-	start /= 8;
-	len /= 8;
-	end = start + len - 1;
+	/* convert from K bytes to qwords used for hw register */
+	start *= 1024/8;
+	space *= 1024/8;
+	end = start + space - 1;
 
 	skge_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR);
 	skge_write32(hw, RB_ADDR(q, RB_START), start);
+	skge_write32(hw, RB_ADDR(q, RB_END), end);
 	skge_write32(hw, RB_ADDR(q, RB_WP), start);
 	skge_write32(hw, RB_ADDR(q, RB_RP), start);
-	skge_write32(hw, RB_ADDR(q, RB_END), end);
 
 	if (q == Q_R1 || q == Q_R2) {
+		u32 tp = space - space/4;
+
 		/* Set thresholds on receive queue's */
-		skge_write32(hw, RB_ADDR(q, RB_RX_UTPP),
-			     start + (2*len)/3);
-		skge_write32(hw, RB_ADDR(q, RB_RX_LTPP),
-			     start + (len/3));
-	} else {
-		/* Enable store & forward on Tx queue's because
-		 * Tx FIFO is only 4K on Genesis and 1K on Yukon
-		 */
+		skge_write32(hw, RB_ADDR(q, RB_RX_UTPP), tp);
+		skge_write32(hw, RB_ADDR(q, RB_RX_LTPP), space/4);
+	} else if (hw->chip_id != CHIP_ID_GENESIS)
+		/* Genesis Tx Fifo is too small for normal store/forward */
 		skge_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_STFWD);
-	}
 
 	skge_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_OP_MD);
 }
@@ -2453,7 +2452,7 @@ static int skge_up(struct net_device *de
 	struct skge_port *skge = netdev_priv(dev);
 	struct skge_hw *hw = skge->hw;
 	int port = skge->port;
-	u32 chunk, ram_addr;
+	u32 ramaddr, ramsize, rxspace;
 	size_t rx_size, tx_size;
 	int err;
 
@@ -2508,14 +2507,15 @@ static int skge_up(struct net_device *de
 	spin_unlock_bh(&hw->phy_lock);
 
 	/* Configure RAMbuffers */
-	chunk = hw->ram_size / ((hw->ports + 1)*2);
-	ram_addr = hw->ram_offset + 2 * chunk * port;
+	ramsize = (hw->ram_size - hw->ram_offset) / hw->ports;
+	ramaddr = hw->ram_offset + port * ramsize;
+	rxspace = 8 + (2*(ramsize - 16))/3;
 
-	skge_ramset(hw, rxqaddr[port], ram_addr, chunk);
-	skge_qset(skge, rxqaddr[port], skge->rx_ring.to_clean);
+	skge_ramset(hw, rxqaddr[port], ramaddr, rxspace);
+	skge_ramset(hw, txqaddr[port], ramaddr + rxspace, ramsize - rxspace);
 
+	skge_qset(skge, rxqaddr[port], skge->rx_ring.to_clean);
 	BUG_ON(skge->tx_ring.to_use != skge->tx_ring.to_clean);
-	skge_ramset(hw, txqaddr[port], ram_addr+chunk, chunk);
 	skge_qset(skge, txqaddr[port], skge->tx_ring.to_use);
 
 	/* Start receiver BMU */
@@ -3450,15 +3450,12 @@ static int skge_reset(struct skge_hw *hw
 	if (hw->chip_id == CHIP_ID_GENESIS) {
 		if (t8 == 3) {
 			/* special case: 4 x 64k x 36, offset = 0x80000 */
-			hw->ram_size = 0x100000;
-			hw->ram_offset = 0x80000;
+			hw->ram_size = 1024;
+			hw->ram_offset = 512;
 		} else
 			hw->ram_size = t8 * 512;
-	}
-	else if (t8 == 0)
-		hw->ram_size = 0x20000;
-	else
-		hw->ram_size = t8 * 4096;
+	} else /* Yukon */
+		hw->ram_size = t8 ? t8 * 4 : 128;
 
 	hw->intr_mask = IS_HW_ERR;
 

-- 
-
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
[patch 14/16] ipw2100: send WEXT scan events, Greg KH, (Thu Nov 15, 2:41 am)
[patch 09/16] skge: XM PHY handling fixes, Greg KH, (Thu Nov 15, 2:40 am)
[patch 10/16] sky2: status ring race fix, Greg KH, (Thu Nov 15, 2:40 am)
[patch 03/16] ehea: 64K page kernel support fix, Greg KH, (Thu Nov 15, 2:40 am)
[patch 08/16] skge: fix ram buffer size calculation, Greg KH, (Thu Nov 15, 2:40 am)
Re: [patch 08/16] skge: fix ram buffer size calculation, Linus Torvalds, (Thu Nov 15, 12:11 pm)
Re: [patch 08/16] skge: fix ram buffer size calculation, Linus Torvalds, (Thu Nov 15, 12:48 pm)
Re: [patch 08/16] skge: fix ram buffer size calculation, Heikki Orsila, (Fri Nov 16, 5:03 pm)
Re: [patch 08/16] skge: fix ram buffer size calculation, Stephen Hemminger, (Thu Nov 15, 12:27 pm)
Re: [patch 08/16] skge: fix ram buffer size calculation, Heikki Orsila, (Thu Nov 15, 5:57 pm)
Re: [patch 08/16] skge: fix ram buffer size calculation, Linus Torvalds, (Thu Nov 15, 12:50 pm)
[patch 04/16] forcedeth msi bugfix, Greg KH, (Thu Nov 15, 2:40 am)
[patch 07/16] Fix L2TP oopses., Greg KH, (Thu Nov 15, 2:40 am)
[patch 05/16] forcedeth: add MCP77 device IDs, Greg KH, (Thu Nov 15, 2:40 am)
[patch 02/16] libertas: fix endianness breakage, Greg KH, (Thu Nov 15, 2:39 am)
[patch 01/16] libertas: more endianness breakage, Greg KH, (Thu Nov 15, 2:39 am)