Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

+27 -24
+27 -24
drivers/net/skge.c
··· 2512 2512 return err; 2513 2513 } 2514 2514 2515 - /* Assign Ram Buffer allocation to queue */ 2516 - static void skge_ramset(struct skge_hw *hw, u16 q, u32 start, u32 space) 2515 + static void skge_ramset(struct skge_hw *hw, u16 q, u32 start, size_t len) 2517 2516 { 2518 2517 u32 end; 2519 2518 2520 - /* convert from K bytes to qwords used for hw register */ 2521 - start *= 1024/8; 2522 - space *= 1024/8; 2523 - end = start + space - 1; 2519 + start /= 8; 2520 + len /= 8; 2521 + end = start + len - 1; 2524 2522 2525 2523 skge_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR); 2526 2524 skge_write32(hw, RB_ADDR(q, RB_START), start); 2527 - skge_write32(hw, RB_ADDR(q, RB_END), end); 2528 2525 skge_write32(hw, RB_ADDR(q, RB_WP), start); 2529 2526 skge_write32(hw, RB_ADDR(q, RB_RP), start); 2527 + skge_write32(hw, RB_ADDR(q, RB_END), end); 2530 2528 2531 2529 if (q == Q_R1 || q == Q_R2) { 2532 - u32 tp = space - space/4; 2533 - 2534 2530 /* Set thresholds on receive queue's */ 2535 - skge_write32(hw, RB_ADDR(q, RB_RX_UTPP), tp); 2536 - skge_write32(hw, RB_ADDR(q, RB_RX_LTPP), space/4); 2537 - } else if (hw->chip_id != CHIP_ID_GENESIS) 2538 - /* Genesis Tx Fifo is too small for normal store/forward */ 2531 + skge_write32(hw, RB_ADDR(q, RB_RX_UTPP), 2532 + start + (2*len)/3); 2533 + skge_write32(hw, RB_ADDR(q, RB_RX_LTPP), 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 2539 skge_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_STFWD); 2540 + } 2540 2541 2541 2542 skge_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_OP_MD); 2542 2543 } ··· 2565 2564 struct skge_port *skge = netdev_priv(dev); 2566 2565 struct skge_hw *hw = skge->hw; 2567 2566 int port = skge->port; 2568 - u32 ramaddr, ramsize, rxspace; 2567 + u32 chunk, ram_addr; 2569 2568 size_t rx_size, tx_size; 2570 2569 int err; 2571 2570 ··· 2620 2619 spin_unlock_bh(&hw->phy_lock); 2621 2620 2622 2621 /* Configure RAMbuffers */ 2623 - ramsize = (hw->ram_size - hw->ram_offset) / hw->ports; 2624 - ramaddr = hw->ram_offset + port * ramsize; 2625 - rxspace = 8 + (2*(ramsize - 16))/3; 2622 + chunk = hw->ram_size / ((hw->ports + 1)*2); 2623 + ram_addr = hw->ram_offset + 2 * chunk * port; 2626 2624 2627 - skge_ramset(hw, rxqaddr[port], ramaddr, rxspace); 2628 - skge_ramset(hw, txqaddr[port], ramaddr + rxspace, ramsize - rxspace); 2629 - 2625 + skge_ramset(hw, rxqaddr[port], ram_addr, chunk); 2630 2626 skge_qset(skge, rxqaddr[port], skge->rx_ring.to_clean); 2627 + 2631 2628 BUG_ON(skge->tx_ring.to_use != skge->tx_ring.to_clean); 2629 + skge_ramset(hw, txqaddr[port], ram_addr+chunk, chunk); 2632 2630 skge_qset(skge, txqaddr[port], skge->tx_ring.to_use); 2633 2631 2634 2632 /* Start receiver BMU */ ··· 3591 3591 if (hw->chip_id == CHIP_ID_GENESIS) { 3592 3592 if (t8 == 3) { 3593 3593 /* special case: 4 x 64k x 36, offset = 0x80000 */ 3594 - hw->ram_size = 1024; 3595 - hw->ram_offset = 512; 3594 + hw->ram_size = 0x100000; 3595 + hw->ram_offset = 0x80000; 3596 3596 } else 3597 3597 hw->ram_size = t8 * 512; 3598 - } else /* Yukon */ 3599 - hw->ram_size = t8 ? t8 * 4 : 128; 3598 + } 3599 + else if (t8 == 0) 3600 + hw->ram_size = 0x20000; 3601 + else 3602 + hw->ram_size = t8 * 4096; 3600 3603 3601 3604 hw->intr_mask = IS_HW_ERR; 3602 3605