aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-11-15 11:44:36 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-11-15 11:44:36 -0500
commit279e1dab949d33737557babfe9f74e0b74fbe39a (patch)
tree42632a4ad59c1b40401b4affa84c8a776f7ea21d /drivers/net
parent8cc91677ae027e15654d7d86a735a7ab6f5c2ec1 (diff)
Revert "skge: fix ram buffer size calculation"
This reverts commit 7fb7ac241162dc51ec0f7644d4a97b2855213c32. 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>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/skge.c51
1 files changed, 27 insertions, 24 deletions
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index b9961dc47606..6d62250fba07 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -2512,31 +2512,32 @@ static int skge_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
2512 return err; 2512 return err;
2513} 2513}
2514 2514
2515/* Assign Ram Buffer allocation to queue */ 2515static void skge_ramset(struct skge_hw *hw, u16 q, u32 start, size_t len)
2516static void skge_ramset(struct skge_hw *hw, u16 q, u32 start, u32 space)
2517{ 2516{
2518 u32 end; 2517 u32 end;
2519 2518
2520 /* convert from K bytes to qwords used for hw register */ 2519 start /= 8;
2521 start *= 1024/8; 2520 len /= 8;
2522 space *= 1024/8; 2521 end = start + len - 1;
2523 end = start + space - 1;
2524 2522
2525 skge_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR); 2523 skge_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR);
2526 skge_write32(hw, RB_ADDR(q, RB_START), start); 2524 skge_write32(hw, RB_ADDR(q, RB_START), start);
2527 skge_write32(hw, RB_ADDR(q, RB_END), end);
2528 skge_write32(hw, RB_ADDR(q, RB_WP), start); 2525 skge_write32(hw, RB_ADDR(q, RB_WP), start);
2529 skge_write32(hw, RB_ADDR(q, RB_RP), start); 2526 skge_write32(hw, RB_ADDR(q, RB_RP), start);
2527 skge_write32(hw, RB_ADDR(q, RB_END), end);
2530 2528
2531 if (q == Q_R1 || q == Q_R2) { 2529 if (q == Q_R1 || q == Q_R2) {
2532 u32 tp = space - space/4;
2533
2534 /* Set thresholds on receive queue's */ 2530 /* Set thresholds on receive queue's */
2535 skge_write32(hw, RB_ADDR(q, RB_RX_UTPP), tp); 2531 skge_write32(hw, RB_ADDR(q, RB_RX_UTPP),
2536 skge_write32(hw, RB_ADDR(q, RB_RX_LTPP), space/4); 2532 start + (2*len)/3);
2537 } else if (hw->chip_id != CHIP_ID_GENESIS) 2533 skge_write32(hw, RB_ADDR(q, RB_RX_LTPP),
2538 /* Genesis Tx Fifo is too small for normal store/forward */ 2534 start + (len/3));
2535 } else {
2536 /* Enable store & forward on Tx queue's because
2537 * Tx FIFO is only 4K on Genesis and 1K on Yukon
2538 */
2539 skge_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_STFWD); 2539 skge_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_STFWD);
2540 }
2540 2541
2541 skge_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_OP_MD); 2542 skge_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_OP_MD);
2542} 2543}
@@ -2564,7 +2565,7 @@ static int skge_up(struct net_device *dev)
2564 struct skge_port *skge = netdev_priv(dev); 2565 struct skge_port *skge = netdev_priv(dev);
2565 struct skge_hw *hw = skge->hw; 2566 struct skge_hw *hw = skge->hw;
2566 int port = skge->port; 2567 int port = skge->port;
2567 u32 ramaddr, ramsize, rxspace; 2568 u32 chunk, ram_addr;
2568 size_t rx_size, tx_size; 2569 size_t rx_size, tx_size;
2569 int err; 2570 int err;
2570 2571
@@ -2619,15 +2620,14 @@ static int skge_up(struct net_device *dev)
2619 spin_unlock_bh(&hw->phy_lock); 2620 spin_unlock_bh(&hw->phy_lock);
2620 2621
2621 /* Configure RAMbuffers */ 2622 /* Configure RAMbuffers */
2622 ramsize = (hw->ram_size - hw->ram_offset) / hw->ports; 2623 chunk = hw->ram_size / ((hw->ports + 1)*2);
2623 ramaddr = hw->ram_offset + port * ramsize; 2624 ram_addr = hw->ram_offset + 2 * chunk * port;
2624 rxspace = 8 + (2*(ramsize - 16))/3;
2625
2626 skge_ramset(hw, rxqaddr[port], ramaddr, rxspace);
2627 skge_ramset(hw, txqaddr[port], ramaddr + rxspace, ramsize - rxspace);
2628 2625
2626 skge_ramset(hw, rxqaddr[port], ram_addr, chunk);
2629 skge_qset(skge, rxqaddr[port], skge->rx_ring.to_clean); 2627 skge_qset(skge, rxqaddr[port], skge->rx_ring.to_clean);
2628
2630 BUG_ON(skge->tx_ring.to_use != skge->tx_ring.to_clean); 2629 BUG_ON(skge->tx_ring.to_use != skge->tx_ring.to_clean);
2630 skge_ramset(hw, txqaddr[port], ram_addr+chunk, chunk);
2631 skge_qset(skge, txqaddr[port], skge->tx_ring.to_use); 2631 skge_qset(skge, txqaddr[port], skge->tx_ring.to_use);
2632 2632
2633 /* Start receiver BMU */ 2633 /* Start receiver BMU */
@@ -3591,12 +3591,15 @@ static int skge_reset(struct skge_hw *hw)
3591 if (hw->chip_id == CHIP_ID_GENESIS) { 3591 if (hw->chip_id == CHIP_ID_GENESIS) {
3592 if (t8 == 3) { 3592 if (t8 == 3) {
3593 /* special case: 4 x 64k x 36, offset = 0x80000 */ 3593 /* special case: 4 x 64k x 36, offset = 0x80000 */
3594 hw->ram_size = 1024; 3594 hw->ram_size = 0x100000;
3595 hw->ram_offset = 512; 3595 hw->ram_offset = 0x80000;
3596 } else 3596 } else
3597 hw->ram_size = t8 * 512; 3597 hw->ram_size = t8 * 512;
3598 } else /* Yukon */ 3598 }
3599 hw->ram_size = t8 ? t8 * 4 : 128; 3599 else if (t8 == 0)
3600 hw->ram_size = 0x20000;
3601 else
3602 hw->ram_size = t8 * 4096;
3600 3603
3601 hw->intr_mask = IS_HW_ERR; 3604 hw->intr_mask = IS_HW_ERR;
3602 3605