aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Hutchings <ben@decadent.org.uk>2010-06-23 09:54:31 -0400
committerDavid S. Miller <davem@davemloft.net>2010-06-29 02:19:18 -0400
commita095cfc40ec7ebe63e9532383c5b5c2a27b14075 (patch)
tree283359a3658ad91b122cd0674bf90b6f9dc0e3d2
parentd2ef8590343f1f236f5f7f070fb4cd3f5c3ffb69 (diff)
3c59x: Specify window explicitly for access to windowed registers
Currently much of the code assumes that a specific window has been selected, while a few functions save and restore the window. This makes it impossible to introduce fine-grained locking. Make those assumptions explicit by introducing wrapper functions to set the window and read/write a register. Use these everywhere except vortex_interrupt(), vortex_start_xmit() and vortex_rx(). These set the window just once, or not at all in the case of vortex_rx() as it should always be called from vortex_interrupt(). Cache the current window in struct vortex_private to avoid unnecessary hardware writes. Signed-off-by: Ben Hutchings <ben@decadent.org.uk> Tested-by: Arne Nordmark <nordmark@mech.kth.se> [against 2.6.32] Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/3c59x.c288
1 files changed, 140 insertions, 148 deletions
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index d75803e6e527..beddef98ad92 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -435,7 +435,6 @@ MODULE_DEVICE_TABLE(pci, vortex_pci_tbl);
435 First the windows. There are eight register windows, with the command 435 First the windows. There are eight register windows, with the command
436 and status registers available in each. 436 and status registers available in each.
437 */ 437 */
438#define EL3WINDOW(win_num) iowrite16(SelectWindow + (win_num), ioaddr + EL3_CMD)
439#define EL3_CMD 0x0e 438#define EL3_CMD 0x0e
440#define EL3_STATUS 0x0e 439#define EL3_STATUS 0x0e
441 440
@@ -647,8 +646,35 @@ struct vortex_private {
647 u16 io_size; /* Size of PCI region (for release_region) */ 646 u16 io_size; /* Size of PCI region (for release_region) */
648 spinlock_t lock; /* Serialise access to device & its vortex_private */ 647 spinlock_t lock; /* Serialise access to device & its vortex_private */
649 struct mii_if_info mii; /* MII lib hooks/info */ 648 struct mii_if_info mii; /* MII lib hooks/info */
649 int window; /* Register window */
650}; 650};
651 651
652static void window_set(struct vortex_private *vp, int window)
653{
654 if (window != vp->window) {
655 iowrite16(SelectWindow + window, vp->ioaddr + EL3_CMD);
656 vp->window = window;
657 }
658}
659
660#define DEFINE_WINDOW_IO(size) \
661static u ## size \
662window_read ## size(struct vortex_private *vp, int window, int addr) \
663{ \
664 window_set(vp, window); \
665 return ioread ## size(vp->ioaddr + addr); \
666} \
667static void \
668window_write ## size(struct vortex_private *vp, u ## size value, \
669 int window, int addr) \
670{ \
671 window_set(vp, window); \
672 iowrite ## size(value, vp->ioaddr + addr); \
673}
674DEFINE_WINDOW_IO(8)
675DEFINE_WINDOW_IO(16)
676DEFINE_WINDOW_IO(32)
677
652#ifdef CONFIG_PCI 678#ifdef CONFIG_PCI
653#define DEVICE_PCI(dev) (((dev)->bus == &pci_bus_type) ? to_pci_dev((dev)) : NULL) 679#define DEVICE_PCI(dev) (((dev)->bus == &pci_bus_type) ? to_pci_dev((dev)) : NULL)
654#else 680#else
@@ -711,7 +737,7 @@ static int vortex_probe1(struct device *gendev, void __iomem *ioaddr, int irq,
711static int vortex_up(struct net_device *dev); 737static int vortex_up(struct net_device *dev);
712static void vortex_down(struct net_device *dev, int final); 738static void vortex_down(struct net_device *dev, int final);
713static int vortex_open(struct net_device *dev); 739static int vortex_open(struct net_device *dev);
714static void mdio_sync(void __iomem *ioaddr, int bits); 740static void mdio_sync(struct vortex_private *vp, int bits);
715static int mdio_read(struct net_device *dev, int phy_id, int location); 741static int mdio_read(struct net_device *dev, int phy_id, int location);
716static void mdio_write(struct net_device *vp, int phy_id, int location, int value); 742static void mdio_write(struct net_device *vp, int phy_id, int location, int value);
717static void vortex_timer(unsigned long arg); 743static void vortex_timer(unsigned long arg);
@@ -1119,6 +1145,7 @@ static int __devinit vortex_probe1(struct device *gendev,
1119 vp->has_nway = (vci->drv_flags & HAS_NWAY) ? 1 : 0; 1145 vp->has_nway = (vci->drv_flags & HAS_NWAY) ? 1 : 0;
1120 vp->io_size = vci->io_size; 1146 vp->io_size = vci->io_size;
1121 vp->card_idx = card_idx; 1147 vp->card_idx = card_idx;
1148 vp->window = -1;
1122 1149
1123 /* module list only for Compaq device */ 1150 /* module list only for Compaq device */
1124 if (gendev == NULL) { 1151 if (gendev == NULL) {
@@ -1205,7 +1232,6 @@ static int __devinit vortex_probe1(struct device *gendev,
1205 vp->mii.force_media = vp->full_duplex; 1232 vp->mii.force_media = vp->full_duplex;
1206 vp->options = option; 1233 vp->options = option;
1207 /* Read the station address from the EEPROM. */ 1234 /* Read the station address from the EEPROM. */
1208 EL3WINDOW(0);
1209 { 1235 {
1210 int base; 1236 int base;
1211 1237
@@ -1218,14 +1244,15 @@ static int __devinit vortex_probe1(struct device *gendev,
1218 1244
1219 for (i = 0; i < 0x40; i++) { 1245 for (i = 0; i < 0x40; i++) {
1220 int timer; 1246 int timer;
1221 iowrite16(base + i, ioaddr + Wn0EepromCmd); 1247 window_write16(vp, base + i, 0, Wn0EepromCmd);
1222 /* Pause for at least 162 us. for the read to take place. */ 1248 /* Pause for at least 162 us. for the read to take place. */
1223 for (timer = 10; timer >= 0; timer--) { 1249 for (timer = 10; timer >= 0; timer--) {
1224 udelay(162); 1250 udelay(162);
1225 if ((ioread16(ioaddr + Wn0EepromCmd) & 0x8000) == 0) 1251 if ((window_read16(vp, 0, Wn0EepromCmd) &
1252 0x8000) == 0)
1226 break; 1253 break;
1227 } 1254 }
1228 eeprom[i] = ioread16(ioaddr + Wn0EepromData); 1255 eeprom[i] = window_read16(vp, 0, Wn0EepromData);
1229 } 1256 }
1230 } 1257 }
1231 for (i = 0; i < 0x18; i++) 1258 for (i = 0; i < 0x18; i++)
@@ -1250,9 +1277,8 @@ static int __devinit vortex_probe1(struct device *gendev,
1250 pr_err("*** EEPROM MAC address is invalid.\n"); 1277 pr_err("*** EEPROM MAC address is invalid.\n");
1251 goto free_ring; /* With every pack */ 1278 goto free_ring; /* With every pack */
1252 } 1279 }
1253 EL3WINDOW(2);
1254 for (i = 0; i < 6; i++) 1280 for (i = 0; i < 6; i++)
1255 iowrite8(dev->dev_addr[i], ioaddr + i); 1281 window_write8(vp, dev->dev_addr[i], 2, i);
1256 1282
1257 if (print_info) 1283 if (print_info)
1258 pr_cont(", IRQ %d\n", dev->irq); 1284 pr_cont(", IRQ %d\n", dev->irq);
@@ -1261,8 +1287,7 @@ static int __devinit vortex_probe1(struct device *gendev,
1261 pr_warning(" *** Warning: IRQ %d is unlikely to work! ***\n", 1287 pr_warning(" *** Warning: IRQ %d is unlikely to work! ***\n",
1262 dev->irq); 1288 dev->irq);
1263 1289
1264 EL3WINDOW(4); 1290 step = (window_read8(vp, 4, Wn4_NetDiag) & 0x1e) >> 1;
1265 step = (ioread8(ioaddr + Wn4_NetDiag) & 0x1e) >> 1;
1266 if (print_info) { 1291 if (print_info) {
1267 pr_info(" product code %02x%02x rev %02x.%d date %02d-%02d-%02d\n", 1292 pr_info(" product code %02x%02x rev %02x.%d date %02d-%02d-%02d\n",
1268 eeprom[6]&0xff, eeprom[6]>>8, eeprom[0x14], 1293 eeprom[6]&0xff, eeprom[6]>>8, eeprom[0x14],
@@ -1285,17 +1310,15 @@ static int __devinit vortex_probe1(struct device *gendev,
1285 (unsigned long long)pci_resource_start(pdev, 2), 1310 (unsigned long long)pci_resource_start(pdev, 2),
1286 vp->cb_fn_base); 1311 vp->cb_fn_base);
1287 } 1312 }
1288 EL3WINDOW(2);
1289 1313
1290 n = ioread16(ioaddr + Wn2_ResetOptions) & ~0x4010; 1314 n = window_read16(vp, 2, Wn2_ResetOptions) & ~0x4010;
1291 if (vp->drv_flags & INVERT_LED_PWR) 1315 if (vp->drv_flags & INVERT_LED_PWR)
1292 n |= 0x10; 1316 n |= 0x10;
1293 if (vp->drv_flags & INVERT_MII_PWR) 1317 if (vp->drv_flags & INVERT_MII_PWR)
1294 n |= 0x4000; 1318 n |= 0x4000;
1295 iowrite16(n, ioaddr + Wn2_ResetOptions); 1319 window_write16(vp, n, 2, Wn2_ResetOptions);
1296 if (vp->drv_flags & WNO_XCVR_PWR) { 1320 if (vp->drv_flags & WNO_XCVR_PWR) {
1297 EL3WINDOW(0); 1321 window_write16(vp, 0x0800, 0, 0);
1298 iowrite16(0x0800, ioaddr);
1299 } 1322 }
1300 } 1323 }
1301 1324
@@ -1313,14 +1336,13 @@ static int __devinit vortex_probe1(struct device *gendev,
1313 { 1336 {
1314 static const char * const ram_split[] = {"5:3", "3:1", "1:1", "3:5"}; 1337 static const char * const ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
1315 unsigned int config; 1338 unsigned int config;
1316 EL3WINDOW(3); 1339 vp->available_media = window_read16(vp, 3, Wn3_Options);
1317 vp->available_media = ioread16(ioaddr + Wn3_Options);
1318 if ((vp->available_media & 0xff) == 0) /* Broken 3c916 */ 1340 if ((vp->available_media & 0xff) == 0) /* Broken 3c916 */
1319 vp->available_media = 0x40; 1341 vp->available_media = 0x40;
1320 config = ioread32(ioaddr + Wn3_Config); 1342 config = window_read32(vp, 3, Wn3_Config);
1321 if (print_info) { 1343 if (print_info) {
1322 pr_debug(" Internal config register is %4.4x, transceivers %#x.\n", 1344 pr_debug(" Internal config register is %4.4x, transceivers %#x.\n",
1323 config, ioread16(ioaddr + Wn3_Options)); 1345 config, window_read16(vp, 3, Wn3_Options));
1324 pr_info(" %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n", 1346 pr_info(" %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
1325 8 << RAM_SIZE(config), 1347 8 << RAM_SIZE(config),
1326 RAM_WIDTH(config) ? "word" : "byte", 1348 RAM_WIDTH(config) ? "word" : "byte",
@@ -1346,7 +1368,6 @@ static int __devinit vortex_probe1(struct device *gendev,