diff options
author | Stephen Hemminger <shemminger@osdl.org> | 2006-12-04 18:53:45 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-12-07 04:58:33 -0500 |
commit | 6771290102c4703dae56bc3e121deb63530e206c (patch) | |
tree | 16d527afee24ae84b14b3083b91517584fe46c84 /drivers/net/sky2.c | |
parent | e5b74c7ddd46d1779bea21d7c8efb39bbcc3df21 (diff) |
[PATCH] sky2: beter ram buffer partitioning
Different chips have different sizes of ram buffers, and some versions have
no ram buffer at all!. Be more careful about sizing the ram usage because
it maybe a problem if vendor keeps changing sizes.
There is the (unlikely) possibility that some of the errors on some of the
chips have been caused by partitioning not on a 1K boundary.
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r-- | drivers/net/sky2.c | 41 |
1 files changed, 25 insertions, 16 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index b1df594fdf56..b9f7eb5453f1 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -696,10 +696,15 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) | |||
696 | 696 | ||
697 | } | 697 | } |
698 | 698 | ||
699 | /* Assign Ram Buffer allocation in units of 64bit (8 bytes) */ | 699 | /* Assign Ram Buffer allocation to queue */ |
700 | static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, u32 end) | 700 | static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, u32 space) |
701 | { | 701 | { |
702 | pr_debug(PFX "q %d %#x %#x\n", q, start, end); | 702 | u32 end; |
703 | |||
704 | /* convert from K bytes to qwords used for hw register */ | ||
705 | start *= 1024/8; | ||
706 | space *= 1024/8; | ||
707 | end = start + space - 1; | ||
703 | 708 | ||
704 | sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR); | 709 | sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR); |
705 | sky2_write32(hw, RB_ADDR(q, RB_START), start); | 710 | sky2_write32(hw, RB_ADDR(q, RB_START), start); |
@@ -708,7 +713,6 @@ static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, u32 end) | |||
708 | sky2_write32(hw, RB_ADDR(q, RB_RP), start); | 713 | sky2_write32(hw, RB_ADDR(q, RB_RP), start); |
709 | 714 | ||
710 | if (q == Q_R1 || q == Q_R2) { | 715 | if (q == Q_R1 || q == Q_R2) { |
711 | u32 space = end - start + 1; | ||
712 | u32 tp = space - space/4; | 716 | u32 tp = space - space/4; |
713 | 717 | ||
714 | /* On receive queue's set the thresholds | 718 | /* On receive queue's set the thresholds |
@@ -1138,7 +1142,7 @@ static int sky2_up(struct net_device *dev) | |||
1138 | struct sky2_port *sky2 = netdev_priv(dev); | 1142 | struct sky2_port *sky2 = netdev_priv(dev); |
1139 | struct sky2_hw *hw = sky2->hw; | 1143 | struct sky2_hw *hw = sky2->hw; |
1140 | unsigned port = sky2->port; | 1144 | unsigned port = sky2->port; |
1141 | u32 ramsize, rxspace, imask; | 1145 | u32 ramsize, imask; |
1142 | int cap, err = -ENOMEM; | 1146 | int cap, err = -ENOMEM; |
1143 | struct net_device *otherdev = hw->dev[sky2->port^1]; | 1147 | struct net_device *otherdev = hw->dev[sky2->port^1]; |
1144 | 1148 | ||
@@ -1191,20 +1195,25 @@ static int sky2_up(struct net_device *dev) | |||
1191 | 1195 | ||
1192 | sky2_mac_init(hw, port); | 1196 | sky2_mac_init(hw, port); |
1193 | 1197 | ||
1194 | /* Determine available ram buffer space in qwords. */ | 1198 | /* Register is number of 4K blocks on internal RAM buffer. */ |
1195 | ramsize = sky2_read8(hw, B2_E_0) * 4096/8; | 1199 | ramsize = sky2_read8(hw, B2_E_0) * 4; |
1200 | printk(KERN_INFO PFX "%s: ram buffer %dK\n", dev->name, ramsize); | ||
1196 | 1201 | ||
1197 | if (ramsize > 6*1024/8) | 1202 | if (ramsize > 0) { |
1198 | rxspace = ramsize - (ramsize + 2) / 3; | 1203 | u32 rxspace; |
1199 | else | ||
1200 | rxspace = ramsize / 2; | ||
1201 | 1204 | ||
1202 | sky2_ramset(hw, rxqaddr[port], 0, rxspace-1); | 1205 | if (ramsize < 16) |
1203 | sky2_ramset(hw, txqaddr[port], rxspace, ramsize-1); | 1206 | rxspace = ramsize / 2; |
1207 | else | ||
1208 | rxspace = 8 + (2*(ramsize - 16))/3; | ||
1204 | 1209 | ||
1205 | /* Make sure SyncQ is disabled */ | 1210 | sky2_ramset(hw, rxqaddr[port], 0, rxspace); |
1206 | sky2_write8(hw, RB_ADDR(port == 0 ? Q_XS1 : Q_XS2, RB_CTRL), | 1211 | sky2_ramset(hw, txqaddr[port], rxspace, ramsize - rxspace); |
1207 | RB_RST_SET); | 1212 | |
1213 | /* Make sure SyncQ is disabled */ | ||
1214 | sky2_write8(hw, RB_ADDR(port == 0 ? Q_XS1 : Q_XS2, RB_CTRL), | ||
1215 | RB_RST_SET); | ||
1216 | } | ||
1208 | 1217 | ||
1209 | sky2_qset(hw, txqaddr[port]); | 1218 | sky2_qset(hw, txqaddr[port]); |
1210 | 1219 | ||