Lines Matching +full:need +full:- +full:phy +full:- +full:for +full:- +full:wake

1 /* natsemi.c: A Linux PCI Ethernet driver for the NatSemi DP8381x series. */
3 Written/copyright 1999-2001 by Donald Becker.
13 system is licensed under the GPL. License for under other terms may be
14 available. Contact the original author for details.
23 [link no longer provides useful info -jgarzik]
51 #include <asm/processor.h> /* Processor type for cache alignment. */
62 /* Updated to recommendations in pci-skeleton v2.03. */
64 /* The user-configurable values.
72 static int debug = -1;
76 /* Maximum number of multicast addresses to filter (vs. rx-all-multicast).
80 /* Set the copy breakpoint for the copy-only-tiny-frames scheme.
87 Both 'options[]' and 'full_duplex[]' should exist for driver
97 /* Keep the ring sizes a power of two for compile efficiency.
101 There are no ill effects from too-large receive rings. */
121 * The nic writes 32-bit values, even if the upper bytes of
122 * a 32-bit value are beyond the end of the buffer.
126 #define NATSEMI_LONGPKT 1518 /* limit for normal packets */
149 "DP8381x copy breakpoint for copy-only-tiny-frames");
152 "DP8381x: Bits 0-3: media type, bit 17: full duplex");
160 This driver is designed for National Semiconductor DP83815 PCI Ethernet NIC.
163 II. Board-specific settings
166 It honors the EEPROM-set values.
172 This driver uses two statically allocated fixed-size descriptor lists
180 This driver uses a zero-copy receive and transmit scheme.
181 The driver allocates full frame size skbuffs for the Rx ring buffers at
182 open() time and passes the skb->data field to the chip as receive data
189 The RX_COPYBREAK value is chosen to trade-off the memory wasted by
190 using a full-sized skbuff for small frames vs. the copying costs of larger
200 longword aligned for further processing. On copies frames are put into the
201 skbuff at an offset of "+2", 16-byte aligning the IP header.
205 Most operations are synchronized on the np->lock irq spinlock, except the
224 * Support for fibre connections on Am79C874:
225 * This phy needs a special setup when connected to a fibre cable.
232 MII_FX_SEL = 0x0001, /* 100BASE-FX (fiber) */
258 Unlike software-only systems, device drivers interact with complex hardware.
259 It's not useful to define symbolic names for every register bit in the
305 /* the values for the 'magic' registers above (PGSEL=1) */
309 #define SDCFG_VAL 0x008c /* set voltage thresholds for Signal Detect */
312 #define TSTDAT_FIXED 0xe8 /* magic number for bad coefficients */
385 * MIB Service, Phy Interrupt, High Bits,
413 * - 256 byte DMA burst length
414 * - fill threshold 512 bytes (i.e. restart DMA when 512 bytes are free)
415 * - 64 bytes initial drain threshold (i.e. begin actual transmission
417 * - on tx underruns, increase drain threshold by 64.
418 * - at most use a drain threshold of 1472 bytes: The sum of the fill
511 /* Note that using only 32 bit fields simplifies conversion to big-endian
539 /* Descriptor rings first for alignment */
543 /* The addresses of receive-in-place skbuffs */
546 /* address of a sent-in-place packet/buffer, for later free() */
554 /* Frequently used values: keep some adjacent for cache effect */
569 /* external phy that is used: only valid if dev->if_port != PORT_TP */
662 device_create_file(&_dev->dev, &dev_attr_##_name)
664 device_remove_file(&_dev->dev, &dev_attr_##_name)
674 return sprintf(buf, "%s\n", np->dspcfg_workaround ? "on" : "off"); in natsemi_show_dspcfg_workaround()
686 if (!strncmp("on", buf, count - 1) || !strncmp("1", buf, count - 1)) in natsemi_set_dspcfg_workaround()
688 else if (!strncmp("off", buf, count - 1) || in natsemi_set_dspcfg_workaround()
689 !strncmp("0", buf, count - 1)) in natsemi_set_dspcfg_workaround()
694 spin_lock_irqsave(&np->lock, flags); in natsemi_set_dspcfg_workaround()
696 np->dspcfg_workaround = new_setting; in natsemi_set_dspcfg_workaround()
698 spin_unlock_irqrestore(&np->lock, flags); in natsemi_set_dspcfg_workaround()
707 return np->ioaddr; in ns_ioaddr()
729 * The internal phy is visible on the external mii bus. Therefore we must in move_int_phy()
730 * move it away before we can send commands to an external phy. in move_int_phy()
732 * - the address on the external phy that is used for transmission. in move_int_phy()
733 * - the address that we want to access. User space can access phys in move_int_phy()
735 * phy that is used for transmission. in move_int_phy()
739 target--; in move_int_phy()
740 if (target == np->phy_addr_external) in move_int_phy()
741 target--; in move_int_phy()
752 if (np->ignore_phy) in natsemi_init_media()
759 np->speed = (tmp & BMCR_SPEED100)? SPEED_100 : SPEED_10; in natsemi_init_media()
760 np->duplex = (tmp & BMCR_FULLDPLX)? DUPLEX_FULL : DUPLEX_HALF; in natsemi_init_media()
761 np->autoneg = (tmp & BMCR_ANENABLE)? AUTONEG_ENABLE: AUTONEG_DISABLE; in natsemi_init_media()
762 np->advertising= mdio_read(dev, MII_ADVERTISE); in natsemi_init_media()
764 if ((np->advertising & ADVERTISE_ALL) != ADVERTISE_ALL && in natsemi_init_media()
768 pci_name(np->pci_dev), in natsemi_init_media()
771 (np->advertising & in natsemi_init_media()
774 (np->advertising & in natsemi_init_media()
781 pci_name(np->pci_dev), mdio_read(dev, MII_BMSR), in natsemi_init_media()
782 np->advertising); in natsemi_init_media()
806 int i, option, irq, chip_idx = ent->driver_data; in natsemi_probe1()
807 static int find_cnt = -1; in natsemi_probe1()
825 /* natsemi has a non-standard PM control register in natsemi_probe1()
826 * in PCI config space. Some boards apparently need in natsemi_probe1()
839 irq = pdev->irq; in natsemi_probe1()
845 return -ENOMEM; in natsemi_probe1()
846 SET_NETDEV_DEV(dev, &pdev->dev); in natsemi_probe1()
854 i = -ENOMEM; in natsemi_probe1()
860 for (i = 0; i < 3; i++) { in natsemi_probe1()
862 dev->dev_addr[i*2] = (eedata << 1) + (prev_eedata >> 15); in natsemi_probe1()
863 dev->dev_addr[i*2+1] = eedata >> 7; in natsemi_probe1()
868 np->ioaddr = ioaddr; in natsemi_probe1()
870 netif_napi_add(dev, &np->napi, natsemi_poll, 64); in natsemi_probe1()
871 np->dev = dev; in natsemi_probe1()
873 np->pci_dev = pdev; in natsemi_probe1()
875 np->iosize = iosize; in natsemi_probe1()
876 spin_lock_init(&np->lock); in natsemi_probe1()
877 np->msg_enable = (debug >= 0) ? (1<<debug)-1 : NATSEMI_DEF_MSG; in natsemi_probe1()
878 np->hands_off = 0; in natsemi_probe1()
879 np->intr_status = 0; in natsemi_probe1()
880 np->eeprom_size = natsemi_pci_info[chip_idx].eeprom_size; in natsemi_probe1()
882 np->ignore_phy = 1; in natsemi_probe1()
884 np->ignore_phy = 0; in natsemi_probe1()
885 np->dspcfg_workaround = dspcfg_workaround; in natsemi_probe1()
888 * - If configured to ignore the PHY set up for external. in natsemi_probe1()
889 * - If the nic was configured to use an external phy and if find_mii in natsemi_probe1()
890 * finds a phy: use external port, first phy that replies. in natsemi_probe1()
891 * - Otherwise: internal port. in natsemi_probe1()
892 * Note that the phy address for the internal phy doesn't matter: in natsemi_probe1()
893 * The address would be used to access a phy over the mii bus, but in natsemi_probe1()
894 * the internal phy is accessed through mapped registers. in natsemi_probe1()
896 if (np->ignore_phy || readl(ioaddr + ChipConfig) & CfgExtPhy) in natsemi_probe1()
897 dev->if_port = PORT_MII; in natsemi_probe1()
899 dev->if_port = PORT_TP; in natsemi_probe1()
904 if (dev->if_port != PORT_TP) { in natsemi_probe1()
905 np->phy_addr_external = find_mii(dev); in natsemi_probe1()
906 /* If we're ignoring the PHY it doesn't matter if we can't in natsemi_probe1()
908 if (!np->ignore_phy && np->phy_addr_external == PHY_ADDR_NONE) { in natsemi_probe1()
909 dev->if_port = PORT_TP; in natsemi_probe1()
910 np->phy_addr_external = PHY_ADDR_INTERNAL; in natsemi_probe1()
913 np->phy_addr_external = PHY_ADDR_INTERNAL; in natsemi_probe1()
920 np->full_duplex = 1; in natsemi_probe1()
924 pci_name(np->pci_dev), option & 15); in natsemi_probe1()
927 np->full_duplex = 1; in natsemi_probe1()
929 dev->netdev_ops = &natsemi_netdev_ops; in natsemi_probe1()
930 dev->watchdog_timeo = TX_TIMEOUT; in natsemi_probe1()
932 dev->ethtool_ops = &ethtool_ops; in natsemi_probe1()
934 /* MTU range: 64 - 2024 */ in natsemi_probe1()
935 dev->min_mtu = ETH_ZLEN + ETH_FCS_LEN; in natsemi_probe1()
936 dev->max_mtu = NATSEMI_RX_LIMIT - NATSEMI_HEADERS; in natsemi_probe1()
939 dev->mtu = mtu; in natsemi_probe1()
943 /* save the silicon revision for later querying */ in natsemi_probe1()
944 np->srr = readl(ioaddr + SiliconRev); in natsemi_probe1()
947 pci_name(np->pci_dev), np->srr); in natsemi_probe1()
959 dev->name, natsemi_pci_info[chip_idx].name, in natsemi_probe1()
960 (unsigned long long)iostart, pci_name(np->pci_dev), in natsemi_probe1()
961 dev->dev_addr, irq); in natsemi_probe1()
962 if (dev->if_port == PORT_TP) in natsemi_probe1()
964 else if (np->ignore_phy) in natsemi_probe1()
965 printk(", port MII, ignoring PHY\n"); in natsemi_probe1()
967 printk(", port MII, phy ad %d.\n", np->phy_addr_external); in natsemi_probe1()
987 The EEPROM code is for the common 93c06/46 EEPROMs with 6 bit addresses. */
990 No extra delay is needed with 33Mhz PCI, but future 66Mhz access may need
991 a delay. Note that pre-2.0.34 kernels had a cache-alignment bug that
1001 /* The EEPROM commands include the alway-set leading bit. */
1016 for (i = 10; i >= 0; i--) { in eeprom_read()
1026 for (i = 0; i < 16; i++) { in eeprom_read()
1043 * External Phy registers are referenced through the MII interface.
1068 for (i = (1 << (len-1)); i; i >>= 1) in mii_send_bits()
1089 /* ST,OP = 0110'b for read operation */ in miiport_read()
1096 for (i = 0; i < 16; i++) { in miiport_read()
1112 /* ST,OP,AAAAA,RRRRR,TA = 0101xxxxxxxxxx10'b = 0x5002 for write */ in miiport_write()
1125 * - an internal transceiver in mdio_read()
1126 * - an external mii bus in mdio_read()
1128 if (dev->if_port == PORT_TP) in mdio_read()
1131 return miiport_read(dev, np->phy_addr_external, reg); in mdio_read()
1140 if (dev->if_port == PORT_TP) in mdio_write()
1143 miiport_write(dev, np->phy_addr_external, reg, data); in mdio_write()
1156 if (np->autoneg == AUTONEG_ENABLE) { in init_phy_fixup()
1159 np->advertising != mdio_read(dev, MII_ADVERTISE)) in init_phy_fixup()
1163 mdio_write(dev, MII_ADVERTISE, np->advertising); in init_phy_fixup()
1168 if (np->speed == SPEED_100) in init_phy_fixup()
1170 if (np->duplex == DUPLEX_FULL) in init_phy_fixup()
1184 /* find out what phy this is */ in init_phy_fixup()
1185 np->mii = (mdio_read(dev, MII_PHYSID1) << 16) in init_phy_fixup()
1189 switch (np->mii) { in init_phy_fixup()
1191 /* phy specific configuration for fibre/tp operation */ in init_phy_fixup()
1194 if (dev->if_port == PORT_FIBRE) in init_phy_fixup()
1207 /* On page 78 of the spec, they recommend some settings for "optimum in init_phy_fixup()
1210 do this for rev C of the chip, but engineers at NSC (Bradley in init_phy_fixup()
1215 the start of the phy. Just retry writing these values until they in init_phy_fixup()
1218 for (i=0;i<NATSEMI_HW_TIMEOUT;i++) { in init_phy_fixup()
1224 np->dspcfg = (np->srr <= SRR_DP83815_C)? in init_phy_fixup()
1226 writew(np->dspcfg, ioaddr + DSPCFG); in init_phy_fixup()
1235 if (np->dspcfg == dspcfg) in init_phy_fixup()
1242 "%s: DSPCFG mismatch after retrying for %d usec.\n", in init_phy_fixup()
1243 dev->name, i*10); in init_phy_fixup()
1247 dev->name, i*10); in init_phy_fixup()
1251 * Enable PHY Specific event based interrupts. Link state change in init_phy_fixup()
1252 * and Auto-Negotiation Completion are among the affected. in init_phy_fixup()
1253 * Read the intr status to clear it (needed for wake events). in init_phy_fixup()
1271 dev->name); in switch_port_external()
1274 /* 1) switch back to external phy */ in switch_port_external()
1279 /* 2) reset the external phy: */ in switch_port_external()
1280 /* resetting the external PHY has been known to cause a hub supplying in switch_port_external()
1282 * power to this computer, so we avoid resetting the phy. in switch_port_external()
1285 /* 3) reinit the phy fixup, it got lost during power down. */ in switch_port_external()
1286 move_int_phy(dev, np->phy_addr_external); in switch_port_external()
1306 dev->name); in switch_port_internal()
1308 /* 1) switch back to internal phy: */ in switch_port_internal()
1314 /* 2) reset the internal phy: */ in switch_port_internal()
1319 for (i=0;i<NATSEMI_HW_TIMEOUT;i++) { in switch_port_internal()
1327 "%s: phy reset did not complete in %d usec.\n", in switch_port_internal()
1328 dev->name, i*10); in switch_port_internal()
1330 /* 3) reinit the phy fixup, it got lost during power down. */ in switch_port_internal()
1336 /* Scan for a PHY on the external mii bus.
1338 * - Do not scan while the internal phy is enabled. The internal phy will
1340 * the nasty random phy reset code will reset the nic every few seconds.
1341 * - The internal phy must be moved around, an external phy could
1342 * have the same address as the internal phy.
1351 /* Switch to external phy */ in find_mii()
1354 /* Scan the possible phy addresses: in find_mii()
1356 * PHY address 0 means that the phy is in isolate mode. Not yet in find_mii()
1360 for (i = 1; i <= 31; i++) { in find_mii()
1365 np->mii = (mdio_read(dev, MII_PHYSID1) << 16) in find_mii()
1368 printk(KERN_INFO "natsemi %s: found external phy %08x at address %d.\n", in find_mii()
1369 pci_name(np->pci_dev), np->mii, i); in find_mii()
1374 /* And switch back to internal phy: */ in find_mii()
1402 * on a normal power-up (see the spec EEPROM map). This assumes in natsemi_reset()
1413 for (i = 0; i < 3; i++) { in natsemi_reset()
1418 for (i = 0; i < 3; i++) { in natsemi_reset()
1425 for (i=0;i<NATSEMI_HW_TIMEOUT;i++) { in natsemi_reset()
1432 dev->name, i*5); in natsemi_reset()
1435 dev->name, i*5); in natsemi_reset()
1440 /* turn on external phy if it was selected */ in natsemi_reset()
1441 if (dev->if_port == PORT_TP) in natsemi_reset()
1452 for (i = 0; i < 3; i++) { in natsemi_reset()
1456 for (i = 0; i < 3; i++) { in natsemi_reset()
1470 np->intr_status &= ~RxResetDone; in reset_rx()
1474 for (i=0;i<NATSEMI_HW_TIMEOUT;i++) { in reset_rx()
1475 np->intr_status |= readl(ioaddr + IntrStatus); in reset_rx()
1476 if (np->intr_status & RxResetDone) in reset_rx()
1482 dev->name, i*15); in reset_rx()
1485 dev->name, i*15); in reset_rx()
1496 for (i=0;i<NATSEMI_HW_TIMEOUT;i++) { in natsemi_reload_eeprom()
1503 pci_name(np->pci_dev), i*50); in natsemi_reload_eeprom()
1506 pci_name(np->pci_dev), i*50); in natsemi_reload_eeprom()
1517 for(i=0;i< NATSEMI_HW_TIMEOUT;i++) { in natsemi_stop_rxtx()
1524 dev->name, i*5); in natsemi_stop_rxtx()
1527 dev->name, i*5); in natsemi_stop_rxtx()
1535 const int irq = np->pci_dev->irq; in netdev_open()
1541 i = request_irq(irq, intr_handler, IRQF_SHARED, dev->name, dev); in netdev_open()
1546 dev->name, irq); in netdev_open()
1552 napi_enable(&np->napi); in netdev_open()
1555 spin_lock_irq(&np->lock); in netdev_open()
1557 /* now set the MAC address according to dev->dev_addr */ in netdev_open()
1558 for (i = 0; i < 3; i++) { in netdev_open()
1559 u16 mac = (dev->dev_addr[2*i+1]<<8) + dev->dev_addr[2*i]; in netdev_open()
1564 writel(np->cur_rx_mode, ioaddr + RxFilterAddr); in netdev_open()
1565 spin_unlock_irq(&np->lock); in netdev_open()
1571 dev->name, (int)readl(ioaddr + ChipCmd)); in netdev_open()
1573 /* Set the timer to check for link beat. */ in netdev_open()
1574 timer_setup(&np->timer, netdev_timer, 0); in netdev_open()
1575 np->timer.expires = round_jiffies(jiffies + NATSEMI_TIMER_FREQ); in netdev_open()
1576 add_timer(&np->timer); in netdev_open()
1586 if (dev->if_port != PORT_TP) in do_cable_magic()
1589 if (np->srr >= SRR_DP83816_A5) in do_cable_magic()
1614 /* the bug has been triggered - fix the coefficient */ in do_cable_magic()
1618 np->dspcfg = data | DSPCFG_LOCK; in do_cable_magic()
1619 writew(np->dspcfg, ioaddr + DSPCFG); in do_cable_magic()
1631 if (dev->if_port != PORT_TP) in undo_cable_magic()
1634 if (np->srr >= SRR_DP83816_A5) in undo_cable_magic()
1640 np->dspcfg = data & ~DSPCFG_LOCK; in undo_cable_magic()
1641 writew(np->dspcfg, ioaddr + DSPCFG); in undo_cable_magic()
1649 int duplex = np->duplex; in check_link()
1652 /* If we are ignoring the PHY then don't try reading it. */ in check_link()
1653 if (np->ignore_phy) in check_link()
1657 * link failure until it's read. We need the current link status, in check_link()
1667 dev->name); in check_link()
1675 printk(KERN_NOTICE "%s: link up.\n", dev->name); in check_link()
1680 duplex = np->full_duplex; in check_link()
1684 np->advertising & mdio_read(dev, MII_LPA)); in check_link()
1693 if (duplex ^ !!(np->rx_config & RxAcceptTx)) { in check_link()
1696 "%s: Setting %s-duplex based on negotiated " in check_link()
1697 "link capability.\n", dev->name, in check_link()
1700 np->rx_config |= RxAcceptTx; in check_link()
1701 np->tx_config |= TxCarrierIgn | TxHeartIgn; in check_link()
1703 np->rx_config &= ~RxAcceptTx; in check_link()
1704 np->tx_config &= ~(TxCarrierIgn | TxHeartIgn); in check_link()
1706 writel(np->tx_config, ioaddr + TxConfig); in check_link()
1707 writel(np->rx_config, ioaddr + RxConfig); in check_link()
1718 /* clear any interrupts that are pending, such as wake events */ in init_registers()
1721 writel(np->ring_dma, ioaddr + RxRingPtr); in init_registers()
1722 writel(np->ring_dma + RX_RING_SIZE * sizeof(struct netdev_desc), in init_registers()
1727 * Configure for standard, in-spec Ethernet. in init_registers()
1728 * Start with half-duplex. check_link will update in init_registers()
1739 np->tx_config = TxAutoPad | TxCollRetry | TxMxdma_256 | in init_registers()
1741 writel(np->tx_config, ioaddr + TxConfig); in init_registers()
1746 np->rx_config = RxMxdma_256 | RX_DRTH_VAL; in init_registers()
1748 if (np->rx_buf_sz > NATSEMI_LONGPKT) in init_registers()
1749 np->rx_config |= RxAcceptLong; in init_registers()
1751 writel(np->rx_config, ioaddr + RxConfig); in init_registers()
1759 np->SavedClkRun = readl(ioaddr + ClkRun); in init_registers()
1760 writel(np->SavedClkRun & ~PMEEnable, ioaddr + ClkRun); in init_registers()
1761 if (np->SavedClkRun & PMEStatus && netif_msg_wol(np)) { in init_registers()
1762 printk(KERN_NOTICE "%s: Wake-up event %#08x\n", in init_registers()
1763 dev->name, readl(ioaddr + WOLCmd)); in init_registers()
1780 * 1) check for link changes. Usually they are handled by the MII interrupt
1782 * 2) check for sudden death of the NIC:
1783 * It seems that a reference set for this chip went out with incorrect info,
1785 * drop can cause the PHY to get itself in a weird state (basically reset).
1793 struct net_device *dev = np->dev; in netdev_timer()
1796 const int irq = np->pci_dev->irq; in netdev_timer()
1803 dev->name); in netdev_timer()
1806 if (dev->if_port == PORT_TP) { in netdev_timer()
1809 spin_lock_irq(&np->lock); in netdev_timer()
1810 /* check for a nasty random phy-reset - use dspcfg as a flag */ in netdev_timer()
1814 if (np->dspcfg_workaround && dspcfg != np->dspcfg) { in netdev_timer()
1816 spin_unlock_irq(&np->lock); in netdev_timer()
1818 printk(KERN_NOTICE "%s: possible phy reset: " in netdev_timer()
1819 "re-initializing\n", dev->name); in netdev_timer()
1821 spin_lock_irq(&np->lock); in netdev_timer()
1826 spin_unlock_irq(&np->lock); in netdev_timer()
1831 spin_unlock_irq(&np->lock); in netdev_timer()
1834 /* init_registers() calls check_link() for the above case */ in netdev_timer()
1836 spin_unlock_irq(&np->lock); in netdev_timer()
1839 spin_lock_irq(&np->lock); in netdev_timer()
1841 spin_unlock_irq(&np->lock); in netdev_timer()
1843 if (np->oom) { in netdev_timer()
1845 np->oom = 0; in netdev_timer()
1848 if (!np->oom) { in netdev_timer()
1856 mod_timer(&np->timer, round_jiffies(jiffies + next_tick)); in netdev_timer()
1858 mod_timer(&np->timer, jiffies + next_tick); in netdev_timer()
1867 printk(KERN_DEBUG " Tx ring at %p:\n", np->tx_ring); in dump_ring()
1868 for (i = 0; i < TX_RING_SIZE; i++) { in dump_ring()
1870 i, np->tx_ring[i].next_desc, in dump_ring()
1871 np->tx_ring[i].cmd_status, in dump_ring()
1872 np->tx_ring[i].addr); in dump_ring()
1874 printk(KERN_DEBUG " Rx ring %p:\n", np->rx_ring); in dump_ring()
1875 for (i = 0; i < RX_RING_SIZE; i++) { in dump_ring()
1877 i, np->rx_ring[i].next_desc, in dump_ring()
1878 np->rx_ring[i].cmd_status, in dump_ring()
1879 np->rx_ring[i].addr); in dump_ring()
1888 const int irq = np->pci_dev->irq; in ns_tx_timeout()
1891 spin_lock_irq(&np->lock); in ns_tx_timeout()
1892 if (!np->hands_off) { in ns_tx_timeout()
1897 dev->name, readl(ioaddr + IntrStatus)); in ns_tx_timeout()
1906 dev->name); in ns_tx_timeout()
1908 spin_unlock_irq(&np->lock); in ns_tx_timeout()
1912 dev->stats.tx_errors++; in ns_tx_timeout()
1919 np->rx_ring = dma_alloc_coherent(&np->pci_dev->dev, in alloc_ring()
1921 &np->ring_dma, GFP_KERNEL); in alloc_ring()
1922 if (!np->rx_ring) in alloc_ring()
1923 return -ENOMEM; in alloc_ring()
1924 np->tx_ring = &np->rx_ring[RX_RING_SIZE]; in alloc_ring()
1933 for (; np->cur_rx - np->dirty_rx > 0; np->dirty_rx++) { in refill_rx()
1935 int entry = np->dirty_rx % RX_RING_SIZE; in refill_rx()
1936 if (np->rx_skbuff[entry] == NULL) { in refill_rx()
1937 unsigned int buflen = np->rx_buf_sz+NATSEMI_PADDING; in refill_rx()
1939 np->rx_skbuff[entry] = skb; in refill_rx()
1942 np->rx_dma[entry] = dma_map_single(&np->pci_dev->dev, in refill_rx()
1943 skb->data, buflen, in refill_rx()
1945 if (dma_mapping_error(&np->pci_dev->dev, np->rx_dma[entry])) { in refill_rx()
1947 np->rx_skbuff[entry] = NULL; in refill_rx()
1950 np->rx_ring[entry].addr = cpu_to_le32(np->rx_dma[entry]); in refill_rx()
1952 np->rx_ring[entry].cmd_status = cpu_to_le32(np->rx_buf_sz); in refill_rx()
1954 if (np->cur_rx - np->dirty_rx == RX_RING_SIZE) { in refill_rx()
1956 printk(KERN_WARNING "%s: going OOM.\n", dev->name); in refill_rx()
1957 np->oom = 1; in refill_rx()
1964 if (dev->mtu <= ETH_DATA_LEN) in set_bufsize()
1965 np->rx_buf_sz = ETH_DATA_LEN + NATSEMI_HEADERS; in set_bufsize()
1967 np->rx_buf_sz = dev->mtu + NATSEMI_HEADERS; in set_bufsize()
1977 np->dirty_tx = np->cur_tx = 0; in init_ring()
1978 for (i = 0; i < TX_RING_SIZE; i++) { in init_ring()
1979 np->tx_skbuff[i] = NULL; in init_ring()
1980 np->tx_ring[i].next_desc = cpu_to_le32(np->ring_dma in init_ring()
1983 np->tx_ring[i].cmd_status = 0; in init_ring()
1987 np->dirty_rx = 0; in init_ring()
1988 np->cur_rx = RX_RING_SIZE; in init_ring()
1989 np->oom = 0; in init_ring()
1992 np->rx_head_desc = &np->rx_ring[0]; in init_ring()
1994 /* Please be careful before changing this loop - at least gcc-2.95.1 in init_ring()
1998 for (i = 0; i < RX_RING_SIZE; i++) { in init_ring()
1999 np->rx_ring[i].next_desc = cpu_to_le32(np->ring_dma in init_ring()
2002 np->rx_ring[i].cmd_status = cpu_to_le32(DescOwn); in init_ring()
2003 np->rx_skbuff[i] = NULL; in init_ring()
2014 for (i = 0; i < TX_RING_SIZE; i++) { in drain_tx()
2015 if (np->tx_skbuff[i]) { in drain_tx()
2016 dma_unmap_single(&np->pci_dev->dev, np->tx_dma[i], in drain_tx()
2017 np->tx_skbuff[i]->len, DMA_TO_DEVICE); in drain_tx()
2018 dev_kfree_skb(np->tx_skbuff[i]); in drain_tx()
2019 dev->stats.tx_dropped++; in drain_tx()
2021 np->tx_skbuff[i] = NULL; in drain_tx()
2028 unsigned int buflen = np->rx_buf_sz; in drain_rx()
2032 for (i = 0; i < RX_RING_SIZE; i++) { in drain_rx()
2033 np->rx_ring[i].cmd_status = 0; in drain_rx()
2034 np->rx_ring[i].addr = cpu_to_le32(0xBADF00D0); /* An invalid address. */ in drain_rx()
2035 if (np->rx_skbuff[i]) { in drain_rx()
2036 dma_unmap_single(&np->pci_dev->dev, np->rx_dma[i], in drain_rx()
2039 dev_kfree_skb(np->rx_skbuff[i]); in drain_rx()
2041 np->rx_skbuff[i] = NULL; in drain_rx()
2054 dma_free_coherent(&np->pci_dev->dev, in free_ring()
2056 np->rx_ring, np->ring_dma); in free_ring()
2065 np->dirty_rx = 0; in reinit_rx()
2066 np->cur_rx = RX_RING_SIZE; in reinit_rx()
2067 np->rx_head_desc = &np->rx_ring[0]; in reinit_rx()
2069 for (i = 0; i < RX_RING_SIZE; i++) in reinit_rx()
2070 np->rx_ring[i].cmd_status = cpu_to_le32(DescOwn); in reinit_rx()
2082 np->dirty_tx = np->cur_tx = 0; in reinit_ring()
2083 for (i=0;i<TX_RING_SIZE;i++) in reinit_ring()
2084 np->tx_ring[i].cmd_status = 0; in reinit_ring()
2100 entry = np->cur_tx % TX_RING_SIZE; in start_tx()
2102 np->tx_skbuff[entry] = skb; in start_tx()
2103 np->tx_dma[entry] = dma_map_single(&np->pci_dev->dev, skb->data, in start_tx()
2104 skb->len, DMA_TO_DEVICE); in start_tx()
2105 if (dma_mapping_error(&np->pci_dev->dev, np->tx_dma[entry])) { in start_tx()
2106 np->tx_skbuff[entry] = NULL; in start_tx()
2108 dev->stats.tx_dropped++; in start_tx()
2112 np->tx_ring[entry].addr = cpu_to_le32(np->tx_dma[entry]); in start_tx()
2114 spin_lock_irqsave(&np->lock, flags); in start_tx()
2116 if (!np->hands_off) { in start_tx()
2117 np->tx_ring[entry].cmd_status = cpu_to_le32(DescOwn | skb->len); in start_tx()
2118 /* StrongARM: Explicitly cache flush np->tx_ring and in start_tx()
2119 * skb->data,skb->len. */ in start_tx()
2121 np->cur_tx++; in start_tx()
2122 if (np->cur_tx - np->dirty_tx >= TX_QUEUE_LEN - 1) { in start_tx()
2124 if (np->cur_tx - np->dirty_tx >= TX_QUEUE_LEN - 1) in start_tx()
2127 /* Wake the potentially-idle transmit channel. */ in start_tx()
2131 dev->stats.tx_dropped++; in start_tx()
2133 spin_unlock_irqrestore(&np->lock, flags); in start_tx()
2137 dev->name, np->cur_tx, entry); in start_tx()
2146 for (; np->cur_tx - np->dirty_tx > 0; np->dirty_tx++) { in netdev_tx_done()
2147 int entry = np->dirty_tx % TX_RING_SIZE; in netdev_tx_done()
2148 if (np->tx_ring[entry].cmd_status & cpu_to_le32(DescOwn)) in netdev_tx_done()
2153 dev->name, np->dirty_tx, in netdev_tx_done()
2154 le32_to_cpu(np->tx_ring[entry].cmd_status)); in netdev_tx_done()
2155 if (np->tx_ring[entry].cmd_status & cpu_to_le32(DescPktOK)) { in netdev_tx_done()
2156 dev->stats.tx_packets++; in netdev_tx_done()
2157 dev->stats.tx_bytes += np->tx_skbuff[entry]->len; in netdev_tx_done()
2160 le32_to_cpu(np->tx_ring[entry].cmd_status); in netdev_tx_done()
2162 dev->stats.tx_aborted_errors++; in netdev_tx_done()
2164 dev->stats.tx_fifo_errors++; in netdev_tx_done()
2166 dev->stats.tx_carrier_errors++; in netdev_tx_done()
2168 dev->stats.tx_window_errors++; in netdev_tx_done()
2169 dev->stats.tx_errors++; in netdev_tx_done()
2171 dma_unmap_single(&np->pci_dev->dev, np->tx_dma[entry], in netdev_tx_done()
2172 np->tx_skbuff[entry]->len, DMA_TO_DEVICE); in netdev_tx_done()
2174 dev_consume_skb_irq(np->tx_skbuff[entry]); in netdev_tx_done()
2175 np->tx_skbuff[entry] = NULL; in netdev_tx_done()
2178 np->cur_tx - np->dirty_tx < TX_QUEUE_LEN - 4) { in netdev_tx_done()
2179 /* The ring is no longer full, wake queue. */ in netdev_tx_done()
2193 * that while interrupts are disabled, (for example, while a in intr_handler()
2195 if (np->hands_off || !readl(ioaddr + IntrEnable)) in intr_handler()
2198 np->intr_status = readl(ioaddr + IntrStatus); in intr_handler()
2200 if (!np->intr_status) in intr_handler()
2206 dev->name, np->intr_status, in intr_handler()
2209 prefetch(&np->rx_skbuff[np->cur_rx % RX_RING_SIZE]); in intr_handler()
2211 if (napi_schedule_prep(&np->napi)) { in intr_handler()
2212 /* Disable interrupts and register for poll */ in intr_handler()
2214 __napi_schedule(&np->napi); in intr_handler()
2218 dev->name, np->intr_status, in intr_handler()
2230 struct net_device *dev = np->dev; in natsemi_poll()
2238 dev->name, np->intr_status, in natsemi_poll()
2243 if (np->intr_status & in natsemi_poll()
2249 if (np->intr_status & in natsemi_poll()
2251 spin_lock(&np->lock); in natsemi_poll()
2253 spin_unlock(&np->lock); in natsemi_poll()
2257 if (np->intr_status & IntrAbnormalSummary) in natsemi_poll()
2258 netdev_error(dev, np->intr_status); in natsemi_poll()
2263 np->intr_status = readl(ioaddr + IntrStatus); in natsemi_poll()
2264 } while (np->intr_status); in natsemi_poll()
2270 spin_lock(&np->lock); in natsemi_poll()
2271 if (!np->hands_off) in natsemi_poll()
2273 spin_unlock(&np->lock); in natsemi_poll()
2279 for clarity and better register allocation. */
2283 int entry = np->cur_rx % RX_RING_SIZE; in netdev_rx()
2284 int boguscnt = np->dirty_rx + RX_RING_SIZE - np->cur_rx; in netdev_rx()
2285 s32 desc_status = le32_to_cpu(np->rx_head_desc->cmd_status); in netdev_rx()
2286 unsigned int buflen = np->rx_buf_sz; in netdev_rx()
2296 if (--boguscnt < 0) in netdev_rx()
2304 pkt_len = (desc_status & DescSizeMask) - 4; in netdev_rx()
2314 "status %#08x.\n", dev->name, in netdev_rx()
2315 np->cur_rx, desc_status); in netdev_rx()
2316 dev->stats.rx_length_errors++; in netdev_rx()
2321 * AN-1287. */ in netdev_rx()
2323 spin_lock_irqsave(&np->lock, flags); in netdev_rx()
2326 writel(np->ring_dma, ioaddr + RxRingPtr); in netdev_rx()
2328 spin_unlock_irqrestore(&np->lock, flags); in netdev_rx()
2336 dev->stats.rx_errors++; in netdev_rx()
2338 dev->stats.rx_over_errors++; in netdev_rx()
2340 dev->stats.rx_length_errors++; in netdev_rx()
2342 dev->stats.rx_frame_errors++; in netdev_rx()
2344 dev->stats.rx_crc_errors++; in netdev_rx()
2346 } else if (pkt_len > np->rx_buf_sz) { in netdev_rx()
2355 * without copying to a minimally-sized skbuff. */ in netdev_rx()
2360 dma_sync_single_for_cpu(&np->pci_dev->dev, in netdev_rx()
2361 np->rx_dma[entry], in netdev_rx()
2365 np->rx_skbuff[entry]->data, pkt_len); in netdev_rx()
2367 dma_sync_single_for_device(&np->pci_dev->dev, in netdev_rx()
2368 np->rx_dma[entry], in netdev_rx()
2372 dma_unmap_single(&np->pci_dev->dev, in netdev_rx()
2373 np->rx_dma[entry], in netdev_rx()
2376 skb_put(skb = np->rx_skbuff[entry], pkt_len); in netdev_rx()
2377 np->rx_skbuff[entry] = NULL; in netdev_rx()
2379 skb->protocol = eth_type_trans(skb, dev); in netdev_rx()
2381 dev->stats.rx_packets++; in netdev_rx()
2382 dev->stats.rx_bytes += pkt_len; in netdev_rx()
2384 entry = (++np->cur_rx) % RX_RING_SIZE; in netdev_rx()
2385 np->rx_head_desc = &np->rx_ring[entry]; in netdev_rx()
2386 desc_status = le32_to_cpu(np->rx_head_desc->cmd_status); in netdev_rx()
2391 if (np->oom) in netdev_rx()
2392 mod_timer(&np->timer, jiffies + 1); in netdev_rx()
2402 spin_lock(&np->lock); in netdev_error()
2409 " %#04x partner %#04x.\n", dev->name, in netdev_error()
2410 np->advertising, lpa); in netdev_error()
2421 if ((np->tx_config & TxDrthMask) < TX_DRTH_VAL_LIMIT) { in netdev_error()
2422 np->tx_config += TX_DRTH_VAL_INC; in netdev_error()
2426 dev->name, np->tx_config); in netdev_error()
2431 dev->name, np->tx_config); in netdev_error()
2433 writel(np->tx_config, ioaddr + TxConfig); in netdev_error()
2437 printk(KERN_NOTICE "%s: Link wake-up event %#08x\n", in netdev_error()
2438 dev->name, wol_status); in netdev_error()
2443 dev->name); in netdev_error()
2445 dev->stats.rx_fifo_errors++; in netdev_error()
2446 dev->stats.rx_errors++; in netdev_error()
2450 printk(KERN_NOTICE "%s: PCI error %#08x\n", dev->name, in netdev_error()
2452 dev->stats.tx_fifo_errors++; in netdev_error()
2453 dev->stats.tx_errors++; in netdev_error()
2454 dev->stats.rx_fifo_errors++; in netdev_error()
2455 dev->stats.rx_errors++; in netdev_error()
2457 spin_unlock(&np->lock); in netdev_error()
2464 /* The chip only need report frame silently dropped. */ in __get_stats()
2465 dev->stats.rx_crc_errors += readl(ioaddr + RxCRCErrs); in __get_stats()
2466 dev->stats.rx_missed_errors += readl(ioaddr + RxMissed); in __get_stats()
2473 /* The chip only need report frame silently dropped. */ in get_stats()
2474 spin_lock_irq(&np->lock); in get_stats()
2475 if (netif_running(dev) && !np->hands_off) in get_stats()
2477 spin_unlock_irq(&np->lock); in get_stats()
2479 return &dev->stats; in get_stats()
2486 const int irq = np->pci_dev->irq; in natsemi_poll_controller()
2502 if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ in __set_rx_mode()
2506 (dev->flags & IFF_ALLMULTI)) { in __set_rx_mode()
2515 int b = (ether_crc(ETH_ALEN, ha->addr) >> 23) & 0x1ff; in __set_rx_mode()
2520 for (i = 0; i < 64; i += 2) { in __set_rx_mode()
2527 np->cur_rx_mode = rx_mode; in __set_rx_mode()
2532 dev->mtu = new_mtu; in natsemi_change_mtu()
2538 const int irq = np->pci_dev->irq; in natsemi_change_mtu()
2541 spin_lock(&np->lock); in natsemi_change_mtu()
2549 writel(np->ring_dma, ioaddr + RxRingPtr); in natsemi_change_mtu()
2552 spin_unlock(&np->lock); in natsemi_change_mtu()
2561 spin_lock_irq(&np->lock); in set_rx_mode()
2562 if (!np->hands_off) in set_rx_mode()
2564 spin_unlock_irq(&np->lock); in set_rx_mode()
2570 strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); in get_drvinfo()
2571 strlcpy(info->version, DRV_VERSION, sizeof(info->version)); in get_drvinfo()
2572 strlcpy(info->bus_info, pci_name(np->pci_dev), sizeof(info->bus_info)); in get_drvinfo()
2583 return np->eeprom_size; in get_eeprom_len()
2590 spin_lock_irq(&np->lock); in get_link_ksettings()
2592 spin_unlock_irq(&np->lock); in get_link_ksettings()
2601 spin_lock_irq(&np->lock); in set_link_ksettings()
2603 spin_unlock_irq(&np->lock); in set_link_ksettings()
2610 spin_lock_irq(&np->lock); in get_wol()
2611 netdev_get_wol(dev, &wol->supported, &wol->wolopts); in get_wol()
2612 netdev_get_sopass(dev, wol->sopass); in get_wol()
2613 spin_unlock_irq(&np->lock); in get_wol()
2620 spin_lock_irq(&np->lock); in set_wol()
2621 netdev_set_wol(dev, wol->wolopts); in set_wol()
2622 res = netdev_set_sopass(dev, wol->sopass); in set_wol()
2623 spin_unlock_irq(&np->lock); in set_wol()
2630 regs->version = NATSEMI_REGS_VER; in get_regs()
2631 spin_lock_irq(&np->lock); in get_regs()
2633 spin_unlock_irq(&np->lock); in get_regs()
2639 return np->msg_enable; in get_msglevel()
2645 np->msg_enable = val; in set_msglevel()
2651 int r = -EINVAL; in nway_reset()
2664 /* LSTATUS is latched low until a read - so read twice */ in get_link()
2675 eebuf = kmalloc(np->eeprom_size, GFP_KERNEL); in get_eeprom()
2677 return -ENOMEM; in get_eeprom()
2679 eeprom->magic = PCI_VENDOR_ID_NS | (PCI_DEVICE_ID_NS_83815<<16); in get_eeprom()
2680 spin_lock_irq(&np->lock); in get_eeprom()
2682 spin_unlock_irq(&np->lock); in get_eeprom()
2684 memcpy(data, eebuf+eeprom->offset, eeprom->len); in get_eeprom()
2724 if (np->srr >= SRR_DP83815_D) { in netdev_set_wol()
2744 if (np->srr >= SRR_DP83815_D) { in netdev_get_wol()
2778 if (np->srr < SRR_DP83815_D) { in netdev_set_sopass()
2797 /* re-enable the RX filter */ in netdev_set_sopass()
2810 if (np->srr < SRR_DP83815_D) { in netdev_get_sopass()
2839 ecmd->base.port = dev->if_port; in netdev_get_ecmd()
2840 ecmd->base.speed = np->speed; in netdev_get_ecmd()
2841 ecmd->base.duplex = np->duplex; in netdev_get_ecmd()
2842 ecmd->base.autoneg = np->autoneg; in netdev_get_ecmd()
2845 if (np->advertising & ADVERTISE_10HALF) in netdev_get_ecmd()
2847 if (np->advertising & ADVERTISE_10FULL) in netdev_get_ecmd()
2849 if (np->advertising & ADVERTISE_100HALF) in netdev_get_ecmd()
2851 if (np->advertising & ADVERTISE_100FULL) in netdev_get_ecmd()
2857 ecmd->base.phy_address = np->phy_addr_external; in netdev_get_ecmd()
2859 * We intentionally report the phy address of the external in netdev_get_ecmd()
2860 * phy, even if the internal phy is used. This is necessary in netdev_get_ecmd()
2864 * # ethtool -s ethX port mii in netdev_get_ecmd()
2866 * settings that are used for the current active port. in netdev_get_ecmd()
2867 * If we would report a different phy address in this in netdev_get_ecmd()
2869 * # ethtool -s ethX port tp;ethtool -s ethX port mii in netdev_get_ecmd()
2870 * would unintentionally change the phy address. in netdev_get_ecmd()
2872 * Fortunately the phy address doesn't matter with the in netdev_get_ecmd()
2873 * internal phy... in netdev_get_ecmd()
2877 switch (ecmd->base.port) { in netdev_get_ecmd()
2891 if (ecmd->base.autoneg == AUTONEG_ENABLE) { in netdev_get_ecmd()
2894 np->advertising & mdio_read(dev, MII_LPA)); in netdev_get_ecmd()
2896 ecmd->base.speed = SPEED_100; in netdev_get_ecmd()
2898 ecmd->base.speed = SPEED_10; in netdev_get_ecmd()
2900 ecmd->base.duplex = DUPLEX_FULL; in netdev_get_ecmd()
2902 ecmd->base.duplex = DUPLEX_HALF; in netdev_get_ecmd()
2905 /* ignore maxtxpkt, maxrxpkt for now */ in netdev_get_ecmd()
2907 ethtool_convert_legacy_u32_to_link_mode(ecmd->link_modes.supported, in netdev_get_ecmd()
2909 ethtool_convert_legacy_u32_to_link_mode(ecmd->link_modes.advertising, in netdev_get_ecmd()
2922 ecmd->link_modes.advertising); in netdev_set_ecmd()
2924 if (ecmd->base.port != PORT_TP && in netdev_set_ecmd()
2925 ecmd->base.port != PORT_MII && in netdev_set_ecmd()
2926 ecmd->base.port != PORT_FIBRE) in netdev_set_ecmd()
2927 return -EINVAL; in netdev_set_ecmd()
2928 if (ecmd->base.autoneg == AUTONEG_ENABLE) { in netdev_set_ecmd()
2933 return -EINVAL; in netdev_set_ecmd()
2935 } else if (ecmd->base.autoneg == AUTONEG_DISABLE) { in netdev_set_ecmd()
2936 u32 speed = ecmd->base.speed; in netdev_set_ecmd()
2938 return -EINVAL; in netdev_set_ecmd()
2939 if (ecmd->base.duplex != DUPLEX_HALF && in netdev_set_ecmd()
2940 ecmd->base.duplex != DUPLEX_FULL) in netdev_set_ecmd()
2941 return -EINVAL; in netdev_set_ecmd()
2943 return -EINVAL; in netdev_set_ecmd()
2947 * If we're ignoring the PHY then autoneg and the internal in netdev_set_ecmd()
2951 if (np->ignore_phy && (ecmd->base.autoneg == AUTONEG_ENABLE || in netdev_set_ecmd()
2952 ecmd->base.port == PORT_TP)) in netdev_set_ecmd()
2953 return -EINVAL; in netdev_set_ecmd()
2956 * maxtxpkt, maxrxpkt: ignored for now. in netdev_set_ecmd()
2960 * XCVR_EXTERNAL. The implementation thus ignores ecmd->transceiver and in netdev_set_ecmd()
2961 * selects based on ecmd->port. in netdev_set_ecmd()
2963 * Actually PORT_FIBRE is nearly identical to PORT_MII: it's for fibre in netdev_set_ecmd()
2971 dev->if_port = ecmd->base.port; in netdev_set_ecmd()
2972 np->autoneg = ecmd->base.autoneg; in netdev_set_ecmd()
2973 np->phy_addr_external = ecmd->base.phy_address & PhyAddrMask; in netdev_set_ecmd()
2974 if (np->autoneg == AUTONEG_ENABLE) { in netdev_set_ecmd()
2976 np->advertising &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4); in netdev_set_ecmd()
2978 np->advertising |= ADVERTISE_10HALF; in netdev_set_ecmd()
2980 np->advertising |= ADVERTISE_10FULL; in netdev_set_ecmd()
2982 np->advertising |= ADVERTISE_100HALF; in netdev_set_ecmd()
2984 np->advertising |= ADVERTISE_100FULL; in netdev_set_ecmd()
2986 np->speed = ecmd->base.speed; in netdev_set_ecmd()
2987 np->duplex = ecmd->base.duplex; in netdev_set_ecmd()
2989 if (np->duplex == DUPLEX_HALF) in netdev_set_ecmd()
2990 np->full_duplex = 0; in netdev_set_ecmd()
2993 /* get the right phy enabled */ in netdev_set_ecmd()
2994 if (ecmd->base.port == PORT_TP) in netdev_set_ecmd()
3013 /* read non-mii page 0 of registers */ in netdev_get_regs()
3014 for (i = 0; i < NATSEMI_PG0_NREGS/2; i++) { in netdev_get_regs()
3019 for (i = NATSEMI_PG0_NREGS/2; i < NATSEMI_PG0_NREGS; i++) in netdev_get_regs()
3032 for (j = 0; j < NATSEMI_RFDR_NREGS; j++) { in netdev_get_regs()
3038 /* the interrupt status is clear-on-read - see if we missed any */ in netdev_get_regs()
3042 dev->name, rbuf[4] & rbuf[5]); in netdev_get_regs()
3065 for (i = 0; i < np->eeprom_size/2; i++) { in netdev_get_eeprom()
3067 /* The EEPROM itself stores data bit-swapped, but eeprom_read in netdev_get_eeprom()
3081 case SIOCGMIIPHY: /* Get address of MII PHY in use. */ in netdev_ioctl()
3082 data->phy_id = np->phy_addr_external; in netdev_ioctl()
3085 case SIOCGMIIREG: /* Read MII PHY register. */ in netdev_ioctl()
3090 if (dev->if_port == PORT_TP) { in netdev_ioctl()
3091 if ((data->phy_id & 0x1f) == np->phy_addr_external) in netdev_ioctl()
3092 data->val_out = mdio_read(dev, in netdev_ioctl()
3093 data->reg_num & 0x1f); in netdev_ioctl()
3095 data->val_out = 0; in netdev_ioctl()
3097 move_int_phy(dev, data->phy_id & 0x1f); in netdev_ioctl()
3098 data->val_out = miiport_read(dev, data->phy_id & 0x1f, in netdev_ioctl()
3099 data->reg_num & 0x1f); in netdev_ioctl()
3103 case SIOCSMIIREG: /* Write MII PHY register. */ in netdev_ioctl()
3104 if (dev->if_port == PORT_TP) { in netdev_ioctl()
3105 if ((data->phy_id & 0x1f) == np->phy_addr_external) { in netdev_ioctl()
3106 if ((data->reg_num & 0x1f) == MII_ADVERTISE) in netdev_ioctl()
3107 np->advertising = data->val_in; in netdev_ioctl()
3108 mdio_write(dev, data->reg_num & 0x1f, in netdev_ioctl()
3109 data->val_in); in netdev_ioctl()
3112 if ((data->phy_id & 0x1f) == np->phy_addr_external) { in netdev_ioctl()
3113 if ((data->reg_num & 0x1f) == MII_ADVERTISE) in netdev_ioctl()
3114 np->advertising = data->val_in; in netdev_ioctl()
3116 move_int_phy(dev, data->phy_id & 0x1f); in netdev_ioctl()
3117 miiport_write(dev, data->phy_id & 0x1f, in netdev_ioctl()
3118 data->reg_num & 0x1f, in netdev_ioctl()
3119 data->val_in); in netdev_ioctl()
3123 return -EOPNOTSUPP; in netdev_ioctl()
3133 printk(KERN_INFO "%s: remaining active for wake-on-lan\n", in enable_wol_mode()
3134 dev->name); in enable_wol_mode()
3136 /* For WOL we must restart the rx process in silent mode. in enable_wol_mode()
3146 writel(np->SavedClkRun | PMEEnable | PMEStatus, ioaddr + ClkRun); in enable_wol_mode()
3164 const int irq = np->pci_dev->irq; in netdev_close()
3169 dev->name, (int)readl(ioaddr + ChipCmd)); in netdev_close()
3173 dev->name, np->cur_tx, np->dirty_tx, in netdev_close()
3174 np->cur_rx, np->dirty_rx); in netdev_close()
3176 napi_disable(&np->napi); in netdev_close()
3185 del_timer_sync(&np->timer); in netdev_close()
3187 spin_lock_irq(&np->lock); in netdev_close()
3189 np->hands_off = 1; in netdev_close()
3190 spin_unlock_irq(&np->lock); in netdev_close()
3199 spin_lock_irq(&np->lock); in netdev_close()
3200 np->hands_off = 0; in netdev_close()
3211 spin_unlock_irq(&np->lock); in netdev_close()
3213 /* clear the carrier last - an interrupt could reenable it otherwise */ in netdev_close()
3225 * The nic must be stopped for this. in netdev_close()
3230 writel(np->SavedClkRun, ioaddr + ClkRun); in netdev_close()
3251 * Kicking the Rx or Tx process for a new packet reenables the Rx process
3259 * No function accesses the hardware without checking np->hands_off.
3260 * the check occurs under spin_lock_irq(&np->lock);
3283 const int irq = np->pci_dev->irq; in natsemi_suspend()
3285 del_timer_sync(&np->timer); in natsemi_suspend()
3288 spin_lock_irq(&np->lock); in natsemi_suspend()
3291 np->hands_off = 1; in natsemi_suspend()
3295 spin_unlock_irq(&np->lock); in natsemi_suspend()
3298 napi_disable(&np->napi); in natsemi_suspend()
3303 /* pci_power_off(pdev, -1); */ in natsemi_suspend()
3310 * The nic must be stopped for this. in natsemi_suspend()
3316 writel(np->SavedClkRun, ioaddr + ClkRun); in natsemi_suspend()
3335 const int irq = np->pci_dev->irq; in natsemi_resume()
3337 BUG_ON(!np->hands_off); in natsemi_resume()
3340 napi_enable(&np->napi); in natsemi_resume()
3345 spin_lock_irq(&np->lock); in natsemi_resume()
3346 np->hands_off = 0; in natsemi_resume()
3349 spin_unlock_irq(&np->lock); in natsemi_resume()
3352 mod_timer(&np->timer, round_jiffies(jiffies + 1*HZ)); in natsemi_resume()