diff options
author | Ben Hutchings <ben@decadent.org.uk> | 2010-06-23 17:54:31 +0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-06-29 10:19:18 +0400 |
commit | a095cfc40ec7ebe63e9532383c5b5c2a27b14075 (patch) | |
tree | 283359a3658ad91b122cd0674bf90b6f9dc0e3d2 /drivers/net/3c59x.c | |
parent | d2ef8590343f1f236f5f7f070fb4cd3f5c3ffb69 (diff) | |
download | linux-a095cfc40ec7ebe63e9532383c5b5c2a27b14075.tar.xz |
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>
Diffstat (limited to 'drivers/net/3c59x.c')
-rw-r--r-- | drivers/net/3c59x.c | 288 |
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); First the windows. There are eight register windows, with the command and status registers available in each. */ -#define EL3WINDOW(win_num) iowrite16(SelectWindow + (win_num), ioaddr + EL3_CMD) #define EL3_CMD 0x0e #define EL3_STATUS 0x0e @@ -647,8 +646,35 @@ struct vortex_private { u16 io_size; /* Size of PCI region (for release_region) */ spinlock_t lock; /* Serialise access to device & its vortex_private */ struct mii_if_info mii; /* MII lib hooks/info */ + int window; /* Register window */ }; +static void window_set(struct vortex_private *vp, int window) +{ + if (window != vp->window) { + iowrite16(SelectWindow + window, vp->ioaddr + EL3_CMD); + vp->window = window; + } +} + +#define DEFINE_WINDOW_IO(size) \ +static u ## size \ +window_read ## size(struct vortex_private *vp, int window, int addr) \ +{ \ + window_set(vp, window); \ + return ioread ## size(vp->ioaddr + addr); \ +} \ +static void \ +window_write ## size(struct vortex_private *vp, u ## size value, \ + int window, int addr) \ +{ \ + window_set(vp, window); \ + iowrite ## size(value, vp->ioaddr + addr); \ +} +DEFINE_WINDOW_IO(8) +DEFINE_WINDOW_IO(16) +DEFINE_WINDOW_IO(32) + #ifdef CONFIG_PCI #define DEVICE_PCI(dev) (((dev)->bus == &pci_bus_type) ? to_pci_dev((dev)) : NULL) #else @@ -711,7 +737,7 @@ static int vortex_probe1(struct device *gendev, void __iomem *ioaddr, int irq, static int vortex_up(struct net_device *dev); static void vortex_down(struct net_device *dev, int final); static int vortex_open(struct net_device *dev); -static void mdio_sync(void __iomem *ioaddr, int bits); +static void mdio_sync(struct vortex_private *vp, int bits); static int mdio_read(struct net_device *dev, int phy_id, int location); static void mdio_write(struct net_device *vp, int phy_id, int location, int value); static void vortex_timer(unsigned long arg); @@ -1119,6 +1145,7 @@ static int __devinit vortex_probe1(struct device *gendev, vp->has_nway = (vci->drv_flags & HAS_NWAY) ? 1 : 0; vp->io_size = vci->io_size; vp->card_idx = card_idx; + vp->window = -1; /* module list only for Compaq device */ if (gendev == NULL) { @@ -1205,7 +1232,6 @@ static int __devinit vortex_probe1(struct device *gendev, vp->mii.force_media = vp->full_duplex; vp->options = option; /* Read the station address from the EEPROM. */ - EL3WINDOW(0); { int base; @@ -1218,14 +1244,15 @@ static int __devinit vortex_probe1(struct device *gendev, for (i = 0; i < 0x40; i++) { int timer; - iowrite16(base + i, ioaddr + Wn0EepromCmd); + window_write16(vp, base + i, 0, Wn0EepromCmd); /* Pause for at least 162 us. for the read to take place. */ for (timer = 10; timer >= 0; timer--) { udelay(162); - if ((ioread16(ioaddr + Wn0EepromCmd) & 0x8000) == 0) + if ((window_read16(vp, 0, Wn0EepromCmd) & + 0x8000) == 0) break; } - eeprom[i] = ioread16(ioaddr + Wn0EepromData); + eeprom[i] = window_read16(vp, 0, Wn0EepromData); } } for (i = 0; i < 0x18; i++) @@ -1250,9 +1277,8 @@ static int __devinit vortex_probe1(struct device *gendev, pr_err("*** EEPROM MAC address is invalid.\n"); goto free_ring; /* With every pack */ } - EL3WINDOW(2); for (i = 0; i < 6; i++) - iowrite8(dev->dev_addr[i], ioaddr + i); + window_write8(vp, dev->dev_addr[i], 2, i); if (print_info) pr_cont(", IRQ %d\n", dev->irq); @@ -1261,8 +1287,7 @@ static int __devinit vortex_probe1(struct device *gendev, pr_warning(" *** Warning: IRQ %d is unlikely to work! ***\n", dev->irq); - EL3WINDOW(4); - step = (ioread8(ioaddr + Wn4_NetDiag) & 0x1e) >> 1; + step = (window_read8(vp, 4, Wn4_NetDiag) & 0x1e) >> 1; if (print_info) { pr_info(" product code %02x%02x rev %02x.%d date %02d-%02d-%02d\n", eeprom[6]&0xff, eeprom[6]>>8, eeprom[0x14], @@ -1285,17 +1310,15 @@ static int __devinit vortex_probe1(struct device *gendev, (unsigned long long)pci_resource_start(pdev, 2), vp->cb_fn_base); } - EL3WINDOW(2); - n = ioread16(ioaddr + Wn2_ResetOptions) & ~0x4010; + n = window_read16(vp, 2, Wn2_ResetOptions) & ~0x4010; if (vp->drv_flags & INVERT_LED_PWR) n |= 0x10; if (vp->drv_flags & INVERT_MII_PWR) n |= 0x4000; - iowrite16(n, ioaddr + Wn2_ResetOptions); + window_write16(vp, n, 2, Wn2_ResetOptions); if (vp->drv_flags & WNO_XCVR_PWR) { - EL3WINDOW(0); - iowrite16(0x0800, ioaddr); + window_write16(vp, 0x0800, 0, 0); } } @@ -1313,14 +1336,13 @@ static int __devinit vortex_probe1(struct device *gendev, { static const char * const ram_split[] = {"5:3", "3:1", "1:1", "3:5"}; unsigned int config; - EL3WINDOW(3); - vp->available_media = ioread16(ioaddr + Wn3_Options); + vp->available_media = window_read16(vp, 3, Wn3_Options); if ((vp->available_media & 0xff) == 0) /* Broken 3c916 */ vp->available_media = 0x40; - config = ioread32(ioaddr + Wn3_Config); + config = window_read32(vp, 3, Wn3_Config); if (print_info) { pr_debug(" Internal config register is %4.4x, transceivers %#x.\n", - config, ioread16(ioaddr + Wn3_Options)); + config, window_read16(vp, 3, Wn3_Options)); pr_info(" %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n", 8 << RAM_SIZE(config), RAM_WIDTH(config) ? "word" : "byte", @@ -1346,7 +1368,6 @@ static int __devinit vortex_probe1(struct device *gendev, if ((vp->available_media & 0x40) || (vci->drv_flags & HAS_NWAY) || dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) { int phy, phy_idx = 0; - EL3WINDOW(4); mii_preamble_required++; if (vp->drv_flags & EXTRA_PREAMBLE) mii_preamble_required++; @@ -1478,18 +1499,17 @@ static void vortex_set_duplex(struct net_device *dev) { struct vortex_private *vp = netdev_priv(dev); - void __iomem *ioaddr = vp->ioaddr; pr_info("%s: setting %s-duplex.\n", dev->name, (vp->full_duplex) ? "full" : "half"); - EL3WINDOW(3); /* Set the full-duplex bit. */ - iowrite16(((vp->info1 & 0x8000) || vp->full_duplex ? 0x20 : 0) | - (vp->large_frames ? 0x40 : 0) | - ((vp->full_duplex && vp->flow_ctrl && vp->partner_flow_ctrl) ? - 0x100 : 0), - ioaddr + Wn3_MAC_Ctrl); + window_write16(vp, + ((vp->info1 & 0x8000) || vp->full_duplex ? 0x20 : 0) | + (vp->large_frames ? 0x40 : 0) | + ((vp->full_duplex && vp->flow_ctrl && vp->partner_flow_ctrl) ? + 0x100 : 0), + 3, Wn3_MAC_Ctrl); } static void vortex_check_media(struct net_device *dev, unsigned int init) @@ -1529,8 +1549,7 @@ vortex_up(struct net_device *dev) } /* Before initializing select the active media port. */ - EL3WINDOW(3); - config = ioread32(ioaddr + Wn3_Config); + config = window_read32(vp, 3, Wn3_Config); if (vp->media_override != 7) { pr_info("%s: Media override to transceiver %d (%s).\n", @@ -1577,10 +1596,9 @@ vortex_up(struct net_device *dev) config = BFINS(config, dev->if_port, 20, 4); if (vortex_debug > 6) pr_debug("vortex_up(): writing 0x%x to InternalConfig\n", config); - iowrite32(config, ioaddr + Wn3_Config); + window_write32(vp, config, 3, Wn3_Config); if (dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) { - EL3WINDOW(4); mii_reg1 = mdio_read(dev, vp->phys[0], MII_BMSR); mii_reg5 = mdio_read(dev, vp->phys[0], MII_LPA); vp->partner_flow_ctrl = ((mii_reg5 & 0x0400) != 0); @@ -1601,51 +1619,46 @@ vortex_up(struct net_device *dev) iowrite16(SetStatusEnb | 0x00, ioaddr + EL3_CMD); if (vortex_debug > 1) { - EL3WINDOW(4); pr_debug("%s: vortex_up() irq %d media status %4.4x.\n", - dev->name, dev->irq, ioread16(ioaddr + Wn4_Media)); + dev->name, dev->irq, window_read16(vp, 4, Wn4_Media)); } /* Set the station address and mask in window 2 each time opened. */ - EL3WINDOW(2); for (i = 0; i < 6; i++) - iowrite8(dev->dev_addr[i], ioaddr + i); + window_write8(vp, dev->dev_addr[i], 2, i); for (; i < 12; i+=2) - iowrite16(0, ioaddr + i); + window_write16(vp, 0, 2, i); if (vp->cb_fn_base) { - unsigned short n = ioread16(ioaddr + Wn2_ResetOptions) & ~0x4010; + unsigned short n = window_read16(vp, 2, Wn2_ResetOptions) & ~0x4010; if (vp->drv_flags & INVERT_LED_PWR) n |= 0x10; if (vp->drv_flags & INVERT_MII_PWR) n |= 0x4000; - iowrite16(n, ioaddr + Wn2_ResetOptions); + window_write16(vp, n, 2, Wn2_ResetOptions); } if (dev->if_port == XCVR_10base2) /* Start the thinnet transceiver. We should really wait 50ms...*/ iowrite16(StartCoax, ioaddr + EL3_CMD); if (dev->if_port != XCVR_NWAY) { - EL3WINDOW(4); - iowrite16((ioread16(ioaddr + Wn4_Media) & ~(Media_10TP|Media_SQE)) | - media_tbl[dev->if_port].media_bits, ioaddr + Wn4_Media); + window_write16(vp, + (window_read16(vp, 4, Wn4_Media) & + ~(Media_10TP|Media_SQE)) | + media_tbl[dev->if_port].media_bits, + 4, Wn4_Media); } /* Switch to the stats window, and clear all stats by reading. */ iowrite16(StatsDisable, ioaddr + EL3_CMD); - EL3WINDOW(6); for (i = 0; i < 10; i++) - ioread8(ioaddr + i); - ioread16(ioaddr + 10); - ioread16(ioaddr + 12); + window_read8(vp, 6, i); + window_read16(vp, 6, 10); + window_read16(vp, 6, 12); /* New: On the Vortex we must also clear the BadSSD counter. */ - EL3WINDOW(4); - ioread8(ioaddr + 12); + window_read8(vp, 4, 12); /* ..and on the Boomerang we enable the extra statistics bits. */ - iowrite16(0x0040, ioaddr + Wn4_NetDiag); - - /* Switch to register set 7 for normal use. */ - EL3WINDOW(7); + window_write16(vp, 0x0040, 4, Wn4_NetDiag); if (vp->full_bus_master_rx) { /* Boomerang bus master. */ vp->cur_rx = vp->dirty_rx = 0; @@ -1763,7 +1776,7 @@ vortex_timer(unsigned long data) void __iomem *ioaddr = vp->ioaddr; int next_tick = 60*HZ; int ok = 0; - int media_status, old_window; + int media_status; if (vortex_debug > 2) { pr_debug("%s: Media selection timer tick happened, %s.\n", @@ -1772,9 +1785,7 @@ vortex_timer(unsigned long data) } disable_irq_lockdep(dev->irq); - old_window = ioread16(ioaddr + EL3_CMD) >> 13; - EL3WINDOW(4); - media_status = ioread16(ioaddr + Wn4_Media); + media_status = window_read16(vp, 4, Wn4_Media); switch (dev->if_port) { case XCVR_10baseT: case XCVR_100baseTx: case XCVR_100baseFx: if (media_status & Media_LnkBeat) { @@ -1830,13 +1841,14 @@ vortex_timer(unsigned long data) dev->name, media_tbl[dev->if_port].name); next_tick = media_tbl[dev->if_port].wait; } - iowrite16((media_status & ~(Media_10TP|Media_SQE)) | - media_tbl[dev->if_port].media_bits, ioaddr + Wn4_Media); + window_write16(vp, + (media_status & ~(Media_10TP|Media_SQE)) | + media_tbl[dev->if_port].media_bits, + 4, Wn4_Media); - EL3WINDOW(3); - config = ioread32(ioaddr + Wn3_Config); + config = window_read32(vp, 3, Wn3_Config); config = BFINS(config, dev->if_port, 20, 4); - iowrite32(config, ioaddr + Wn3_Config); + window_write32(vp, config, 3, Wn3_Config); iowrite16(dev->if_port == XCVR_10base2 ? StartCoax : StopCoax, ioaddr + EL3_CMD); @@ -1850,7 +1862,6 @@ leave_media_alone: pr_debug("%s: Media selection timer finished, %s.\n", dev->name, media_tbl[dev->if_port].name); - EL3WINDOW(old_window); enable_irq_lockdep(dev->irq); mod_timer(&vp->timer, RUN_AT(next_tick)); if (vp->deferred) @@ -1865,12 +1876,11 @@ static void vortex_tx_timeout(struct net_device *dev) pr_err("%s: transmit timed out, tx_status %2.2x status %4.4x.\n", dev->name, ioread8(ioaddr + TxStatus), ioread16(ioaddr + EL3_STATUS)); - EL3WINDOW(4); pr_err(" diagnostics: net %04x media %04x dma %08x fifo %04x\n", - ioread16(ioaddr + Wn4_NetDiag), - ioread16(ioaddr + Wn4_Media), + window_read16(vp, 4, Wn4_NetDiag), + window_read16(vp, 4, Wn4_Media), ioread32(ioaddr + PktStatus), - ioread16(ioaddr + Wn4_FIFODiag)); + window_read16(vp, 4, Wn4_FIFODiag)); /* Slight code bloat to be user friendly. */ if ((ioread8(ioaddr + TxStatus) & 0x88) == 0x88) pr_err("%s: Transmitter encountered 16 collisions --" @@ -1917,9 +1927,6 @@ static void vortex_tx_timeout(struct net_device *dev) /* Issue Tx Enable */ iowrite16(TxEnable, ioaddr + EL3_CMD); dev->trans_start = jiffies; /* prevent tx timeout */ - - /* Switch to register set 7 for normal use. */ - EL3WINDOW(7); } /* @@ -1980,10 +1987,10 @@ vortex_error(struct net_device *dev, int status) ioread16(ioaddr + EL3_STATUS) & StatsFull) { pr_warning("%s: Updating statistics failed, disabling " "stats as an interrupt source.\n", dev->name); - EL3WINDOW(5); - iowrite16(SetIntrEnb | (ioread16(ioaddr + 10) & ~StatsFull), ioaddr + EL3_CMD); + iowrite16(SetIntrEnb | + (window_read16(vp, 5, 10) & ~StatsFull), + ioaddr + EL3_CMD); vp->intr_enable &= ~StatsFull; - EL3WINDOW(7); DoneDidThat++; } } @@ -1993,8 +2000,7 @@ vortex_error(struct net_device *dev, int status) } if (status & HostError) { u16 fifo_diag; - EL3WINDOW(4); - fifo_diag = ioread16(ioaddr + Wn4_FIFODiag); + fifo_diag = window_read16(vp, 4, Wn4_FIFODiag); pr_err("%s: Host error, FIFO diagnostic register %4.4x.\n", dev->name, fifo_diag); /* Adapter failure requires Tx/Rx reset and reinit. */ @@ -2043,8 +2049,10 @@ vortex_start_xmit(struct sk_buff *skb, struct net_device *dev) if (vp->bus_master) { /* Set the bus-master controller to transfer the packet. */ int len = (skb->len + 3) & ~3; - iowrite32(vp->tx_skb_dma = pci_map_single(VORTEX_PCI(vp), skb->data, len, PCI_DMA_TODEVICE), - ioaddr + Wn7_MasterAddr); + vp->tx_skb_dma = pci_map_single(VORTEX_PCI(vp), skb->data, len, + PCI_DMA_TODEVICE); + window_set(vp, 7); + iowrite32(vp->tx_skb_dma, ioaddr + Wn7_MasterAddr); iowrite16(len, ioaddr + Wn7_MasterLen); vp->tx_skb = skb; iowrite16(StartDMADown, ioaddr + EL3_CMD); @@ -2217,6 +2225,8 @@ vortex_interrupt(int irq, void *dev_id) pr_debug("%s: interrupt, status %4.4x, latency %d ticks.\n", dev->name, status, ioread8(ioaddr + Timer)); + window_set(vp, 7); + do { if (vortex_debug > 5) pr_debug("%s: In interrupt loop, status %4.4x.\n", @@ -2760,54 +2770,46 @@ static struct net_device_stats *vortex_get_stats(struct net_device *dev) static void update_stats(void __iomem *ioaddr, struct net_device *dev) { struct vortex_private *vp = netdev_priv(dev); - int old_window = ioread16(ioaddr + EL3_CMD); - if (old_window == 0xffff) /* Chip suspended or ejected. */ - return; /* Unlike the 3c5x9 we need not turn off stats updates while reading. */ /* Switch to the stats window, and read everything. */ - EL3WINDOW(6); - dev->stats.tx_carrier_errors += ioread8(ioaddr + 0); - dev->stats.tx_heartbeat_errors += ioread8(ioaddr + 1); - dev->stats.tx_window_errors += ioread8(ioaddr + 4); - dev->stats.rx_fifo_errors += ioread8(ioaddr + 5); - dev->stats.tx_packets += ioread8(ioaddr + 6); - dev->stats.tx_packets += (ioread8(ioaddr + 9)&0x30) << 4; - /* Rx packets */ ioread8(ioaddr + 7); /* Must read to clear */ + dev->stats.tx_carrier_errors += window_read8(vp, 6, 0); + dev->stats.tx_heartbeat_errors += window_read8(vp, 6, 1); + dev->stats.tx_window_errors += window_read8(vp, 6, 4); + dev->stats.rx_fifo_errors += window_read8(vp, 6, 5); + dev->stats.tx_packets += window_read8(vp, 6, 6); + dev->stats.tx_packets += (window_read8(vp, 6, 9) & + 0x30) << 4; + /* Rx packets */ window_read8(vp, 6, 7); /* Must read to clear */ /* Don't bother with register 9, an extension of registers 6&7. If we do use the 6&7 values the atomic update assumption above is invalid. */ - dev->stats.rx_bytes += ioread16(ioaddr + 10); - dev->stats.tx_bytes += ioread16(ioaddr + 12); + dev->stats.rx_bytes += window_read16(vp, 6, 10); + dev->stats.tx_bytes += window_read16(vp, 6, 12); /* Extra stats for get_ethtool_stats() */ - vp->xstats.tx_multiple_collisions += ioread8(ioaddr + 2); - vp->xstats.tx_single_collisions += ioread8(ioaddr + 3); - vp->xstats.tx_deferred += ioread8(ioaddr + 8); - EL3WINDOW(4); - vp->xstats.rx_bad_ssd += ioread8(ioaddr + 12); + vp->xstats.tx_multiple_collisions += window_read8(vp, 6, 2); + vp->xstats.tx_single_collisions += window_read8(vp, 6, 3); + vp->xstats.tx_deferred += window_read8(vp, 6, 8); + vp->xstats.rx_bad_ssd += window_read8(vp, 4, 12); dev->stats.collisions = vp->xstats.tx_multiple_collisions + vp->xstats.tx_single_collisions + vp->xstats.tx_max_collisions; { - u8 up = ioread8(ioaddr + 13); + u8 up = window_read8(vp, 4, 13); dev->stats.rx_bytes += (up & 0x0f) << 16; dev->stats.tx_bytes += (up & 0xf0) << 12; } - - EL3WINDOW(old_window >> 13); } static int vortex_nway_reset(struct net_device *dev) { struct vortex_private *vp = netdev_priv(dev); - void __iomem *ioaddr = vp->ioaddr; unsigned long flags; int rc; spin_lock_irqsave(&vp->lock, flags); - EL3WINDOW(4); rc = mii_nway_restart(&vp->mii); spin_unlock_irqrestore(&vp->lock, flags); return rc; @@ -2816,12 +2818,10 @@ static int vortex_nway_reset(struct net_device *dev) static int vortex_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct vortex_private *vp = netdev_priv(dev); - void __iomem *ioaddr = vp->ioaddr; unsigned long flags; int rc; spin_lock_irqsave(&vp->lock, flags); - EL3WINDOW(4); rc = mii_ethtool_gset(&vp->mii, cmd); spin_unlock_irqrestore(&vp->lock, flags); return rc; @@ -2830,12 +2830,10 @@ static int vortex_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) static int vortex_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct vortex_private *vp = netdev_priv(dev); - void __iomem *ioaddr = vp->ioaddr; unsigned long flags; int rc; spin_lock_irqsave(&vp->lock, flags); - EL3WINDOW(4); rc = mii_ethtool_sset(&vp->mii, cmd); spin_unlock_irqrestore(&vp->lock, flags); return rc; @@ -2930,7 +2928,6 @@ static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { int err; struct vortex_private *vp = netdev_priv(dev); - void __iomem *ioaddr = vp->ioaddr; unsigned long flags; pci_power_t state = 0; @@ -2942,7 +2939,6 @@ static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) if(state != 0) pci_set_power_state(VORTEX_PCI(vp), PCI_D0); spin_lock_irqsave(&vp->lock, flags); - EL3WINDOW(4); err = generic_mii_ioctl(&vp->mii, if_mii(rq), cmd, NULL); spin_unlock_irqrestore(&vp->lock, flags); if(state != 0) @@ -2985,8 +2981,6 @@ static void set_rx_mode(struct net_device *dev) static void set_8021q_mode(struct net_device *dev, int enable) { struct vortex_private *vp = netdev_priv(dev); - void __iomem *ioaddr = vp->ioaddr; - int old_window = ioread16(ioaddr + EL3_CMD); int mac_ctrl; if ((vp->drv_flags&IS_CYCLONE) || (vp->drv_flags&IS_TORNADO)) { @@ -2997,28 +2991,23 @@ static void set_8021q_mode(struct net_device *dev, int enable) if (enable) max_pkt_size += 4; /* 802.1Q VLAN tag */ - EL3WINDOW(3); - iowrite16(max_pkt_size, ioaddr+Wn3_MaxPktSize); + window_write16(vp, max_pkt_size, 3, Wn3_MaxPktSize); /* set VlanEtherType to let the hardware checksumming treat tagged frames correctly */ - EL3WINDOW(7); - iowrite16(VLAN_ETHER_TYPE, ioaddr+Wn7_VlanEtherType); + window_write16(vp, VLAN_ETHER_TYPE, 7, Wn7_VlanEtherType); } else { /* on older cards we have to enable large frames */ vp->large_frames = dev->mtu > 1500 || enable; - EL3WINDOW(3); - mac_ctrl = ioread16(ioaddr+Wn3_MAC_Ctrl); + mac_ctrl = window_read16(vp, 3, Wn3_MAC_Ctrl); if (vp->large_frames) mac_ctrl |= 0x40; else mac_ctrl &= ~0x40; - iowrite16(mac_ctrl, ioaddr+Wn3_MAC_Ctrl); + window_write16(vp, mac_ctrl, 3, Wn3_MAC_Ctrl); } - - EL3WINDOW(old_window); } #else @@ -3037,7 +3026,10 @@ static void set_8021q_mode(struct net_device *dev, int enable) /* The maximum data clock rate is 2.5 Mhz. The minimum timing is usually met by back-to-back PCI I/O cycles, but we insert a delay to avoid "overclocking" issues. */ -#define mdio_delay() ioread32(mdio_addr) +static void mdio_delay(struct vortex_private *vp) +{ + window_read32(vp, 4, Wn4_PhysicalMgmt); +} #define MDIO_SHIFT_CLK 0x01 #define MDIO_DIR_WRITE 0x04 @@ -3048,16 +3040,15 @@ static void set_8021q_mode(struct net_device *dev, int enable) /* Generate the preamble required for initial synchronization and a few older transceivers. */ -static void mdio_sync(void __iomem *ioaddr, int bits) +static void mdio_sync(struct vortex_private *vp, int bits) { - void __iomem *mdio_addr = ioaddr + Wn4_PhysicalMgmt; - /* Establish sync by sending at least 32 logic ones. */ while (-- bits >= 0) { - iowrite16(MDIO_DATA_WRITE1, mdio_addr); - mdio_delay(); - iowrite16(MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr); - mdio_delay(); + window_write16(vp, MDIO_DATA_WRITE1, 4, Wn4_PhysicalMgmt); + mdio_delay(vp); + window_write16(vp, MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, + 4, Wn4_PhysicalMgmt); + mdio_delay(vp); } } @@ -3065,29 +3056,31 @@ static int mdio_read(struct net_device *dev, int phy_id, int location) { int i; struct vortex_private *vp = netdev_priv(dev); - void __iomem *ioaddr = vp->ioaddr; int read_cmd = (0xf6 << 10) | (phy_id << 5) | location; unsigned int retval = 0; - void __iomem *mdio_addr = ioaddr + Wn4_PhysicalMgmt; if (mii_preamble_required) - mdio_sync(ioaddr, 32); + mdio_sync(vp, 32); /* Shift the read command bits out. */ for (i = 14; i >= 0; i--) { int dataval = (read_cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0; - iowrite16(dataval, mdio_addr); - mdio_delay(); - iowrite16(dataval | MDIO_SHIFT_CLK, mdio_addr); - mdio_delay(); + window_write16(vp, dataval, 4, Wn4_PhysicalMgmt); + mdio_delay(vp); + window_write16(vp, dataval | MDIO_SHIFT_CLK, + 4, Wn4_PhysicalMgmt); + mdio_delay(vp); } /* Read the two transition, 16 data, and wire-idle bits. */ for (i = 19; i > 0; i--) { - iowrite16(MDIO_ENB_IN, mdio_addr); - mdio_delay(); - retval = (retval << 1) | ((ioread16(mdio_addr) & MDIO_DATA_READ) ? 1 : 0); - iowrite16(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr); - mdio_delay(); + window_write16(vp, MDIO_ENB_IN, 4, Wn4_PhysicalMgmt); + mdio_delay(vp); + retval = (retval << 1) | + ((window_read16(vp, 4, Wn4_PhysicalMgmt) & + MDIO_DATA_READ) ? 1 : 0); + window_write16(vp, MDIO_ENB_IN | MDIO_SHIFT_CLK, + 4, Wn4_PhysicalMgmt); + mdio_delay(vp); } return retval & 0x20000 ? 0xffff : retval>>1 & 0xffff; } @@ -3095,28 +3088,28 @@ static int mdio_read(struct net_device *dev, int phy_id, int location) static void mdio_write(struct net_device *dev, int phy_id, int location, int value) { struct vortex_private *vp = netdev_priv(dev); - void __iomem *ioaddr = vp->ioaddr; int write_cmd = 0x50020000 | (phy_id << 23) | (location << 18) | value; - void __iomem *mdio_addr = ioaddr + Wn4_PhysicalMgmt; int i; if (mii_preamble_required) - mdio_sync(ioaddr, 32); + mdio_sync(vp, 32); /* Shift the command bits out. */ for (i = 31; i >= 0; i--) { int dataval = (write_cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0; - iowrite16(dataval, mdio_addr); - mdio_delay(); - iowrite16(dataval | MDIO_SHIFT_CLK, mdio_addr); - mdio_delay(); + window_write16(vp, dataval, 4, Wn4_PhysicalMgmt); + mdio_delay(vp); + window_write16(vp, dataval | MDIO_SHIFT_CLK, + 4, Wn4_PhysicalMgmt); + mdio_delay(vp); } /* Leave the interface idle. */ for (i = 1; i >= 0; i--) { - iowrite16(MDIO_ENB_IN, mdio_addr); - mdio_delay(); - iowrite16(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr); - mdio_delay(); + window_write16(vp, MDIO_ENB_IN, 4, Wn4_PhysicalMgmt); + mdio_delay(vp); + window_write16(vp, MDIO_ENB_IN | MDIO_SHIFT_CLK, + 4, Wn4_PhysicalMgmt); + mdio_delay(vp); } } @@ -3131,8 +3124,7 @@ static void acpi_set_WOL(struct net_device *dev) if (vp->enable_wol) { /* Power up on: 1==Downloaded Filter, 2==Magic Packets, 4==Link Status. */ - EL3WINDOW(7); - iowrite16(2, ioaddr + 0x0c); + window_write16(vp, 2, 7, 0x0c); /* The RxFilter must accept the WOL frames. */ iowrite16(SetRxFilter|RxStation|RxMulticast|RxBroadcast, ioaddr + EL3_CMD); iowrite16(RxEnable, ioaddr + EL3_CMD); |