aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@osdl.org>2006-12-04 18:53:45 -0500
committerJeff Garzik <jeff@garzik.org>2006-12-07 04:58:33 -0500
commit6771290102c4703dae56bc3e121deb63530e206c (patch)
tree16d527afee24ae84b14b3083b91517584fe46c84
parente5b74c7ddd46d1779bea21d7c8efb39bbcc3df21 (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>
-rw-r--r--drivers/net/sky2.c41
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 */
700static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, u32 end) 700static 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