Revert "skge: fix ram buffer size calculation"

This reverts commit 7fb7ac2411.

Heikki Orsila reports that it causes a regression:

  "Doing

	nc host port < /dev/zero

   on a sending machine (not skge) to an skge machine that is receiving:

	nc -l -p port >/dev/null

   with ~60 MiB/s speed, causes the interface go malfunct. A slow
   transfer doesn't cause a problem."

See

	http://bugzilla.kernel.org/show_bug.cgi?id=9321

for some more information.

There is a workaround (also reported by Heikki):

  "After some fiddling, I noticed that not changing the register write
   order on patch:

   +       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);

   fixes the visible effect..  Possibly not the root cause of the
   problem, but changing the order back fixes networking here."

but that has yet to be ack'ed or tested more widely, so the whole
problem-causing commit gets reverted until this is resolved properly.

Bisected-and-requested-by: Heikki Orsila <shdl@zakalwe.fi>
Cc: Stephen Hemminger <shemminger@linux-foundation.org>
Cc: Jeff Garzik <jeff@garzik.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Linus Torvalds 2007-11-15 08:44:36 -08:00
parent 8cc91677ae
commit 279e1dab94

View file

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