aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@osdl.org>2006-01-17 16:43:13 -0500
committerJeff Garzik <jgarzik@pobox.com>2006-01-17 19:27:29 -0500
commit1c28f6ba600d05be2dc7ab0592e4d845f668a485 (patch)
tree4dab29ea4d4d83588ef478ac34d5f99961416b45 /drivers
parente0c94455ce2a0e5734eeb236fb49a4613e20e7b0 (diff)
[PATCH] sky2: fix ram buffer for Yukon FE rev 2
Fix problems with Yukon FE rev 2 chipset. Don't cut and paste bugs in from sk98lin driver. Change how the ram buffer is divided up, and make the math clearer. Also, set the thresholds where rx takes precedence. The threshold values are just guesses at this point, it might be worth tuning them later. Signed-off-by: Stephen Hemminger <shemminger@osdl.org> Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/sky2.c52
1 files changed, 30 insertions, 22 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index f68ccfbffff3..178249a96e1c 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -625,13 +625,16 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
625 625
626} 626}
627 627
628static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, size_t len) 628/* Assign Ram Buffer allocation.
629 * start and end are in units of 4k bytes
630 * ram registers are in units of 64bit words
631 */
632static void sky2_ramset(struct sky2_hw *hw, u16 q, u8 startk, u8 endk)
629{ 633{
630 u32 end; 634 u32 start, end;
631 635
632 start /= 8; 636 start = startk * 4096/8;
633 len /= 8; 637 end = (endk * 4096/8) - 1;
634 end = start + len - 1;
635 638
636 sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR); 639 sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR);
637 sky2_write32(hw, RB_ADDR(q, RB_START), start); 640 sky2_write32(hw, RB_ADDR(q, RB_START), start);
@@ -640,14 +643,19 @@ static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, size_t len)
640 sky2_write32(hw, RB_ADDR(q, RB_RP), start); 643 sky2_write32(hw, RB_ADDR(q, RB_RP), start);
641 644
642 if (q == Q_R1 || q == Q_R2) { 645 if (q == Q_R1 || q == Q_R2) {
643 u32 rxup, rxlo; 646 u32 space = (endk - startk) * 4096/8;
647 u32 tp = space - space/4;
644 648
645 rxlo = len/2; 649 /* On receive queue's set the thresholds
646 rxup = rxlo + len/4; 650 * give receiver priority when > 3/4 full
651 * send pause when down to 2K
652 */
653 sky2_write32(hw, RB_ADDR(q, RB_RX_UTHP), tp);
654 sky2_write32(hw, RB_ADDR(q, RB_RX_LTHP), space/2);
647 655
648 /* Set thresholds on receive queue's */ 656 tp = space - 2048/8;
649 sky2_write32(hw, RB_ADDR(q, RB_RX_UTPP), rxup); 657 sky2_write32(hw, RB_ADDR(q, RB_RX_UTPP), tp);
650 sky2_write32(hw, RB_ADDR(q, RB_RX_LTPP), rxlo); 658 sky2_write32(hw, RB_ADDR(q, RB_RX_LTPP), space/4);
651 } else { 659 } else {
652 /* Enable store & forward on Tx queue's because 660 /* Enable store & forward on Tx queue's because
653 * Tx FIFO is only 1K on Yukon 661 * Tx FIFO is only 1K on Yukon
@@ -1002,19 +1010,19 @@ static int sky2_up(struct net_device *dev)
1002 1010
1003 sky2_mac_init(hw, port); 1011 sky2_mac_init(hw, port);
1004 1012
1005 /* Configure RAM buffers */ 1013 /* Determine available ram buffer space (in 4K blocks).
1006 if (hw->chip_id == CHIP_ID_YUKON_FE || 1014 * Note: not sure about the FE setting below yet
1007 (hw->chip_id == CHIP_ID_YUKON_EC && hw->chip_rev == 2)) 1015 */
1008 ramsize = 4096; 1016 if (hw->chip_id == CHIP_ID_YUKON_FE)
1009 else { 1017 ramsize = 4;
1010 u8 e0 = sky2_read8(hw, B2_E_0); 1018 else
1011 ramsize = (e0 == 0) ? (128 * 1024) : (e0 * 4096); 1019 ramsize = sky2_read8(hw, B2_E_0);
1012 } 1020
1021 /* Give transmitter one third (rounded up) */
1022 rxspace = ramsize - (ramsize + 2) / 3;
1013 1023
1014 /* 2/3 for Rx */
1015 rxspace = (2 * ramsize) / 3;
1016 sky2_ramset(hw, rxqaddr[port], 0, rxspace); 1024 sky2_ramset(hw, rxqaddr[port], 0, rxspace);
1017 sky2_ramset(hw, txqaddr[port], rxspace, ramsize - rxspace); 1025 sky2_ramset(hw, txqaddr[port], rxspace, ramsize);
1018 1026
1019 /* Make sure SyncQ is disabled */ 1027 /* Make sure SyncQ is disabled */
1020 sky2_write8(hw, RB_ADDR(port == 0 ? Q_XS1 : Q_XS2, RB_CTRL), 1028 sky2_write8(hw, RB_ADDR(port == 0 ? Q_XS1 : Q_XS2, RB_CTRL),