Merge branch 'upstream-fixes'
Jeff Garzik [Tue, 4 Oct 2005 09:30:02 +0000 (05:30 -0400)]
121 files changed:
drivers/net/8139cp.c
drivers/net/8139too.c
drivers/net/Kconfig
drivers/net/Makefile
drivers/net/b44.c
drivers/net/e100.c
drivers/net/e1000/e1000_ethtool.c
drivers/net/e1000/e1000_main.c
drivers/net/forcedeth.c
drivers/net/gianfar.c
drivers/net/gianfar.h
drivers/net/gianfar_ethtool.c
drivers/net/gianfar_mii.c [new file with mode: 0644]
drivers/net/gianfar_mii.h [new file with mode: 0644]
drivers/net/gianfar_phy.c [deleted file]
drivers/net/gianfar_phy.h [deleted file]
drivers/net/hp100.c
drivers/net/irda/stir4200.c
drivers/net/ixgb/ixgb_ethtool.c
drivers/net/ixgb/ixgb_main.c
drivers/net/lne390.c
drivers/net/mii.c
drivers/net/ne2k-pci.c
drivers/net/ns83820.c
drivers/net/pcnet32.c
drivers/net/phy/Kconfig
drivers/net/phy/phy.c
drivers/net/phy/phy_device.c
drivers/net/r8169.c
drivers/net/rionet.c [new file with mode: 0644]
drivers/net/skge.c
drivers/net/sundance.c
drivers/net/tokenring/ibmtr.c
drivers/net/tokenring/olympic.c
drivers/net/tokenring/tms380tr.c
drivers/net/typhoon.c
drivers/net/via-rhine.c
drivers/net/wan/cosa.c
drivers/net/wan/cycx_drv.c
drivers/net/wan/cycx_main.c
drivers/net/wan/cycx_x25.c
drivers/net/wan/dscc4.c
drivers/net/wan/farsync.c
drivers/net/wan/hdlc_fr.c
drivers/net/wan/lmc/lmc_debug.c
drivers/net/wan/lmc/lmc_media.c
drivers/net/wan/pc300.h
drivers/net/wan/pc300_drv.c
drivers/net/wan/pc300_tty.c
drivers/net/wan/sdla.c
drivers/net/wan/sdla_fr.c
drivers/net/wan/sdla_x25.c
drivers/net/wan/sdladrv.c
drivers/net/wan/syncppp.c
drivers/net/wireless/airo.c
drivers/net/wireless/airport.c
drivers/net/wireless/atmel.c
drivers/net/wireless/hermes.c
drivers/net/wireless/hermes.h
drivers/net/wireless/hostap/hostap.c
drivers/net/wireless/hostap/hostap_80211_rx.c
drivers/net/wireless/hostap/hostap_80211_tx.c
drivers/net/wireless/hostap/hostap_ap.c
drivers/net/wireless/hostap/hostap_ap.h
drivers/net/wireless/hostap/hostap_cs.c
drivers/net/wireless/hostap/hostap_hw.c
drivers/net/wireless/hostap/hostap_ioctl.c
drivers/net/wireless/hostap/hostap_pci.c
drivers/net/wireless/hostap/hostap_plx.c
drivers/net/wireless/hostap/hostap_wlan.h
drivers/net/wireless/ipw2100.c
drivers/net/wireless/ipw2100.h
drivers/net/wireless/ipw2200.c
drivers/net/wireless/ipw2200.h
drivers/net/wireless/netwave_cs.c
drivers/net/wireless/orinoco.c
drivers/net/wireless/orinoco.h
drivers/net/wireless/orinoco_cs.c
drivers/net/wireless/orinoco_nortel.c
drivers/net/wireless/orinoco_pci.c
drivers/net/wireless/orinoco_plx.c
drivers/net/wireless/orinoco_tmd.c
drivers/net/wireless/prism54/isl_ioctl.c
drivers/net/wireless/prism54/islpci_dev.c
drivers/net/wireless/prism54/islpci_dev.h
drivers/net/wireless/prism54/islpci_mgt.c
drivers/net/wireless/ray_cs.c
drivers/net/wireless/spectrum_cs.c
drivers/net/wireless/wavelan.c
drivers/net/wireless/wavelan.p.h
drivers/net/wireless/wavelan_cs.c
drivers/net/wireless/wavelan_cs.p.h
drivers/net/wireless/wl3501.h
drivers/s390/net/qeth.h
drivers/s390/net/qeth_fs.h
drivers/s390/net/qeth_main.c
drivers/s390/net/qeth_mpc.c
drivers/s390/net/qeth_mpc.h
drivers/s390/net/qeth_sys.c
include/linux/cyclomx.h
include/linux/cycx_drv.h
include/linux/ibmtr.h
include/linux/if_arp.h
include/linux/mii.h
include/linux/netdevice.h
include/linux/sdladrv.h
include/linux/wanpipe.h
include/net/ieee80211.h
include/net/ieee80211_crypt.h
include/net/ieee80211_radiotap.h [new file with mode: 0644]
include/net/syncppp.h
net/ieee80211/Makefile
net/ieee80211/ieee80211_crypt.c
net/ieee80211/ieee80211_crypt_ccmp.c
net/ieee80211/ieee80211_crypt_tkip.c
net/ieee80211/ieee80211_crypt_wep.c
net/ieee80211/ieee80211_geo.c [new file with mode: 0644]
net/ieee80211/ieee80211_module.c
net/ieee80211/ieee80211_rx.c
net/ieee80211/ieee80211_tx.c
net/ieee80211/ieee80211_wx.c

index bc53744..f822cd3 100644 (file)
@@ -1027,8 +1027,7 @@ static void cp_reset_hw (struct cp_private *cp)
                if (!(cpr8(Cmd) & CmdReset))
                        return;
 
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(10);
+               schedule_timeout_uninterruptible(10);
        }
 
        printk(KERN_ERR "%s: hardware reset timeout\n", cp->dev->name);
@@ -1575,6 +1574,7 @@ static struct ethtool_ops cp_ethtool_ops = {
        .set_wol                = cp_set_wol,
        .get_strings            = cp_get_strings,
        .get_ethtool_stats      = cp_get_ethtool_stats,
+       .get_perm_addr          = ethtool_op_get_perm_addr,
 };
 
 static int cp_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
@@ -1773,6 +1773,7 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        for (i = 0; i < 3; i++)
                ((u16 *) (dev->dev_addr))[i] =
                    le16_to_cpu (read_eeprom (regs, i + 7, addr_len));
+       memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
        dev->open = cp_open;
        dev->stop = cp_close;
index 4c2cf7b..76ef6ef 100644 (file)
@@ -970,6 +970,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
        for (i = 0; i < 3; i++)
                ((u16 *) (dev->dev_addr))[i] =
                    le16_to_cpu (read_eeprom (ioaddr, i + 7, addr_len));
+       memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
        /* The Rtl8139-specific entries in the device structure. */
        dev->open = rtl8139_open;
@@ -2465,6 +2466,7 @@ static struct ethtool_ops rtl8139_ethtool_ops = {
        .get_strings            = rtl8139_get_strings,
        .get_stats_count        = rtl8139_get_stats_count,
        .get_ethtool_stats      = rtl8139_get_ethtool_stats,
+       .get_perm_addr          = ethtool_op_get_perm_addr,
 };
 
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
index c748b0e..0a30368 100644 (file)
@@ -2083,6 +2083,7 @@ config SPIDER_NET
 config GIANFAR
        tristate "Gianfar Ethernet"
        depends on 85xx || 83xx
+       select PHYLIB
        help
          This driver supports the Gigabit TSEC on the MPC85xx 
          family of chips, and the FEC on the 8540
@@ -2243,6 +2244,20 @@ config ISERIES_VETH
        tristate "iSeries Virtual Ethernet driver support"
        depends on PPC_ISERIES
 
+config RIONET
+       tristate "RapidIO Ethernet over messaging driver support"
+       depends on NETDEVICES && RAPIDIO
+
+config RIONET_TX_SIZE
+       int "Number of outbound queue entries"
+       depends on RIONET
+       default "128"
+
+config RIONET_RX_SIZE
+       int "Number of inbound queue entries"
+       depends on RIONET
+       default "128"
+
 config FDDI
        bool "FDDI driver support"
        depends on (PCI || EISA)
index 8aeec9f..4c9477c 100644 (file)
@@ -13,7 +13,7 @@ obj-$(CONFIG_CHELSIO_T1) += chelsio/
 obj-$(CONFIG_BONDING) += bonding/
 obj-$(CONFIG_GIANFAR) += gianfar_driver.o
 
-gianfar_driver-objs := gianfar.o gianfar_ethtool.o gianfar_phy.o
+gianfar_driver-objs := gianfar.o gianfar_ethtool.o gianfar_mii.o
 
 #
 # link order important here
@@ -64,6 +64,7 @@ obj-$(CONFIG_SKFP) += skfp/
 obj-$(CONFIG_VIA_RHINE) += via-rhine.o
 obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o
 obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o
+obj-$(CONFIG_RIONET) += rionet.o
 
 #
 # end link order section
index 94939f5..d27e870 100644 (file)
@@ -1676,6 +1676,7 @@ static struct ethtool_ops b44_ethtool_ops = {
        .set_pauseparam         = b44_set_pauseparam,
        .get_msglevel           = b44_get_msglevel,
        .set_msglevel           = b44_set_msglevel,
+       .get_perm_addr          = ethtool_op_get_perm_addr,
 };
 
 static int b44_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
@@ -1718,6 +1719,7 @@ static int __devinit b44_get_invariants(struct b44 *bp)
        bp->dev->dev_addr[3] = eeprom[80];
        bp->dev->dev_addr[4] = eeprom[83];
        bp->dev->dev_addr[5] = eeprom[82];
+       memcpy(bp->dev->perm_addr, bp->dev->dev_addr, bp->dev->addr_len);
 
        bp->phy_addr = eeprom[90] & 0x1f;
 
index fbf1c06..c15406d 100644 (file)
@@ -2389,6 +2389,7 @@ static struct ethtool_ops e100_ethtool_ops = {
        .phys_id                = e100_phys_id,
        .get_stats_count        = e100_get_stats_count,
        .get_ethtool_stats      = e100_get_ethtool_stats,
+       .get_perm_addr          = ethtool_op_get_perm_addr,
 };
 
 static int e100_do_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
@@ -2539,7 +2540,8 @@ static int __devinit e100_probe(struct pci_dev *pdev,
        e100_phy_init(nic);
 
        memcpy(netdev->dev_addr, nic->eeprom, ETH_ALEN);
-       if(!is_valid_ether_addr(netdev->dev_addr)) {
+       memcpy(netdev->perm_addr, nic->eeprom, ETH_ALEN);
+       if(!is_valid_ether_addr(netdev->perm_addr)) {
                DPRINTK(PROBE, ERR, "Invalid MAC address from "
                        "EEPROM, aborting.\n");
                err = -EAGAIN;
index f133ff0..8f3a134 100644 (file)
@@ -1739,6 +1739,7 @@ struct ethtool_ops e1000_ethtool_ops = {
        .phys_id                = e1000_phys_id,
        .get_stats_count        = e1000_get_stats_count,
        .get_ethtool_stats      = e1000_get_ethtool_stats,
+       .get_perm_addr          = ethtool_op_get_perm_addr,
 };
 
 void e1000_set_ethtool_ops(struct net_device *netdev)
index ee687c9..c062b0a 100644 (file)
@@ -614,8 +614,9 @@ e1000_probe(struct pci_dev *pdev,
        if(e1000_read_mac_addr(&adapter->hw))
                DPRINTK(PROBE, ERR, "EEPROM Read Error\n");
        memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
+       memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len);
 
-       if(!is_valid_ether_addr(netdev->dev_addr)) {
+       if(!is_valid_ether_addr(netdev->perm_addr)) {
                DPRINTK(PROBE, ERR, "Invalid MAC Address\n");
                err = -EIO;
                goto err_eeprom;
index d6eefdb..e5f4802 100644 (file)
@@ -95,6 +95,7 @@
  *                        of nv_remove
  *      0.42: 06 Aug 2005: Fix lack of link speed initialization
  *                        in the second (and later) nv_open call
+ *      0.43: 10 Aug 2005: Add support for tx checksum.
  *
  * Known bugs:
  * We suspect that on some hardware no TX done interrupts are generated.
  * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
  * superfluous timer interrupts from the nic.
  */
-#define FORCEDETH_VERSION              "0.41"
+#define FORCEDETH_VERSION              "0.43"
 #define DRV_NAME                       "forcedeth"
 
 #include <linux/module.h>
 #define DEV_NEED_LINKTIMER     0x0002  /* poll link settings. Relies on the timer irq */
 #define DEV_HAS_LARGEDESC      0x0004  /* device supports jumbo frames and needs packet format 2 */
 #define DEV_HAS_HIGH_DMA        0x0008  /* device supports 64bit dma */
+#define DEV_HAS_CHECKSUM        0x0010  /* device supports tx and rx checksum offloads */
 
 enum {
        NvRegIrqStatus = 0x000,
@@ -241,6 +243,9 @@ enum {
 #define NVREG_TXRXCTL_IDLE     0x0008
 #define NVREG_TXRXCTL_RESET    0x0010
 #define NVREG_TXRXCTL_RXCHECK  0x0400
+#define NVREG_TXRXCTL_DESC_1   0
+#define NVREG_TXRXCTL_DESC_2   0x02100
+#define NVREG_TXRXCTL_DESC_3   0x02200
        NvRegMIIStatus = 0x180,
 #define NVREG_MIISTAT_ERROR            0x0001
 #define NVREG_MIISTAT_LINKCHANGE       0x0008
@@ -335,6 +340,8 @@ typedef union _ring_type {
 /* error and valid are the same for both */
 #define NV_TX2_ERROR           (1<<30)
 #define NV_TX2_VALID           (1<<31)
+#define NV_TX2_CHECKSUM_L3     (1<<27)
+#define NV_TX2_CHECKSUM_L4     (1<<26)
 
 #define NV_RX_DESCRIPTORVALID  (1<<16)
 #define NV_RX_MISSEDFRAME      (1<<17)
@@ -417,14 +424,14 @@ typedef union _ring_type {
 
 /* 
  * desc_ver values:
- * This field has two purposes:
- * - Newer nics uses a different ring layout. The layout is selected by
- *   comparing np->desc_ver with DESC_VER_xy.
- * - It contains bits that are forced on when writing to NvRegTxRxControl.
+ * The nic supports three different descriptor types:
+ * - DESC_VER_1: Original
+ * - DESC_VER_2: support for jumbo frames.
+ * - DESC_VER_3: 64-bit format.
  */
-#define DESC_VER_1     0x0
-#define DESC_VER_2     (0x02100|NVREG_TXRXCTL_RXCHECK)
-#define DESC_VER_3      (0x02200|NVREG_TXRXCTL_RXCHECK)
+#define DESC_VER_1     1
+#define DESC_VER_2     2
+#define DESC_VER_3     3
 
 /* PHY defines */
 #define PHY_OUI_MARVELL        0x5043
@@ -491,6 +498,7 @@ struct fe_priv {
        u32 orig_mac[2];
        u32 irqmask;
        u32 desc_ver;
+       u32 txrxctl_bits;
 
        void __iomem *base;
 
@@ -786,10 +794,10 @@ static void nv_txrx_reset(struct net_device *dev)
        u8 __iomem *base = get_hwbase(dev);
 
        dprintk(KERN_DEBUG "%s: nv_txrx_reset\n", dev->name);
-       writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->desc_ver, base + NvRegTxRxControl);
+       writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->txrxctl_bits, base + NvRegTxRxControl);
        pci_push(base);
        udelay(NV_TXRX_RESET_DELAY);
-       writel(NVREG_TXRXCTL_BIT2 | np->desc_ver, base + NvRegTxRxControl);
+       writel(NVREG_TXRXCTL_BIT2 | np->txrxctl_bits, base + NvRegTxRxControl);
        pci_push(base);
 }
 
@@ -961,6 +969,7 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct fe_priv *np = get_nvpriv(dev);
        int nr = np->next_tx % TX_RING;
+       u32 tx_checksum = (skb->ip_summed == CHECKSUM_HW ? (NV_TX2_CHECKSUM_L3|NV_TX2_CHECKSUM_L4) : 0);
 
        np->tx_skbuff[nr] = skb;
        np->tx_dma[nr] = pci_map_single(np->pci_dev, skb->data,skb->len,
@@ -976,10 +985,10 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
        spin_lock_irq(&np->lock);
        wmb();
        if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2)
-               np->tx_ring.orig[nr].FlagLen = cpu_to_le32( (skb->len-1) | np->tx_flags );
+               np->tx_ring.orig[nr].FlagLen = cpu_to_le32( (skb->len-1) | np->tx_flags | tx_checksum);
        else
-               np->tx_ring.ex[nr].FlagLen = cpu_to_le32( (skb->len-1) | np->tx_flags );
-       dprintk(KERN_DEBUG "%s: nv_start_xmit: packet packet %d queued for transmission.\n",
+               np->tx_ring.ex[nr].FlagLen = cpu_to_le32( (skb->len-1) | np->tx_flags | tx_checksum);
+       dprintk(KERN_DEBUG "%s: nv_start_xmit: packet packet %d queued for transmission\n",
                                dev->name, np->next_tx);
        {
                int j;
@@ -997,7 +1006,7 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
        if (np->next_tx - np->nic_tx >= TX_LIMIT_STOP)
                netif_stop_queue(dev);
        spin_unlock_irq(&np->lock);
-       writel(NVREG_TXRXCTL_KICK|np->desc_ver, get_hwbase(dev) + NvRegTxRxControl);
+       writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl);
        pci_push(get_hwbase(dev));
        return 0;
 }
@@ -1408,7 +1417,7 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu)
                writel( ((RX_RING-1) << NVREG_RINGSZ_RXSHIFT) + ((TX_RING-1) << NVREG_RINGSZ_TXSHIFT),
                        base + NvRegRingSizes);
                pci_push(base);
-               writel(NVREG_TXRXCTL_KICK|np->desc_ver, get_hwbase(dev) + NvRegTxRxControl);
+               writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl);
                pci_push(base);
 
                /* restart rx engine */
@@ -2065,6 +2074,7 @@ static struct ethtool_ops ops = {
        .get_regs_len = nv_get_regs_len,
        .get_regs = nv_get_regs,
        .nway_reset = nv_nway_reset,
+       .get_perm_addr = ethtool_op_get_perm_addr,
 };
 
 static int nv_open(struct net_device *dev)
@@ -2114,9 +2124,9 @@ static int nv_open(struct net_device *dev)
        /* 5) continue setup */
        writel(np->linkspeed, base + NvRegLinkSpeed);
        writel(NVREG_UNKSETUP3_VAL1, base + NvRegUnknownSetupReg3);
-       writel(np->desc_ver, base + NvRegTxRxControl);
+       writel(np->txrxctl_bits, base + NvRegTxRxControl);
        pci_push(base);
-       writel(NVREG_TXRXCTL_BIT1|np->desc_ver, base + NvRegTxRxControl);
+       writel(NVREG_TXRXCTL_BIT1|np->txrxctl_bits, base + NvRegTxRxControl);
        reg_delay(dev, NvRegUnknownSetupReg5, NVREG_UNKSETUP5_BIT31, NVREG_UNKSETUP5_BIT31,
                        NV_SETUP5_DELAY, NV_SETUP5_DELAYMAX,
                        KERN_INFO "open: SetupReg5, Bit 31 remained off\n");
@@ -2314,18 +2324,26 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
                        printk(KERN_INFO "forcedeth: 64-bit DMA failed, using 32-bit addressing for device %s.\n",
                                        pci_name(pci_dev));
                }
+               np->txrxctl_bits = NVREG_TXRXCTL_DESC_3;
        } else if (id->driver_data & DEV_HAS_LARGEDESC) {
                /* packet format 2: supports jumbo frames */
                np->desc_ver = DESC_VER_2;
+               np->txrxctl_bits = NVREG_TXRXCTL_DESC_2;
        } else {
                /* original packet format */
                np->desc_ver = DESC_VER_1;
+               np->txrxctl_bits = NVREG_TXRXCTL_DESC_1;
        }
 
        np->pkt_limit = NV_PKTLIMIT_1;
        if (id->driver_data & DEV_HAS_LARGEDESC)
                np->pkt_limit = NV_PKTLIMIT_2;
 
+       if (id->driver_data & DEV_HAS_CHECKSUM) {
+               np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK;
+               dev->features |= NETIF_F_HW_CSUM;
+       }
+
        err = -ENOMEM;
        np->base = ioremap(addr, NV_PCI_REGSZ);
        if (!np->base)
@@ -2377,8 +2395,9 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
        dev->dev_addr[3] = (np->orig_mac[0] >> 16) & 0xff;
        dev->dev_addr[4] = (np->orig_mac[0] >>  8) & 0xff;
        dev->dev_addr[5] = (np->orig_mac[0] >>  0) & 0xff;
+       memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
-       if (!is_valid_ether_addr(dev->dev_addr)) {
+       if (!is_valid_ether_addr(dev->perm_addr)) {
                /*
                 * Bad mac address. At least one bios sets the mac address
                 * to 01:23:45:67:89:ab
@@ -2525,35 +2544,35 @@ static struct pci_device_id pci_tbl[] = {
        },
        {       /* nForce3 Ethernet Controller */
                PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_4),
-               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM,
        },
        {       /* nForce3 Ethernet Controller */
                PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_5),
-               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM,
        },
        {       /* nForce3 Ethernet Controller */
                PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_6),
-               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM,
        },
        {       /* nForce3 Ethernet Controller */
                PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_7),
-               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM,
        },
        {       /* CK804 Ethernet Controller */
                PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_8),
-               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA,
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA,
        },
        {       /* CK804 Ethernet Controller */
                PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_9),
-               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA,
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA,
        },
        {       /* MCP04 Ethernet Controller */
                PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_10),
-               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA,
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA,
        },
        {       /* MCP04 Ethernet Controller */
                PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_11),
-               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA,
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA,
        },
        {       /* MCP51 Ethernet Controller */
                PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_12),
@@ -2565,11 +2584,11 @@ static struct pci_device_id pci_tbl[] = {
        },
        {       /* MCP55 Ethernet Controller */
                PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14),
-               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA,
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA,
        },
        {       /* MCP55 Ethernet Controller */
                PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15),
-               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA,
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA,
        },
        {0,},
 };
index 6518334..ae5a2ed 100644 (file)
  *  define the configuration needed by the board are defined in a
  *  board structure in arch/ppc/platforms (though I do not
  *  discount the possibility that other architectures could one
- *  day be supported.  One assumption the driver currently makes
- *  is that the PHY is configured in such a way to advertise all
- *  capabilities.  This is a sensible default, and on certain
- *  PHYs, changing this default encounters substantial errata
- *  issues.  Future versions may remove this requirement, but for
- *  now, it is best for the firmware to ensure this is the case.
+ *  day be supported.
  *
  *  The Gianfar Ethernet Controller uses a ring of buffer
  *  descriptors.  The beginning is indicated by a register
@@ -47,7 +42,7 @@
  *  corresponding bit in the IMASK register is also set (if
  *  interrupt coalescing is active, then the interrupt may not
  *  happen immediately, but will wait until either a set number
- *  of frames or amount of time have passed.).  In NAPI, the
+ *  of frames or amount of time have passed).  In NAPI, the
  *  interrupt handler will signal there is work to be done, and
  *  exit.  Without NAPI, the packet(s) will be handled
  *  immediately.  Both methods will start at the last known empty
@@ -75,6 +70,7 @@
 #include <linux/sched.h>
 #include <linux/string.h>
 #include <linux/errno.h>
+#include <linux/unistd.h>
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/version.h>
 #include <linux/dma-mapping.h>
 #include <linux/crc32.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
 
 #include "gianfar.h"
-#include "gianfar_phy.h"
+#include "gianfar_mii.h"
 
 #define TX_TIMEOUT      (1*HZ)
 #define SKB_ALLOC_TIMEOUT 1000000
 #endif
 
 const char gfar_driver_name[] = "Gianfar Ethernet";
-const char gfar_driver_version[] = "1.1";
+const char gfar_driver_version[] = "1.2";
 
-int startup_gfar(struct net_device *dev);
 static int gfar_enet_open(struct net_device *dev);
 static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static void gfar_timeout(struct net_device *dev);
@@ -126,17 +123,13 @@ static int gfar_set_mac_address(struct net_device *dev);
 static int gfar_change_mtu(struct net_device *dev, int new_mtu);
 static irqreturn_t gfar_error(int irq, void *dev_id, struct pt_regs *regs);
 static irqreturn_t gfar_transmit(int irq, void *dev_id, struct pt_regs *regs);
-static irqreturn_t gfar_receive(int irq, void *dev_id, struct pt_regs *regs);
 static irqreturn_t gfar_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static irqreturn_t phy_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static void gfar_phy_change(void *data);
-static void gfar_phy_timer(unsigned long data);
 static void adjust_link(struct net_device *dev);
 static void init_registers(struct net_device *dev);
 static int init_phy(struct net_device *dev);
 static int gfar_probe(struct device *device);
 static int gfar_remove(struct device *device);
-void free_skb_resources(struct gfar_private *priv);
+static void free_skb_resources(struct gfar_private *priv);
 static void gfar_set_multi(struct net_device *dev);
 static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr);
 #ifdef CONFIG_GFAR_NAPI
@@ -144,7 +137,6 @@ static int gfar_poll(struct net_device *dev, int *budget);
 #endif
 int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit);
 static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int length);
-static void gfar_phy_startup_timer(unsigned long data);
 static void gfar_vlan_rx_register(struct net_device *netdev,
                                struct vlan_group *grp);
 static void gfar_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid);
@@ -162,6 +154,9 @@ int gfar_uses_fcb(struct gfar_private *priv)
        else
                return 0;
 }
+
+/* Set up the ethernet device structure, private data,
+ * and anything else we need before we start */
 static int gfar_probe(struct device *device)
 {
        u32 tempval;
@@ -175,7 +170,7 @@ static int gfar_probe(struct device *device)
 
        einfo = (struct gianfar_platform_data *) pdev->dev.platform_data;
 
-       if (einfo == NULL) {
+       if (NULL == einfo) {
                printk(KERN_ERR "gfar %d: Missing additional data!\n",
                       pdev->id);
 
@@ -185,7 +180,7 @@ static int gfar_probe(struct device *device)
        /* Create an ethernet device instance */
        dev = alloc_etherdev(sizeof (*priv));
 
-       if (dev == NULL)
+       if (NULL == dev)
                return -ENOMEM;
 
        priv = netdev_priv(dev);
@@ -207,20 +202,11 @@ static int gfar_probe(struct device *device)
        priv->regs = (struct gfar *)
                ioremap(r->start, sizeof (struct gfar));
 
-       if (priv->regs == NULL) {
+       if (NULL == priv->regs) {
                err = -ENOMEM;
                goto regs_fail;
        }
 
-       /* Set the PHY base address */
-       priv->phyregs = (struct gfar *)
-           ioremap(einfo->phy_reg_addr, sizeof (struct gfar));
-
-       if (priv->phyregs == NULL) {
-               err = -ENOMEM;
-               goto phy_regs_fail;
-       }
-
        spin_lock_init(&priv->lock);
 
        dev_set_drvdata(device, dev);
@@ -386,12 +372,10 @@ static int gfar_probe(struct device *device)
        return 0;
 
 register_fail:
-       iounmap((void *) priv->phyregs);
-phy_regs_fail:
        iounmap((void *) priv->regs);
 regs_fail:
        free_netdev(dev);
-       return -ENOMEM;
+       return err;
 }
 
 static int gfar_remove(struct device *device)
@@ -402,108 +386,41 @@ static int gfar_remove(struct device *device)
        dev_set_drvdata(device, NULL);
 
        iounmap((void *) priv->regs);
-       iounmap((void *) priv->phyregs);
        free_netdev(dev);
 
        return 0;
 }
 
 
-/* Configure the PHY for dev.
- * returns 0 if success.  -1 if failure
+/* Initializes driver's PHY state, and attaches to the PHY.
+ * Returns 0 on success.
  */
 static int init_phy(struct net_device *dev)
 {
        struct gfar_private *priv = netdev_priv(dev);
-       struct phy_info *curphy;
-       unsigned int timeout = PHY_INIT_TIMEOUT;
-       struct gfar *phyregs = priv->phyregs;
-       struct gfar_mii_info *mii_info;
-       int err;
+       uint gigabit_support =
+               priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ?
+               SUPPORTED_1000baseT_Full : 0;
+       struct phy_device *phydev;
 
        priv->oldlink = 0;
        priv->oldspeed = 0;
        priv->oldduplex = -1;
 
-       mii_info = kmalloc(sizeof(struct gfar_mii_info),
-                       GFP_KERNEL);
-
-       if(NULL == mii_info) {
-               if (netif_msg_ifup(priv))
-                       printk(KERN_ERR "%s: Could not allocate mii_info\n",
-                                       dev->name);
-               return -ENOMEM;
-       }
-
-       mii_info->speed = SPEED_1000;
-       mii_info->duplex = DUPLEX_FULL;
-       mii_info->pause = 0;
-       mii_info->link = 1;
-
-       mii_info->advertising = (ADVERTISED_10baseT_Half |
-                       ADVERTISED_10baseT_Full |
-                       ADVERTISED_100baseT_Half |
-                       ADVERTISED_100baseT_Full |
-                       ADVERTISED_1000baseT_Full);
-       mii_info->autoneg = 1;
+       phydev = phy_connect(dev, priv->einfo->bus_id, &adjust_link, 0);
 
-       spin_lock_init(&mii_info->mdio_lock);
-
-       mii_info->mii_id = priv->einfo->phyid;
-
-       mii_info->dev = dev;
-
-       mii_info->mdio_read = &read_phy_reg;
-       mii_info->mdio_write = &write_phy_reg;
-
-       priv->mii_info = mii_info;
-
-       /* Reset the management interface */
-       gfar_write(&phyregs->miimcfg, MIIMCFG_RESET);
-
-       /* Setup the MII Mgmt clock speed */
-       gfar_write(&phyregs->miimcfg, MIIMCFG_INIT_VALUE);
-
-       /* Wait until the bus is free */
-       while ((gfar_read(&phyregs->miimind) & MIIMIND_BUSY) &&
-                       timeout--)
-               cpu_relax();
-
-       if(timeout <= 0) {
-               printk(KERN_ERR "%s: The MII Bus is stuck!\n",
-                               dev->name);
-               err = -1;
-               goto bus_fail;
-       }
-
-       /* get info for this PHY */
-       curphy = get_phy_info(priv->mii_info);
-
-       if (curphy == NULL) {
-               if (netif_msg_ifup(priv))
-                       printk(KERN_ERR "%s: No PHY found\n", dev->name);
-               err = -1;
-               goto no_phy;
+       if (IS_ERR(phydev)) {
+               printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
+               return PTR_ERR(phydev);
        }
 
-       mii_info->phyinfo = curphy;
+       /* Remove any features not supported by the controller */
+       phydev->supported &= (GFAR_SUPPORTED | gigabit_support);
+       phydev->advertising = phydev->supported;
 
-       /* Run the commands which initialize the PHY */
-       if(curphy->init) {
-               err = curphy->init(priv->mii_info);
-
-               if (err)
-                       goto phy_init_fail;
-       }
+       priv->phydev = phydev;
 
        return 0;
-
-phy_init_fail:
-no_phy:
-bus_fail:
-       kfree(mii_info);
-
-       return err;
 }
 
 static void init_registers(struct net_device *dev)
@@ -603,24 +520,13 @@ void stop_gfar(struct net_device *dev)
        struct gfar *regs = priv->regs;
        unsigned long flags;
 
+       phy_stop(priv->phydev);
+
        /* Lock it down */
        spin_lock_irqsave(&priv->lock, flags);
 
-       /* Tell the kernel the link is down */
-       priv->mii_info->link = 0;
-       adjust_link(dev);
-
        gfar_halt(dev);
 
-       if (priv->einfo->board_flags & FSL_GIANFAR_BRD_HAS_PHY_INTR) {
-               /* Clear any pending interrupts */
-               mii_clear_phy_interrupt(priv->mii_info);
-
-               /* Disable PHY Interrupts */
-               mii_configure_phy_interrupt(priv->mii_info,
-                               MII_INTERRUPT_DISABLED);
-       }
-
        spin_unlock_irqrestore(&priv->lock, flags);
 
        /* Free the IRQs */
@@ -629,13 +535,7 @@ void stop_gfar(struct net_device *dev)
                free_irq(priv->interruptTransmit, dev);
                free_irq(priv->interruptReceive, dev);
        } else {
-               free_irq(priv->interruptTransmit, dev);
-       }
-
-       if (priv->einfo->board_flags & FSL_GIANFAR_BRD_HAS_PHY_INTR) {
-               free_irq(priv->einfo->interruptPHY, dev);
-       } else {
-               del_timer_sync(&priv->phy_info_timer);
+               free_irq(priv->interruptTransmit, dev);
        }
 
        free_skb_resources(priv);
@@ -649,7 +549,7 @@ void stop_gfar(struct net_device *dev)
 
 /* If there are any tx skbs or rx skbs still around, free them.
  * Then free tx_skbuff and rx_skbuff */
-void free_skb_resources(struct gfar_private *priv)
+static void free_skb_resources(struct gfar_private *priv)
 {
        struct rxbd8 *rxbdp;
        struct txbd8 *txbdp;
@@ -770,7 +670,7 @@ int startup_gfar(struct net_device *dev)
            (struct sk_buff **) kmalloc(sizeof (struct sk_buff *) *
                                        priv->tx_ring_size, GFP_KERNEL);
 
-       if (priv->tx_skbuff == NULL) {
+       if (NULL == priv->tx_skbuff) {
                if (netif_msg_ifup(priv))
                        printk(KERN_ERR "%s: Could not allocate tx_skbuff\n",
                                        dev->name);
@@ -785,7 +685,7 @@ int startup_gfar(struct net_device *dev)
            (struct sk_buff **) kmalloc(sizeof (struct sk_buff *) *
                                        priv->rx_ring_size, GFP_KERNEL);
 
-       if (priv->rx_skbuff == NULL) {
+       if (NULL == priv->rx_skbuff) {
                if (netif_msg_ifup(priv))
                        printk(KERN_ERR "%s: Could not allocate rx_skbuff\n",
                                        dev->name);
@@ -879,13 +779,7 @@ int startup_gfar(struct net_device *dev)
                }
        }
 
-       /* Set up the PHY change work queue */
-       INIT_WORK(&priv->tq, gfar_phy_change, dev);
-
-       init_timer(&priv->phy_info_timer);
-       priv->phy_info_timer.function = &gfar_phy_startup_timer;
-       priv->phy_info_timer.data = (unsigned long) priv->mii_info;
-       mod_timer(&priv->phy_info_timer, jiffies + HZ);
+       phy_start(priv->phydev);
 
        /* Configure the coalescing support */
        if (priv->txcoalescing)
@@ -933,11 +827,6 @@ tx_skb_fail:
                        priv->tx_bd_base,
                        gfar_read(&regs->tbase0));
 
-       if (priv->mii_info->phyinfo->close)
-               priv->mii_info->phyinfo->close(priv->mii_info);
-
-       kfree(priv->mii_info);
-
        return err;
 }
 
@@ -1035,7 +924,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
        txbdp->status &= TXBD_WRAP;
 
        /* Set up checksumming */
-       if ((dev->features & NETIF_F_IP_CSUM) 
+       if ((dev->features & NETIF_F_IP_CSUM)
                        && (CHECKSUM_HW == skb->ip_summed)) {
                fcb = gfar_add_fcb(skb, txbdp);
                gfar_tx_checksum(skb, fcb);
@@ -1103,11 +992,9 @@ static int gfar_close(struct net_device *dev)
        struct gfar_private *priv = netdev_priv(dev);
        stop_gfar(dev);
 
-       /* Shutdown the PHY */
-       if (priv->mii_info->phyinfo->close)
-               priv->mii_info->phyinfo->close(priv->mii_info);
-
-       kfree(priv->mii_info);
+       /* Disconnect from the PHY */
+       phy_disconnect(priv->phydev);
+       priv->phydev = NULL;
 
        netif_stop_queue(dev);
 
@@ -1343,7 +1230,7 @@ struct sk_buff * gfar_new_skb(struct net_device *dev, struct rxbd8 *bdp)
        while ((!skb) && timeout--)
                skb = dev_alloc_skb(priv->rx_buffer_size + RXBUF_ALIGNMENT);
 
-       if (skb == NULL)
+       if (NULL == skb)
                return NULL;
 
        /* We need the data buffer to be aligned properly.  We will reserve
@@ -1490,7 +1377,7 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb,
        struct gfar_private *priv = netdev_priv(dev);
        struct rxfcb *fcb = NULL;
 
-       if (skb == NULL) {
+       if (NULL == skb) {
                if (netif_msg_rx_err(priv))
                        printk(KERN_WARNING "%s: Missing skb!!.\n", dev->name);
                priv->stats.rx_dropped++;
@@ -1718,131 +1605,9 @@ static irqreturn_t gfar_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-static irqreturn_t phy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-       struct net_device *dev = (struct net_device *) dev_id;
-       struct gfar_private *priv = netdev_priv(dev);
-
-       /* Clear the interrupt */
-       mii_clear_phy_interrupt(priv->mii_info);
-
-       /* Disable PHY interrupts */
-       mii_configure_phy_interrupt(priv->mii_info,
-                       MII_INTERRUPT_DISABLED);
-
-       /* Schedule the phy change */
-       schedule_work(&priv->tq);
-
-       return IRQ_HANDLED;
-}
-
-/* Scheduled by the phy_interrupt/timer to handle PHY changes */
-static void gfar_phy_change(void *data)
-{
-       struct net_device *dev = (struct net_device *) data;
-       struct gfar_private *priv = netdev_priv(dev);
-       int result = 0;
-
-       /* Delay to give the PHY a chance to change the
-        * register state */
-       msleep(1);
-
-       /* Update the link, speed, duplex */
-       result = priv->mii_info->phyinfo->read_status(priv->mii_info);
-
-       /* Adjust the known status as long as the link
-        * isn't still coming up */
-       if((0 == result) || (priv->mii_info->link == 0))
-               adjust_link(dev);
-
-       /* Reenable interrupts, if needed */
-       if (priv->einfo->board_flags & FSL_GIANFAR_BRD_HAS_PHY_INTR)
-               mii_configure_phy_interrupt(priv->mii_info,
-                               MII_INTERRUPT_ENABLED);
-}
-
-/* Called every so often on systems that don't interrupt
- * the core for PHY changes */
-static void gfar_phy_timer(unsigned long data)
-{
-       struct net_device *dev = (struct net_device *) data;
-       struct gfar_private *priv = netdev_priv(dev);
-
-       schedule_work(&priv->tq);
-
-       mod_timer(&priv->phy_info_timer, jiffies +
-                       GFAR_PHY_CHANGE_TIME * HZ);
-}
-
-/* Keep trying aneg for some time
- * If, after GFAR_AN_TIMEOUT seconds, it has not
- * finished, we switch to forced.
- * Either way, once the process has completed, we either
- * request the interrupt, or switch the timer over to
- * using gfar_phy_timer to check status */
-static void gfar_phy_startup_timer(unsigned long data)
-{
-       int result;
-       static int secondary = GFAR_AN_TIMEOUT;
-       struct gfar_mii_info *mii_info = (struct gfar_mii_info *)data;
-       struct gfar_private *priv = netdev_priv(mii_info->dev);
-
-       /* Configure the Auto-negotiation */
-       result = mii_info->phyinfo->config_aneg(mii_info);
-
-       /* If autonegotiation failed to start, and
-        * we haven't timed out, reset the timer, and return */
-       if (result && secondary--) {
-               mod_timer(&priv->phy_info_timer, jiffies + HZ);
-               return;
-       } else if (result) {
-               /* Couldn't start autonegotiation.
-                * Try switching to forced */
-               mii_info->autoneg = 0;
-               result = mii_info->phyinfo->config_aneg(mii_info);
-
-               /* Forcing failed!  Give up */
-               if(result) {
-                       if (netif_msg_link(priv))
-                               printk(KERN_ERR "%s: Forcing failed!\n",
-                                               mii_info->dev->name);
-                       return;
-               }
-       }
-
-       /* Kill the timer so it can be restarted */
-       del_timer_sync(&priv->phy_info_timer);
-
-       /* Grab the PHY interrupt, if necessary/possible */
-       if (priv->einfo->board_flags & FSL_GIANFAR_BRD_HAS_PHY_INTR) {
-               if (request_irq(priv->einfo->interruptPHY,
-                                       phy_interrupt,
-                                       SA_SHIRQ,
-                                       "phy_interrupt",
-                                       mii_info->dev) < 0) {
-                       if (netif_msg_intr(priv))
-                               printk(KERN_ERR "%s: Can't get IRQ %d (PHY)\n",
-                                               mii_info->dev->name,
-                                       priv->einfo->interruptPHY);
-               } else {
-                       mii_configure_phy_interrupt(priv->mii_info,
-                                       MII_INTERRUPT_ENABLED);
-                       return;
-               }
-       }
-
-       /* Start the timer again, this time in order to
-        * handle a change in status */
-       init_timer(&priv->phy_info_timer);
-       priv->phy_info_timer.function = &gfar_phy_timer;
-       priv->phy_info_timer.data = (unsigned long) mii_info->dev;
-       mod_timer(&priv->phy_info_timer, jiffies +
-                       GFAR_PHY_CHANGE_TIME * HZ);
-}
-
 /* Called every time the controller might need to be made
  * aware of new link state.  The PHY code conveys this
- * information through variables in the priv structure, and this
+ * information through variables in the phydev structure, and this
  * function converts those variables into the appropriate
  * register values, and can bring down the device if needed.
  */
@@ -1850,84 +1615,68 @@ static void adjust_link(struct net_device *dev)
 {
        struct gfar_private *priv = netdev_priv(dev);
        struct gfar *regs = priv->regs;
-       u32 tempval;
-       struct gfar_mii_info *mii_info = priv->mii_info;
+       unsigned long flags;
+       struct phy_device *phydev = priv->phydev;
+       int new_state = 0;
+
+       spin_lock_irqsave(&priv->lock, flags);
+       if (phydev->link) {
+               u32 tempval = gfar_read(&regs->maccfg2);
 
-       if (mii_info->link) {
                /* Now we make sure that we can be in full duplex mode.
                 * If not, we operate in half-duplex mode. */
-               if (mii_info->duplex != priv->oldduplex) {
-                       if (!(mii_info->duplex)) {
-                               tempval = gfar_read(&regs->maccfg2);
+               if (phydev->duplex != priv->oldduplex) {
+                       new_state = 1;
+                       if (!(phydev->duplex))
                                tempval &= ~(MACCFG2_FULL_DUPLEX);
-                               gfar_write(&regs->maccfg2, tempval);
-
-                               if (netif_msg_link(priv))
-                                       printk(KERN_INFO "%s: Half Duplex\n",
-                                                       dev->name);
-                       } else {
-                               tempval = gfar_read(&regs->maccfg2);
+                       else
                                tempval |= MACCFG2_FULL_DUPLEX;
-                               gfar_write(&regs->maccfg2, tempval);
 
-                               if (netif_msg_link(priv))
-                                       printk(KERN_INFO "%s: Full Duplex\n",
-                                                       dev->name);
-                       }
-
-                       priv->oldduplex = mii_info->duplex;
+                       priv->oldduplex = phydev->duplex;
                }
 
-               if (mii_info->speed != priv->oldspeed) {
-                       switch (mii_info->speed) {
+               if (phydev->speed != priv->oldspeed) {
+                       new_state = 1;
+                       switch (phydev->speed) {
                        case 1000:
-                               tempval = gfar_read(&regs->maccfg2);
                                tempval =
                                    ((tempval & ~(MACCFG2_IF)) | MACCFG2_GMII);
-                               gfar_write(&regs->maccfg2, tempval);
                                break;
                        case 100:
                        case 10:
-                               tempval = gfar_read(&regs->maccfg2);
                                tempval =
                                    ((tempval & ~(MACCFG2_IF)) | MACCFG2_MII);
-                               gfar_write(&regs->maccfg2, tempval);
                                break;
                        default:
                                if (netif_msg_link(priv))
                                        printk(KERN_WARNING
-                                                       "%s: Ack!  Speed (%d) is not 10/100/1000!\n",
-                                                       dev->name, mii_info->speed);
+                                               "%s: Ack!  Speed (%d) is not 10/100/1000!\n",
+                                               dev->name, phydev->speed);
                                break;
                        }
 
-                       if (netif_msg_link(priv))
-                               printk(KERN_INFO "%s: Speed %dBT\n", dev->name,
-                                               mii_info->speed);
-
-                       priv->oldspeed = mii_info->speed;
+                       priv->oldspeed = phydev->speed;
                }
 
+               gfar_write(&regs->maccfg2, tempval);
+
                if (!priv->oldlink) {
-                       if (netif_msg_link(priv))
-                               printk(KERN_INFO "%s: Link is up\n", dev->name);
+                       new_state = 1;
                        priv->oldlink = 1;
-                       netif_carrier_on(dev);
                        netif_schedule(dev);
                }
-       } else {
-               if (priv->oldlink) {
-                       if (netif_msg_link(priv))
-                               printk(KERN_INFO "%s: Link is down\n",
-                                               dev->name);
-                       priv->oldlink = 0;
-                       priv->oldspeed = 0;
-                       priv->oldduplex = -1;
-                       netif_carrier_off(dev);
-               }
+       } else if (priv->oldlink) {
+               new_state = 1;
+               priv->oldlink = 0;
+               priv->oldspeed = 0;
+               priv->oldduplex = -1;
        }
-}
 
+       if (new_state && netif_msg_link(priv))
+               phy_print_status(phydev);
+
+       spin_unlock_irqrestore(&priv->lock, flags);
+}
 
 /* Update the hash table based on the current list of multicast
  * addresses we subscribe to.  Also, change the promiscuity of
@@ -2122,12 +1871,23 @@ static struct device_driver gfar_driver = {
 
 static int __init gfar_init(void)
 {
-       return driver_register(&gfar_driver);
+       int err = gfar_mdio_init();
+
+       if (err)
+               return err;
+
+       err = driver_register(&gfar_driver);
+
+       if (err)
+               gfar_mdio_exit();
+       
+       return err;
 }
 
 static void __exit gfar_exit(void)
 {
        driver_unregister(&gfar_driver);
+       gfar_mdio_exit();
 }
 
 module_init(gfar_init);
index 28af087..c77ca6c 100644 (file)
@@ -17,7 +17,6 @@
  *
  *  Still left to do:
  *      -Add support for module parameters
- *     -Add support for ethtool -s
  *     -Add patch for ethtool phys id
  */
 #ifndef __GIANFAR_H
@@ -37,7 +36,8 @@
 #include <linux/skbuff.h>
 #include <linux/spinlock.h>
 #include <linux/mm.h>
-#include <linux/fsl_devices.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -48,7 +48,8 @@
 #include <linux/workqueue.h>
 #include <linux/ethtool.h>
 #include <linux/netdevice.h>
-#include "gianfar_phy.h"
+#include <linux/fsl_devices.h>
+#include "gianfar_mii.h"
 
 /* The maximum number of packets to be handled in one call of gfar_poll */
 #define GFAR_DEV_WEIGHT 64
@@ -73,7 +74,7 @@
 #define PHY_INIT_TIMEOUT 100000
 #define GFAR_PHY_CHANGE_TIME 2
 
-#define DEVICE_NAME "%s: Gianfar Ethernet Controller Version 1.1, "
+#define DEVICE_NAME "%s: Gianfar Ethernet Controller Version 1.2, "
 #define DRV_NAME "gfar-enet"
 extern const char gfar_driver_name[];
 extern const char gfar_driver_version[];
@@ -578,12 +579,7 @@ struct gfar {
        u32     hafdup;         /* 0x.50c - Half Duplex Register */
        u32     maxfrm;         /* 0x.510 - Maximum Frame Length Register */
        u8      res18[12];
-       u32     miimcfg;        /* 0x.520 - MII Management Configuration Register */
-       u32     miimcom;        /* 0x.524 - MII Management Command Register */
-       u32     miimadd;        /* 0x.528 - MII Management Address Register */
-       u32     miimcon;        /* 0x.52c - MII Management Control Register */
-       u32     miimstat;       /* 0x.530 - MII Management Status Register */
-       u32     miimind;        /* 0x.534 - MII Management Indicator Register */
+       u8      gfar_mii_regs[24];      /* See gianfar_phy.h */
        u8      res19[4];
        u32     ifstat;         /* 0x.53c - Interface Status Register */
        u32     macstnaddr1;    /* 0x.540 - Station Address Part 1 Register */
@@ -688,9 +684,6 @@ struct gfar_private {
        struct gfar *regs;      /* Pointer to the GFAR memory mapped Registers */
        u32 *hash_regs[16];
        int hash_width;
-       struct gfar *phyregs;
-       struct work_struct tq;
-       struct timer_list phy_info_timer;
        struct net_device_stats stats; /* linux network statistics */
        struct gfar_extra_stats extra_stats;
        spinlock_t lock;
@@ -710,7 +703,8 @@ struct gfar_private {
        unsigned int interruptError;
        struct gianfar_platform_data *einfo;
 
-       struct gfar_mii_info *mii_info;
+       struct phy_device *phydev;
+       struct mii_bus *mii_bus;
        int oldspeed;
        int oldduplex;
        int oldlink;
@@ -732,4 +726,12 @@ extern inline void gfar_write(volatile unsigned *addr, u32 val)
 
 extern struct ethtool_ops *gfar_op_array[];
 
+extern irqreturn_t gfar_receive(int irq, void *dev_id, struct pt_regs *regs);
+extern int startup_gfar(struct net_device *dev);
+extern void stop_gfar(struct net_device *dev);
+extern void gfar_halt(struct net_device *dev);
+extern void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev,
+               int enable, u32 regnum, u32 read);
+void gfar_setup_stashing(struct net_device *dev);
+
 #endif /* __GIANFAR_H */
index a451de6..68e3578 100644 (file)
 #include <asm/types.h>
 #include <asm/uaccess.h>
 #include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
 
 #include "gianfar.h"
 
 #define is_power_of_2(x)        ((x) != 0 && (((x) & ((x) - 1)) == 0))
 
-extern int startup_gfar(struct net_device *dev);
-extern void stop_gfar(struct net_device *dev);
-extern void gfar_halt(struct net_device *dev);
 extern void gfar_start(struct net_device *dev);
 extern int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit);
 
+#define GFAR_MAX_COAL_USECS 0xffff
+#define GFAR_MAX_COAL_FRAMES 0xff
 static void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy,
                     u64 * buf);
 static void gfar_gstrings(struct net_device *dev, u32 stringset, u8 * buf);
@@ -182,38 +183,32 @@ static void gfar_gdrvinfo(struct net_device *dev, struct
        drvinfo->eedump_len = 0;
 }
 
+
+static int gfar_ssettings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+       struct gfar_private *priv = netdev_priv(dev);
+       struct phy_device *phydev = priv->phydev;
+
+       if (NULL == phydev)
+               return -ENODEV;
+
+       return phy_ethtool_sset(phydev, cmd);
+}
+
+
 /* Return the current settings in the ethtool_cmd structure */
 static int gfar_gsettings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
        struct gfar_private *priv = netdev_priv(dev);
-       uint gigabit_support = 
-               priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ?
-                       SUPPORTED_1000baseT_Full : 0;
-       uint gigabit_advert = 
-               priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ?
-                       ADVERTISED_1000baseT_Full: 0;
-
-       cmd->supported = (SUPPORTED_10baseT_Half
-                         | SUPPORTED_100baseT_Half
-                         | SUPPORTED_100baseT_Full
-                         | gigabit_support | SUPPORTED_Autoneg);
-
-       /* For now, we always advertise everything */
-       cmd->advertising = (ADVERTISED_10baseT_Half
-                           | ADVERTISED_100baseT_Half
-                           | ADVERTISED_100baseT_Full
-                           | gigabit_advert | ADVERTISED_Autoneg);
-
-       cmd->speed = priv->mii_info->speed;
-       cmd->duplex = priv->mii_info->duplex;
-       cmd->port = PORT_MII;
-       cmd->phy_address = priv->mii_info->mii_id;
-       cmd->transceiver = XCVR_EXTERNAL;
-       cmd->autoneg = AUTONEG_ENABLE;
+       struct phy_device *phydev = priv->phydev;
+
+       if (NULL == phydev)
+               return -ENODEV;
+       
        cmd->maxtxpkt = priv->txcount;
        cmd->maxrxpkt = priv->rxcount;
 
-       return 0;
+       return phy_ethtool_gset(phydev, cmd);
 }
 
 /* Return the length of the register structure */
@@ -241,14 +236,14 @@ static unsigned int gfar_usecs2ticks(struct gfar_private *priv, unsigned int use
        unsigned int count;
 
        /* The timer is different, depending on the interface speed */
-       switch (priv->mii_info->speed) {
-       case 1000:
+       switch (priv->phydev->speed) {
+       case SPEED_1000:
                count = GFAR_GBIT_TIME;
                break;
-       case 100:
+       case SPEED_100:
                count = GFAR_100_TIME;
                break;
-       case 10:
+       case SPEED_10:
        default:
                count = GFAR_10_TIME;
                break;
@@ -265,14 +260,14 @@ static unsigned int gfar_ticks2usecs(struct gfar_private *priv, unsigned int tic
        unsigned int count;
 
        /* The timer is different, depending on the interface speed */
-       switch (priv->mii_info->speed) {
-       case 1000:
+       switch (priv->phydev->speed) {
+       case SPEED_1000:
                count = GFAR_GBIT_TIME;
                break;
-       case 100:
+       case SPEED_100:
                count = GFAR_100_TIME;
                break;
-       case 10:
+       case SPEED_10:
        default:
                count = GFAR_10_TIME;
                break;
@@ -292,6 +287,9 @@ static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals
        if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_COALESCE))
                return -EOPNOTSUPP;
 
+       if (NULL == priv->phydev)
+               return -ENODEV;
+
        cvals->rx_coalesce_usecs = gfar_ticks2usecs(priv, priv->rxtime);
        cvals->rx_max_coalesced_frames = priv->rxcount;
 
@@ -348,6 +346,22 @@ static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals
        else
                priv->rxcoalescing = 1;
 
+       if (NULL == priv->phydev)
+               return -ENODEV;
+
+       /* Check the bounds of the values */
+       if (cvals->rx_coalesce_usecs > GFAR_MAX_COAL_USECS) {
+               pr_info("Coalescing is limited to %d microseconds\n",
+                               GFAR_MAX_COAL_USECS);
+               return -EINVAL;
+       }
+
+       if (cvals->rx_max_coalesced_frames > GFAR_MAX_COAL_FRAMES) {
+               pr_info("Coalescing is limited to %d frames\n",
+                               GFAR_MAX_COAL_FRAMES);
+               return -EINVAL;
+       }
+
        priv->rxtime = gfar_usecs2ticks(priv, cvals->rx_coalesce_usecs);
        priv->rxcount = cvals->rx_max_coalesced_frames;
 
@@ -358,6 +372,19 @@ static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals
        else
                priv->txcoalescing = 1;
 
+       /* Check the bounds of the values */
+       if (cvals->tx_coalesce_usecs > GFAR_MAX_COAL_USECS) {
+               pr_info("Coalescing is limited to %d microseconds\n",
+                               GFAR_MAX_COAL_USECS);
+               return -EINVAL;
+       }
+
+       if (cvals->tx_max_coalesced_frames > GFAR_MAX_COAL_FRAMES) {
+               pr_info("Coalescing is limited to %d frames\n",
+                               GFAR_MAX_COAL_FRAMES);
+               return -EINVAL;
+       }
+
        priv->txtime = gfar_usecs2ticks(priv, cvals->tx_coalesce_usecs);
        priv->txcount = cvals->tx_max_coalesced_frames;
 
@@ -536,6 +563,7 @@ static void gfar_set_msglevel(struct net_device *dev, uint32_t data)
 
 struct ethtool_ops gfar_ethtool_ops = {
        .get_settings = gfar_gsettings,
+       .set_settings = gfar_ssettings,
        .get_drvinfo = gfar_gdrvinfo,
        .get_regs_len = gfar_reglen,
        .get_regs = gfar_get_regs,
diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c
new file mode 100644 (file)
index 0000000..1eca1db
--- /dev/null
@@ -0,0 +1,219 @@
+/* 
+ * drivers/net/gianfar_mii.c
+ *
+ * Gianfar Ethernet Driver -- MIIM bus implementation
+ * Provides Bus interface for MIIM regs
+ *
+ * Author: Andy Fleming
+ * Maintainer: Kumar Gala (kumar.gala@freescale.com)
+ *
+ * Copyright (c) 2002-2004 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/unistd.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <asm/ocp.h>
+#include <linux/crc32.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+
+#include "gianfar.h"
+#include "gianfar_mii.h"
+
+/* Write value to the PHY at mii_id at register regnum,
+ * on the bus, waiting until the write is done before returning.
+ * All PHY configuration is done through the TSEC1 MIIM regs */
+int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value)
+{
+       struct gfar_mii *regs = bus->priv;
+
+       /* Set the PHY address and the register address we want to write */
+       gfar_write(&regs->miimadd, (mii_id << 8) | regnum);
+
+       /* Write out the value we want */
+       gfar_write(&regs->miimcon, value);
+
+       /* Wait for the transaction to finish */
+       while (gfar_read(&regs->miimind) & MIIMIND_BUSY)
+               cpu_relax();
+
+       return 0;
+}
+
+/* Read the bus for PHY at addr mii_id, register regnum, and
+ * return the value.  Clears miimcom first.  All PHY
+ * configuration has to be done through the TSEC1 MIIM regs */
+int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
+{
+       struct gfar_mii *regs = bus->priv;
+       u16 value;
+
+       /* Set the PHY address and the register address we want to read */
+       gfar_write(&regs->miimadd, (mii_id << 8) | regnum);
+
+       /* Clear miimcom, and then initiate a read */
+       gfar_write(&regs->miimcom, 0);
+       gfar_write(&regs->miimcom, MII_READ_COMMAND);
+
+       /* Wait for the transaction to finish */
+       while (gfar_read(&regs->miimind) & (MIIMIND_NOTVALID | MIIMIND_BUSY))
+               cpu_relax();
+
+       /* Grab the value of the register from miimstat */
+       value = gfar_read(&regs->miimstat);
+
+       return value;
+}
+
+
+/* Reset the MIIM registers, and wait for the bus to free */
+int gfar_mdio_reset(struct mii_bus *bus)
+{
+       struct gfar_mii *regs = bus->priv;
+       unsigned int timeout = PHY_INIT_TIMEOUT;
+
+       spin_lock_bh(&bus->mdio_lock);
+
+       /* Reset the management interface */
+       gfar_write(&regs->miimcfg, MIIMCFG_RESET);
+
+       /* Setup the MII Mgmt clock speed */
+       gfar_write(&regs->miimcfg, MIIMCFG_INIT_VALUE);
+
+       /* Wait until the bus is free */
+       while ((gfar_read(&regs->miimind) & MIIMIND_BUSY) &&
+                       timeout--)
+               cpu_relax();
+
+       spin_unlock_bh(&bus->mdio_lock);
+
+       if(timeout <= 0) {
+               printk(KERN_ERR "%s: The MII Bus is stuck!\n",
+                               bus->name);
+               return -EBUSY;
+       }
+
+       return 0;
+}
+
+
+int gfar_mdio_probe(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct gianfar_mdio_data *pdata;
+       struct gfar_mii *regs;
+       struct mii_bus *new_bus;
+       int err = 0;
+
+       if (NULL == dev)
+               return -EINVAL;
+
+       new_bus = kmalloc(sizeof(struct mii_bus), GFP_KERNEL);
+
+       if (NULL == new_bus)
+               return -ENOMEM;
+
+       new_bus->name = "Gianfar MII Bus",
+       new_bus->read = &gfar_mdio_read,
+       new_bus->write = &gfar_mdio_write,
+       new_bus->reset = &gfar_mdio_reset,
+       new_bus->id = pdev->id;
+
+       pdata = (struct gianfar_mdio_data *)pdev->dev.platform_data;
+
+       if (NULL == pdata) {
+               printk(KERN_ERR "gfar mdio %d: Missing platform data!\n", pdev->id);
+               return -ENODEV;
+       }
+
+       /* Set the PHY base address */
+       regs = (struct gfar_mii *) ioremap(pdata->paddr, 
+                       sizeof (struct gfar_mii));
+
+       if (NULL == regs) {
+               err = -ENOMEM;
+               goto reg_map_fail;
+       }
+
+       new_bus->priv = regs;
+
+       new_bus->irq = pdata->irq;
+
+       new_bus->dev = dev;
+       dev_set_drvdata(dev, new_bus);
+
+       err = mdiobus_register(new_bus);
+
+       if (0 != err) {
+               printk (KERN_ERR "%s: Cannot register as MDIO bus\n", 
+                               new_bus->name);
+               goto bus_register_fail;
+       }
+
+       return 0;
+
+bus_register_fail:
+       iounmap((void *) regs);
+reg_map_fail:
+       kfree(new_bus);
+
+       return err;
+}
+
+
+int gfar_mdio_remove(struct device *dev)
+{
+       struct mii_bus *bus = dev_get_drvdata(dev);
+
+       mdiobus_unregister(bus);
+
+       dev_set_drvdata(dev, NULL);
+
+       iounmap((void *) (&bus->priv));
+       bus->priv = NULL;
+       kfree(bus);
+
+       return 0;
+}
+
+static struct device_driver gianfar_mdio_driver = {
+       .name = "fsl-gianfar_mdio",
+       .bus = &platform_bus_type,
+       .probe = gfar_mdio_probe,
+       .remove = gfar_mdio_remove,
+};
+
+int __init gfar_mdio_init(void)
+{
+       return driver_register(&gianfar_mdio_driver);
+}
+
+void __exit gfar_mdio_exit(void)
+{
+       driver_unregister(&gianfar_mdio_driver);
+}
diff --git a/drivers/net/gianfar_mii.h b/drivers/net/gianfar_mii.h
new file mode 100644 (file)
index 0000000..56e5665
--- /dev/null
@@ -0,0 +1,45 @@
+/* 
+ * drivers/net/gianfar_mii.h
+ *
+ * Gianfar Ethernet Driver -- MII Management Bus Implementation
+ * Driver for the MDIO bus controller in the Gianfar register space
+ *
+ * Author: Andy Fleming
+ * Maintainer: Kumar Gala (kumar.gala@freescale.com)
+ *
+ * Copyright (c) 2002-2004 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+#ifndef __GIANFAR_MII_H
+#define __GIANFAR_MII_H
+
+#define MIIMIND_BUSY            0x00000001
+#define MIIMIND_NOTVALID        0x00000004
+
+#define MII_READ_COMMAND       0x00000001
+
+#define GFAR_SUPPORTED (SUPPORTED_10baseT_Half \
+               | SUPPORTED_100baseT_Half \
+               | SUPPORTED_100baseT_Full \
+               | SUPPORTED_Autoneg \
+               | SUPPORTED_MII)
+
+struct gfar_mii {
+       u32     miimcfg;        /* 0x.520 - MII Management Config Register */
+       u32     miimcom;        /* 0x.524 - MII Management Command Register */
+       u32     miimadd;        /* 0x.528 - MII Management Address Register */
+       u32     miimcon;        /* 0x.52c - MII Management Control Register */
+       u32     miimstat;       /* 0x.530 - MII Management Status Register */
+       u32     miimind;        /* 0x.534 - MII Management Indicator Register */
+};
+
+int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum);
+int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value);
+int __init gfar_mdio_init(void);
+void __exit gfar_mdio_exit(void);
+#endif /* GIANFAR_PHY_H */
diff --git a/drivers/net/gianfar_phy.c b/drivers/net/gianfar_phy.c
deleted file mode 100644 (file)
index 7c965f2..0000000
+++ /dev/null
@@ -1,661 +0,0 @@
-/* 
- * drivers/net/gianfar_phy.c
- *
- * Gianfar Ethernet Driver -- PHY handling
- * Driver for FEC on MPC8540 and TSEC on MPC8540/MPC8560
- * Based on 8260_io/fcc_enet.c
- *
- * Author: Andy Fleming
- * Maintainer: Kumar Gala (kumar.gala@freescale.com)
- *
- * Copyright (c) 2002-2004 Freescale Semiconductor, Inc.
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- *
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/spinlock.h>
-#include <linux/mm.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
-#include <linux/module.h>
-#include <linux/version.h>
-#include <linux/crc32.h>
-#include <linux/mii.h>
-
-#include "gianfar.h"
-#include "gianfar_phy.h"
-
-static void config_genmii_advert(struct gfar_mii_info *mii_info);
-static void genmii_setup_forced(struct gfar_mii_info *mii_info);
-static void genmii_restart_aneg(struct gfar_mii_info *mii_info);
-static int gbit_config_aneg(struct gfar_mii_info *mii_info);
-static int genmii_config_aneg(struct gfar_mii_info *mii_info);
-static int genmii_update_link(struct gfar_mii_info *mii_info);
-static int genmii_read_status(struct gfar_mii_info *mii_info);
-u16 phy_read(struct gfar_mii_info *mii_info, u16 regnum);
-void phy_write(struct gfar_mii_info *mii_info, u16 regnum, u16 val);
-
-/* Write value to the PHY for this device to the register at regnum, */
-/* waiting until the write is done before it returns.  All PHY */
-/* configuration has to be done through the TSEC1 MIIM regs */
-void write_phy_reg(struct net_device *dev, int mii_id, int regnum, int value)
-{
-       struct gfar_private *priv = netdev_priv(dev);
-       struct gfar *regbase = priv->phyregs;
-
-       /* Set the PHY address and the register address we want to write */
-       gfar_write(&regbase->miimadd, (mii_id << 8) | regnum);
-
-       /* Write out the value we want */
-       gfar_write(&regbase->miimcon, value);
-
-       /* Wait for the transaction to finish */
-       while (gfar_read(&regbase->miimind) & MIIMIND_BUSY)
-               cpu_relax();
-}
-
-/* Reads from register regnum in the PHY for device dev, */
-/* returning the value.  Clears miimcom first.  All PHY */
-/* configuration has to be done through the TSEC1 MIIM regs */
-int read_phy_reg(struct net_device *dev, int mii_id, int regnum)
-{
-       struct gfar_private *priv = netdev_priv(dev);
-       struct gfar *regbase = priv->phyregs;
-       u16 value;
-
-       /* Set the PHY address and the register address we want to read */
-       gfar_write(&regbase->miimadd, (mii_id << 8) | regnum);
-
-       /* Clear miimcom, and then initiate a read */
-       gfar_write(&regbase->miimcom, 0);
-       gfar_write(&regbase->miimcom, MII_READ_COMMAND);
-
-       /* Wait for the transaction to finish */
-       while (gfar_read(&regbase->miimind) & (MIIMIND_NOTVALID | MIIMIND_BUSY))
-               cpu_relax();
-
-       /* Grab the value of the register from miimstat */
-       value = gfar_read(&regbase->miimstat);
-
-       return value;
-}
-
-void mii_clear_phy_interrupt(struct gfar_mii_info *mii_info)
-{
-       if(mii_info->phyinfo->ack_interrupt)
-               mii_info->phyinfo->ack_interrupt(mii_info);
-}
-
-
-void mii_configure_phy_interrupt(struct gfar_mii_info *mii_info, u32 interrupts)
-{
-       mii_info->interrupts = interrupts;
-       if(mii_info->phyinfo->config_intr)
-               mii_info->phyinfo->config_intr(mii_info);
-}
-
-
-/* Writes MII_ADVERTISE with the appropriate values, after
- * sanitizing advertise to make sure only supported features
- * are advertised 
- */
-static void config_genmii_advert(struct gfar_mii_info *mii_info)
-{
-       u32 advertise;
-       u16 adv;
-
-       /* Only allow advertising what this PHY supports */
-       mii_info->advertising &= mii_info->phyinfo->features;
-       advertise = mii_info->advertising;
-
-       /* Setup standard advertisement */
-       adv = phy_read(mii_info, MII_ADVERTISE);
-       adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4);
-       if (advertise & ADVERTISED_10baseT_Half)
-               adv |= ADVERTISE_10HALF;
-       if (advertise & ADVERTISED_10baseT_Full)
-               adv |= ADVERTISE_10FULL;
-       if (advertise & ADVERTISED_100baseT_Half)
-               adv |= ADVERTISE_100HALF;
-       if (advertise & ADVERTISED_100baseT_Full)
-               adv |= ADVERTISE_100FULL;
-       phy_write(mii_info, MII_ADVERTISE, adv);
-}
-
-static void genmii_setup_forced(struct gfar_mii_info *mii_info)
-{
-       u16 ctrl;
-       u32 features = mii_info->phyinfo->features;
-       
-       ctrl = phy_read(mii_info, MII_BMCR);
-
-       ctrl &= ~(BMCR_FULLDPLX|BMCR_SPEED100|BMCR_SPEED1000|BMCR_ANENABLE);
-       ctrl |= BMCR_RESET;
-
-       switch(mii_info->speed) {
-               case SPEED_1000:
-                       if(features & (SUPPORTED_1000baseT_Half
-                                               | SUPPORTED_1000baseT_Full)) {
-                               ctrl |= BMCR_SPEED1000;
-                               break;
-                       }
-                       mii_info->speed = SPEED_100;
-               case SPEED_100:
-                       if (features & (SUPPORTED_100baseT_Half
-                                               | SUPPORTED_100baseT_Full)) {
-                               ctrl |= BMCR_SPEED100;
-                               break;
-                       }
-                       mii_info->speed = SPEED_10;
-               case SPEED_10:
-                       if (features & (SUPPORTED_10baseT_Half
-                                               | SUPPORTED_10baseT_Full))
-                               break;
-               default: /* Unsupported speed! */
-                       printk(KERN_ERR "%s: Bad speed!\n", 
-                                       mii_info->dev->name);
-                       break;
-       }
-
-       phy_write(mii_info, MII_BMCR, ctrl);
-}
-
-
-/* Enable and Restart Autonegotiation */
-static void genmii_restart_aneg(struct gfar_mii_info *mii_info)
-{
-       u16 ctl;
-
-       ctl = phy_read(mii_info, MII_BMCR);
-       ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
-       phy_write(mii_info, MII_BMCR, ctl);
-}
-
-
-static int gbit_config_aneg(struct gfar_mii_info *mii_info)
-{
-       u16 adv;
-       u32 advertise;
-
-       if(mii_info->autoneg) {
-               /* Configure the ADVERTISE register */
-               config_genmii_advert(mii_info);
-               advertise = mii_info->advertising;
-
-               adv = phy_read(mii_info, MII_1000BASETCONTROL);
-               adv &= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP |
-                               MII_1000BASETCONTROL_HALFDUPLEXCAP);
-               if (advertise & SUPPORTED_1000baseT_Half)
-                       adv |= MII_1000BASETCONTROL_HALFDUPLEXCAP;
-               if (advertise & SUPPORTED_1000baseT_Full)
-                       adv |= MII_1000BASETCONTROL_FULLDUPLEXCAP;
-               phy_write(mii_info, MII_1000BASETCONTROL, adv);
-
-               /* Start/Restart aneg */
-               genmii_restart_aneg(mii_info);
-       } else
-               genmii_setup_forced(mii_info);
-
-       return 0;
-}
-
-static int marvell_config_aneg(struct gfar_mii_info *mii_info)
-{
-       /* The Marvell PHY has an errata which requires
-        * that certain registers get written in order
-        * to restart autonegotiation */
-       phy_write(mii_info, MII_BMCR, BMCR_RESET);
-
-       phy_write(mii_info, 0x1d, 0x1f);
-       phy_write(mii_info, 0x1e, 0x200c);
-       phy_write(mii_info, 0x1d, 0x5);
-       phy_write(mii_info, 0x1e, 0);
-       phy_write(mii_info, 0x1e, 0x100);
-
-       gbit_config_aneg(mii_info);
-
-       return 0;
-}
-static int genmii_config_aneg(struct gfar_mii_info *mii_info)
-{
-       if (mii_info->autoneg) {
-               config_genmii_advert(mii_info);
-               genmii_restart_aneg(mii_info);
-       } else
-               genmii_setup_forced(mii_info);
-
-       return 0;
-}
-
-
-static int genmii_update_link(struct gfar_mii_info *mii_info)
-{
-       u16 status;
-
-       /* Do a fake read */
-       phy_read(mii_info, MII_BMSR);
-
-       /* Read link and autonegotiation status */
-       status = phy_read(mii_info, MII_BMSR);
-       if ((status & BMSR_LSTATUS) == 0)
-               mii_info->link = 0;
-       else
-               mii_info->link = 1;
-
-       /* If we are autonegotiating, and not done, 
-        * return an error */
-       if (mii_info->autoneg && !(status & BMSR_ANEGCOMPLETE))
-               return -EAGAIN;
-
-       return 0;
-}
-
-static int genmii_read_status(struct gfar_mii_info *mii_info)
-{
-       u16 status;
-       int err;
-
-       /* Update the link, but return if there
-        * was an error */
-       err = genmii_update_link(mii_info);
-       if (err)
-               return err;
-
-       if (mii_info->autoneg) {
-               status = phy_read(mii_info, MII_LPA);
-
-               if (status & (LPA_10FULL | LPA_100FULL))
-                       mii_info->duplex = DUPLEX_FULL;
-               else
-                       mii_info->duplex = DUPLEX_HALF;
-               if (status & (LPA_100FULL | LPA_100HALF))
-                       mii_info->speed = SPEED_100;
-               else
-                       mii_info->speed = SPEED_10;
-               mii_info->pause = 0;
-       }
-       /* On non-aneg, we assume what we put in BMCR is the speed,
-        * though magic-aneg shouldn't prevent this case from occurring
-        */
-
-       return 0;
-}
-static int marvell_read_status(struct gfar_mii_info *mii_info)
-{
-       u16 status;
-       int err;
-
-       /* Update the link, but return if there
-        * was an error */
-       err = genmii_update_link(mii_info);
-       if (err)
-               return err;
-
-       /* If the link is up, read the speed and duplex */
-       /* If we aren't autonegotiating, assume speeds 
-        * are as set */
-       if (mii_info->autoneg && mii_info->link) {
-               int speed;
-               status = phy_read(mii_info, MII_M1011_PHY_SPEC_STATUS);
-
-#if 0
-               /* If speed and duplex aren't resolved,
-                * return an error.  Isn't this handled
-                * by checking aneg?
-                */
-               if ((status & MII_M1011_PHY_SPEC_STATUS_RESOLVED) == 0)
-                       return -EAGAIN;
-#endif
-
-               /* Get the duplexity */
-               if (status & MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX)
-                       mii_info->duplex = DUPLEX_FULL;
-               else
-                       mii_info->duplex = DUPLEX_HALF;
-
-               /* Get the speed */
-               speed = status & MII_M1011_PHY_SPEC_STATUS_SPD_MASK;
-               switch(speed) {
-                       case MII_M1011_PHY_SPEC_STATUS_1000:
-                               mii_info->speed = SPEED_1000;
-                               break;
-                       case MII_M1011_PHY_SPEC_STATUS_100:
-                               mii_info->speed = SPEED_100;
-                               break;
-                       default:
-                               mii_info->speed = SPEED_10;
-                               break;
-               }
-               mii_info->pause = 0;
-       }
-
-       return 0;
-}
-
-
-static int cis820x_read_status(struct gfar_mii_info *mii_info)
-{
-       u16 status;
-       int err;
-
-       /* Update the link, but return if there
-        * was an error */
-       err = genmii_update_link(mii_info);
-       if (err)
-               return err;
-
-       /* If the link is up, read the speed and duplex */
-       /* If we aren't autonegotiating, assume speeds 
-        * are as set */
-       if (mii_info->autoneg && mii_info->link) {
-               int speed;
-
-               status = phy_read(mii_info, MII_CIS8201_AUX_CONSTAT);
-               if (status & MII_CIS8201_AUXCONSTAT_DUPLEX)
-                       mii_info->duplex = DUPLEX_FULL;
-               else
-                       mii_info->duplex = DUPLEX_HALF;
-
-               speed = status & MII_CIS8201_AUXCONSTAT_SPEED;
-
-               switch (speed) {
-               case MII_CIS8201_AUXCONSTAT_GBIT:
-                       mii_info->speed = SPEED_1000;
-                       break;
-               case MII_CIS8201_AUXCONSTAT_100:
-                       mii_info->speed = SPEED_100;
-                       break;
-               default:
-                       mii_info->speed = SPEED_10;
-                       break;
-               }
-       }
-
-       return 0;
-}
-
-static int marvell_ack_interrupt(struct gfar_mii_info *mii_info)
-{
-       /* Clear the interrupts by reading the reg */
-       phy_read(mii_info, MII_M1011_IEVENT);
-
-       return 0;
-}
-
-static int marvell_config_intr(struct gfar_mii_info *mii_info)
-{
-       if(mii_info->interrupts == MII_INTERRUPT_ENABLED)
-               phy_write(mii_info, MII_M1011_IMASK, MII_M1011_IMASK_INIT);
-       else
-               phy_write(mii_info, MII_M1011_IMASK, MII_M1011_IMASK_CLEAR);
-
-       return 0;
-}
-
-static int cis820x_init(struct gfar_mii_info *mii_info)
-{
-       phy_write(mii_info, MII_CIS8201_AUX_CONSTAT, 
-                       MII_CIS8201_AUXCONSTAT_INIT);
-       phy_write(mii_info, MII_CIS8201_EXT_CON1,
-                       MII_CIS8201_EXTCON1_INIT);
-
-       return 0;
-}
-
-static int cis820x_ack_interrupt(struct gfar_mii_info *mii_info)
-{
-       phy_read(mii_info, MII_CIS8201_ISTAT);
-
-       return 0;
-}
-
-static int cis820x_config_intr(struct gfar_mii_info *mii_info)
-{
-       if(mii_info->interrupts == MII_INTERRUPT_ENABLED)
-               phy_write(mii_info, MII_CIS8201_IMASK, MII_CIS8201_IMASK_MASK);
-       else
-               phy_write(mii_info, MII_CIS8201_IMASK, 0);
-
-       return 0;
-}
-
-#define DM9161_DELAY 10
-
-static int dm9161_read_status(struct gfar_mii_info *mii_info)
-{
-       u16 status;
-       int err;
-
-       /* Update the link, but return if there
-        * was an error */
-       err = genmii_update_link(mii_info);
-       if (err)
-               return err;
-
-       /* If the link is up, read the speed and duplex */
-       /* If we aren't autonegotiating, assume speeds 
-        * are as set */
-       if (mii_info->autoneg && mii_info->link) {
-               status = phy_read(mii_info, MII_DM9161_SCSR);
-               if (status & (MII_DM9161_SCSR_100F | MII_DM9161_SCSR_100H))
-                       mii_info->speed = SPEED_100;
-               else
-                       mii_info->speed = SPEED_10;
-
-               if (status & (MII_DM9161_SCSR_100F | MII_DM9161_SCSR_10F))
-                       mii_info->duplex = DUPLEX_FULL;
-               else
-                       mii_info->duplex = DUPLEX_HALF;
-       }
-
-       return 0;
-}
-
-
-static int dm9161_config_aneg(struct gfar_mii_info *mii_info)
-{
-       struct dm9161_private *priv = mii_info->priv;
-
-       if(0 == priv->resetdone)
-               return -EAGAIN;
-
-       return 0;
-}
-
-static void dm9161_timer(unsigned long data)
-{
-       struct gfar_mii_info *mii_info = (struct gfar_mii_info *)data;
-       struct dm9161_private *priv = mii_info->priv;
-       u16 status = phy_read(mii_info, MII_BMSR);
-
-       if (status & BMSR_ANEGCOMPLETE) {
-               priv->resetdone = 1;
-       } else
-               mod_timer(&priv->timer, jiffies + DM9161_DELAY * HZ);
-}
-
-static int dm9161_init(struct gfar_mii_info *mii_info)
-{
-       struct dm9161_private *priv;
-
-       /* Allocate the private data structure */
-       priv = kmalloc(sizeof(struct dm9161_private), GFP_KERNEL);
-
-       if (NULL == priv)
-               return -ENOMEM;
-
-       mii_info->priv = priv;
-
-       /* Reset is not done yet */
-       priv->resetdone = 0;
-
-       /* Isolate the PHY */
-       phy_write(mii_info, MII_BMCR, BMCR_ISOLATE);
-
-       /* Do not bypass the scrambler/descrambler */
-       phy_write(mii_info, MII_DM9161_SCR, MII_DM9161_SCR_INIT);
-
-       /* Clear 10BTCSR to default */
-       phy_write(mii_info, MII_DM9161_10BTCSR, MII_DM9161_10BTCSR_INIT);
-
-       /* Reconnect the PHY, and enable Autonegotiation */
-       phy_write(mii_info, MII_BMCR, BMCR_ANENABLE);
-
-       /* Start a timer for DM9161_DELAY seconds to wait
-        * for the PHY to be ready */
-       init_timer(&priv->timer);
-       priv->timer.function = &dm9161_timer;
-       priv->timer.data = (unsigned long) mii_info;
-       mod_timer(&priv->timer, jiffies + DM9161_DELAY * HZ);
-
-       return 0;
-}
-
-static void dm9161_close(struct gfar_mii_info *mii_info)
-{
-       struct dm9161_private *priv = mii_info->priv;
-
-       del_timer_sync(&priv->timer);
-       kfree(priv);
-}
-
-#if 0
-static int dm9161_ack_interrupt(struct gfar_mii_info *mii_info)
-{
-       phy_read(mii_info, MII_DM9161_INTR);
-
-       return 0;
-}
-#endif
-
-/* Cicada 820x */
-static struct phy_info phy_info_cis820x = {
-       0x000fc440,
-       "Cicada Cis8204",
-       0x000fffc0,
-       .features       = MII_GBIT_FEATURES,
-       .init           = &cis820x_init,
-       .config_aneg    = &gbit_config_aneg,
-       .read_status    = &cis820x_read_status,
-       .ack_interrupt  = &cis820x_ack_interrupt,
-       .config_intr    = &cis820x_config_intr,
-};
-
-static struct phy_info phy_info_dm9161 = {
-       .phy_id         = 0x0181b880,
-       .name           = "Davicom DM9161E",
-       .phy_id_mask    = 0x0ffffff0,
-       .init           = dm9161_init,
-       .config_aneg    = dm9161_config_aneg,
-       .read_status    = dm9161_read_status,
-       .close          = dm9161_close,
-};
-
-static struct phy_info phy_info_marvell = {
-       .phy_id         = 0x01410c00,
-       .phy_id_mask    = 0xffffff00,
-       .name           = "Marvell 88E1101/88E1111",
-       .features       = MII_GBIT_FEATURES,
-       .config_aneg    = &marvell_config_aneg,
-       .read_status    = &marvell_read_status,
-       .ack_interrupt  = &marvell_ack_interrupt,
-       .config_intr    = &marvell_config_intr,
-};
-
-static struct phy_info phy_info_genmii= {
-       .phy_id         = 0x00000000,
-       .phy_id_mask    = 0x00000000,
-       .name           = "Generic MII",
-       .features       = MII_BASIC_FEATURES,
-       .config_aneg    = genmii_config_aneg,
-       .read_status    = genmii_read_status,
-};
-
-static struct phy_info *phy_info[] = {
-       &phy_info_cis820x,
-       &phy_info_marvell,
-       &phy_info_dm9161,
-       &phy_info_genmii,
-       NULL
-};
-
-u16 phy_read(struct gfar_mii_info *mii_info, u16 regnum)
-{
-       u16 retval;
-       unsigned long flags;
-
-       spin_lock_irqsave(&mii_info->mdio_lock, flags);
-       retval = mii_info->mdio_read(mii_info->dev, mii_info->mii_id, regnum);
-       spin_unlock_irqrestore(&mii_info->mdio_lock, flags);
-
-       return retval;
-}
-
-void phy_write(struct gfar_mii_info *mii_info, u16 regnum, u16 val)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&mii_info->mdio_lock, flags);
-       mii_info->mdio_write(mii_info->dev, 
-                       mii_info->mii_id, 
-                       regnum, val);
-       spin_unlock_irqrestore(&mii_info->mdio_lock, flags);
-}
-
-/* Use the PHY ID registers to determine what type of PHY is attached
- * to device dev.  return a struct phy_info structure describing that PHY
- */
-struct phy_info * get_phy_info(struct gfar_mii_info *mii_info)
-{
-       u16 phy_reg;
-       u32 phy_ID;
-       int i;
-       struct phy_info *theInfo = NULL;
-       struct net_device *dev = mii_info->dev;
-
-       /* Grab the bits from PHYIR1, and put them in the upper half */
-       phy_reg = phy_read(mii_info, MII_PHYSID1);
-       phy_ID = (phy_reg & 0xffff) << 16;
-
-       /* Grab the bits from PHYIR2, and put them in the lower half */
-       phy_reg = phy_read(mii_info, MII_PHYSID2);
-       phy_ID |= (phy_reg & 0xffff);
-
-       /* loop through all the known PHY types, and find one that */
-       /* matches the ID we read from the PHY. */
-       for (i = 0; phy_info[i]; i++)
-               if (phy_info[i]->phy_id == 
-                               (phy_ID & phy_info[i]->phy_id_mask)) {
-                       theInfo = phy_info[i];
-                       break;
-               }
-
-       /* This shouldn't happen, as we have generic PHY support */
-       if (theInfo == NULL) {
-               printk("%s: PHY id %x is not supported!\n", dev->name, phy_ID);
-               return NULL;
-       } else {
-               printk("%s: PHY is %s (%x)\n", dev->name, theInfo->name,
-                      phy_ID);
-       }
-
-       return theInfo;
-}
diff --git a/drivers/net/gianfar_phy.h b/drivers/net/gianfar_phy.h
deleted file mode 100644 (file)
index 1e9b3ab..0000000
+++ /dev/null
@@ -1,213 +0,0 @@
-/* 
- * drivers/net/gianfar_phy.h
- *
- * Gianfar Ethernet Driver -- PHY handling
- * Driver for FEC on MPC8540 and TSEC on MPC8540/MPC8560
- * Based on 8260_io/fcc_enet.c
- *
- * Author: Andy Fleming
- * Maintainer: Kumar Gala (kumar.gala@freescale.com)
- *
- * Copyright (c) 2002-2004 Freescale Semiconductor, Inc.
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- *
- */
-#ifndef __GIANFAR_PHY_H
-#define __GIANFAR_PHY_H
-
-#define MII_end ((u32)-2)
-#define MII_read ((u32)-1)
-
-#define MIIMIND_BUSY            0x00000001
-#define MIIMIND_NOTVALID        0x00000004
-
-#define GFAR_AN_TIMEOUT         2000
-
-/* 1000BT control (Marvell & BCM54xx at least) */
-#define MII_1000BASETCONTROL                   0x09
-#define MII_1000BASETCONTROL_FULLDUPLEXCAP     0x0200
-#define MII_1000BASETCONTROL_HALFDUPLEXCAP     0x0100
-
-/* Cicada Extended Control Register 1 */
-#define MII_CIS8201_EXT_CON1           0x17
-#define MII_CIS8201_EXTCON1_INIT       0x0000
-
-/* Cicada Interrupt Mask Register */
-#define MII_CIS8201_IMASK              0x19
-#define MII_CIS8201_IMASK_IEN          0x8000
-#define MII_CIS8201_IMASK_SPEED        0x4000
-#define MII_CIS8201_IMASK_LINK         0x2000
-#define MII_CIS8201_IMASK_DUPLEX       0x1000
-#define MII_CIS8201_IMASK_MASK         0xf000
-
-/* Cicada Interrupt Status Register */
-#define MII_CIS8201_ISTAT              0x1a
-#define MII_CIS8201_ISTAT_STATUS       0x8000
-#define MII_CIS8201_ISTAT_SPEED        0x4000
-#define MII_CIS8201_ISTAT_LINK         0x2000
-#define MII_CIS8201_ISTAT_DUPLEX       0x1000
-
-/* Cicada Auxiliary Control/Status Register */
-#define MII_CIS8201_AUX_CONSTAT        0x1c
-#define MII_CIS8201_AUXCONSTAT_INIT    0x0004
-#define MII_CIS8201_AUXCONSTAT_DUPLEX  0x0020
-#define MII_CIS8201_AUXCONSTAT_SPEED   0x0018
-#define MII_CIS8201_AUXCONSTAT_GBIT    0x0010
-#define MII_CIS8201_AUXCONSTAT_100     0x0008
-                                                                                
-/* 88E1011 PHY Status Register */
-#define MII_M1011_PHY_SPEC_STATUS              0x11
-#define MII_M1011_PHY_SPEC_STATUS_1000         0x8000
-#define MII_M1011_PHY_SPEC_STATUS_100          0x4000
-#define MII_M1011_PHY_SPEC_STATUS_SPD_MASK     0xc000
-#define MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX   0x2000
-#define MII_M1011_PHY_SPEC_STATUS_RESOLVED     0x0800
-#define MII_M1011_PHY_SPEC_STATUS_LINK         0x0400
-
-#define MII_M1011_IEVENT               0x13
-#define MII_M1011_IEVENT_CLEAR         0x0000
-
-#define MII_M1011_IMASK                        0x12
-#define MII_M1011_IMASK_INIT           0x6400
-#define MII_M1011_IMASK_CLEAR          0x0000
-
-#define MII_DM9161_SCR         0x10
-#define MII_DM9161_SCR_INIT    0x0610
-
-/* DM9161 Specified Configuration and Status Register */
-#define MII_DM9161_SCSR        0x11
-#define MII_DM9161_SCSR_100F   0x8000
-#define MII_DM9161_SCSR_100H   0x4000
-#define MII_DM9161_SCSR_10F    0x2000
-#define MII_DM9161_SCSR_10H    0x1000
-
-/* DM9161 Interrupt Register */
-#define MII_DM9161_INTR        0x15
-#define MII_DM9161_INTR_PEND           0x8000
-#define MII_DM9161_INTR_DPLX_MASK      0x0800
-#define MII_DM9161_INTR_SPD_MASK       0x0400
-#define MII_DM9161_INTR_LINK_MASK      0x0200
-#define MII_DM9161_INTR_MASK           0x0100
-#define MII_DM9161_INTR_DPLX_CHANGE    0x0010
-#define MII_DM9161_INTR_SPD_CHANGE     0x0008
-#define MII_DM9161_INTR_LINK_CHANGE    0x0004
-#define MII_DM9161_INTR_INIT           0x0000
-#define MII_DM9161_INTR_STOP   \
-(MII_DM9161_INTR_DPLX_MASK | MII_DM9161_INTR_SPD_MASK \
- | MII_DM9161_INTR_LINK_MASK | MII_DM9161_INTR_MASK)
-
-/* DM9161 10BT Configuration/Status */
-#define MII_DM9161_10BTCSR     0x12
-#define MII_DM9161_10BTCSR_INIT        0x7800
-
-#define MII_BASIC_FEATURES     (SUPPORTED_10baseT_Half | \
-                                SUPPORTED_10baseT_Full | \
-                                SUPPORTED_100baseT_Half | \
-                                SUPPORTED_100baseT_Full | \
-                                SUPPORTED_Autoneg | \
-                                SUPPORTED_TP | \
-                                SUPPORTED_MII)
-
-#define MII_GBIT_FEATURES      (MII_BASIC_FEATURES | \
-                                SUPPORTED_1000baseT_Half | \
-                                SUPPORTED_1000baseT_Full)
-
-#define MII_READ_COMMAND       0x00000001
-
-#define MII_INTERRUPT_DISABLED 0x0
-#define MII_INTERRUPT_ENABLED 0x1
-/* Taken from mii_if_info and sungem_phy.h */
-struct gfar_mii_info {
-       /* Information about the PHY type */
-       /* And management functions */
-       struct phy_info *phyinfo;
-
-       /* forced speed & duplex (no autoneg)
-        * partner speed & duplex & pause (autoneg)
-        */
-       int speed;
-       int duplex;
-       int pause;
-
-       /* The most recently read link state */
-       int link;
-
-       /* Enabled Interrupts */
-       u32 interrupts;
-
-       u32 advertising;
-       int autoneg;
-       int mii_id;
-
-       /* private data pointer */
-       /* For use by PHYs to maintain extra state */
-       void *priv;
-
-       /* Provided by host chip */
-       struct net_device *dev;
-
-       /* A lock to ensure that only one thing can read/write
-        * the MDIO bus at a time */
-       spinlock_t mdio_lock;
-
-       /* Provided by ethernet driver */
-       int (*mdio_read) (struct net_device *dev, int mii_id, int reg);
-       void (*mdio_write) (struct net_device *dev, int mii_id, int reg, int val);
-};
-
-/* struct phy_info: a structure which defines attributes for a PHY
- *
- * id will contain a number which represents the PHY.  During
- * startup, the driver will poll the PHY to find out what its
- * UID--as defined by registers 2 and 3--is.  The 32-bit result
- * gotten from the PHY will be ANDed with phy_id_mask to
- * discard any bits which may change based on revision numbers
- * unimportant to functionality
- *
- * There are 6 commands which take a gfar_mii_info structure.
- * Each PHY must declare config_aneg, and read_status.
- */
-struct phy_info {
-       u32 phy_id;
-       char *name;
-       unsigned int phy_id_mask;
-       u32 features;
-
-       /* Called to initialize the PHY */
-       int (*init)(struct gfar_mii_info *mii_info);
-
-       /* Called to suspend the PHY for power */
-       int (*suspend)(struct gfar_mii_info *mii_info);
-
-       /* Reconfigures autonegotiation (or disables it) */
-       int (*config_aneg)(struct gfar_mii_info *mii_info);
-
-       /* Determines the negotiated speed and duplex */
-       int (*read_status)(struct gfar_mii_info *mii_info);
-
-       /* Clears any pending interrupts */
-       int (*ack_interrupt)(struct gfar_mii_info *mii_info);
-
-       /* Enables or disables interrupts */
-       int (*config_intr)(struct gfar_mii_info *mii_info);
-
-       /* Clears up any memory if needed */
-       void (*close)(struct gfar_mii_info *mii_info);
-};
-
-struct phy_info *get_phy_info(struct gfar_mii_info *mii_info);
-int read_phy_reg(struct net_device *dev, int mii_id, int regnum);
-void write_phy_reg(struct net_device *dev, int mii_id, int regnum, int value);
-void mii_clear_phy_interrupt(struct gfar_mii_info *mii_info);
-void mii_configure_phy_interrupt(struct gfar_mii_info *mii_info, u32 interrupts);
-
-struct dm9161_private {
-       struct timer_list timer;
-       int resetdone;
-};
-
-#endif /* GIANFAR_PHY_H */
index cf0ac6f..b71fab6 100644 (file)
@@ -2517,10 +2517,8 @@ static int hp100_down_vg_link(struct net_device *dev)
        do {
                if (hp100_inb(VG_LAN_CFG_1) & HP100_LINK_CABLE_ST)
                        break;
-               if (!in_interrupt()) {
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       schedule_timeout(1);
-               }
+               if (!in_interrupt())
+                       schedule_timeout_interruptible(1);
        } while (time_after(time, jiffies));
 
        if (time_after_eq(jiffies, time))       /* no signal->no logout */
@@ -2536,10 +2534,8 @@ static int hp100_down_vg_link(struct net_device *dev)
        do {
                if (!(hp100_inb(VG_LAN_CFG_1) & HP100_LINK_UP_ST))
                        break;
-               if (!in_interrupt()) {
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       schedule_timeout(1);
-               }
+               if (!in_interrupt())
+                       schedule_timeout_interruptible(1);
        } while (time_after(time, jiffies));
 
 #ifdef HP100_DEBUG
@@ -2577,10 +2573,8 @@ static int hp100_down_vg_link(struct net_device *dev)
                do {
                        if (!(hp100_inb(MAC_CFG_4) & HP100_MAC_SEL_ST))
                                break;
-                       if (!in_interrupt()) {
-                               set_current_state(TASK_INTERRUPTIBLE);
-                               schedule_timeout(1);
-                       }
+                       if (!in_interrupt())
+                               schedule_timeout_interruptible(1);
                } while (time_after(time, jiffies));
 
                hp100_orb(HP100_AUTO_MODE, MAC_CFG_3);  /* Autosel back on */
@@ -2591,10 +2585,8 @@ static int hp100_down_vg_link(struct net_device *dev)
        do {
                if ((hp100_inb(VG_LAN_CFG_1) & HP100_LINK_CABLE_ST) == 0)
                        break;
-               if (!in_interrupt()) {
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       schedule_timeout(1);
-               }
+               if (!in_interrupt())
+                       schedule_timeout_interruptible(1);
        } while (time_after(time, jiffies));
 
        if (time_before_eq(time, jiffies)) {
@@ -2606,10 +2598,8 @@ static int hp100_down_vg_link(struct net_device *dev)
 
        time = jiffies + (2 * HZ);      /* This seems to take a while.... */
        do {
-               if (!in_interrupt()) {
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       schedule_timeout(1);
-               }
+               if (!in_interrupt())
+                       schedule_timeout_interruptible(1);
        } while (time_after(time, jiffies));
 
        return 0;
@@ -2659,10 +2649,8 @@ static int hp100_login_to_vg_hub(struct net_device *dev, u_short force_relogin)
                do {
                        if (~(hp100_inb(VG_LAN_CFG_1) & HP100_LINK_UP_ST))
                                break;
-                       if (!in_interrupt()) {
-                               set_current_state(TASK_INTERRUPTIBLE);
-                               schedule_timeout(1);
-                       }
+                       if (!in_interrupt())
+                               schedule_timeout_interruptible(1);
                } while (time_after(time, jiffies));
 
                /* Start an addressed training and optionally request promiscuous port */
@@ -2697,10 +2685,8 @@ static int hp100_login_to_vg_hub(struct net_device *dev, u_short force_relogin)
                do {
                        if (hp100_inb(VG_LAN_CFG_1) & HP100_LINK_CABLE_ST)
                                break;
-                       if (!in_interrupt()) {
-                               set_current_state(TASK_INTERRUPTIBLE);
-                               schedule_timeout(1);
-                       }
+                       if (!in_interrupt())
+                               schedule_timeout_interruptible(1);
                } while (time_before(jiffies, time));
 
                if (time_after_eq(jiffies, time)) {
@@ -2723,10 +2709,8 @@ static int hp100_login_to_vg_hub(struct net_device *dev, u_short force_relogin)
 #endif
                                        break;
                                }
-                               if (!in_interrupt()) {
-                                       set_current_state(TASK_INTERRUPTIBLE);
-                                       schedule_timeout(1);
-                               }
+                               if (!in_interrupt())
+                                       schedule_timeout_interruptible(1);
                        } while (time_after(time, jiffies));
                }
 
index 15f2073..3961a75 100644 (file)
@@ -678,10 +678,9 @@ static void turnaround_delay(const struct stir_cb *stir, long us)
                return;
 
        ticks = us / (1000000 / HZ);
-       if (ticks > 0) {
-               current->state = TASK_INTERRUPTIBLE;
-               schedule_timeout(1 + ticks);
-       } else
+       if (ticks > 0)
+               schedule_timeout_interruptible(1 + ticks);
+       else
                udelay(us);
 }
 
index 9d026ed..04e4718 100644 (file)
@@ -645,11 +645,10 @@ ixgb_phys_id(struct net_device *netdev, uint32_t data)
 
        mod_timer(&adapter->blink_timer, jiffies);
 
-       set_current_state(TASK_INTERRUPTIBLE);
-       if(data)
-               schedule_timeout(data * HZ);
+       if (data)
+               schedule_timeout_interruptible(data * HZ);
        else
-               schedule_timeout(MAX_SCHEDULE_TIMEOUT);
+               schedule_timeout_interruptible(MAX_SCHEDULE_TIMEOUT);
 
        del_timer_sync(&adapter->blink_timer);
        ixgb_led_off(&adapter->hw);
@@ -723,6 +722,7 @@ struct ethtool_ops ixgb_ethtool_ops = {
        .phys_id = ixgb_phys_id,
        .get_stats_count = ixgb_get_stats_count,
        .get_ethtool_stats = ixgb_get_ethtool_stats,
+       .get_perm_addr = ethtool_op_get_perm_addr,
 };
 
 void ixgb_set_ethtool_ops(struct net_device *netdev)
index 89d6d69..176680c 100644 (file)
@@ -460,8 +460,9 @@ ixgb_probe(struct pci_dev *pdev,
        }
 
        ixgb_get_ee_mac_addr(&adapter->hw, netdev->dev_addr);
+       memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len);
 
-       if(!is_valid_ether_addr(netdev->dev_addr)) {
+       if(!is_valid_ether_addr(netdev->perm_addr)) {
                err = -EIO;
                goto err_eeprom;
        }
index 27f0d8a..309d254 100644 (file)
@@ -298,7 +298,7 @@ static int __init lne390_probe1(struct net_device *dev, int ioaddr)
        return 0;
 unmap:
        if (ei_status.reg0)
-               iounmap((void *)dev->mem_start);
+               iounmap(ei_status.mem);
 cleanup:
        free_irq(dev->irq, dev);
        return ret;
index c33cb3d..e42aa79 100644 (file)
@@ -207,6 +207,20 @@ int mii_ethtool_sset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
        return 0;
 }
 
+int mii_check_gmii_support(struct mii_if_info *mii)
+{
+       int reg;
+
+       reg = mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR);
+       if (reg & BMSR_ESTATEN) {
+               reg = mii->mdio_read(mii->dev, mii->phy_id, MII_ESTATUS);
+               if (reg & (ESTATUS_1000_TFULL | ESTATUS_1000_THALF))
+                       return 1;
+       }
+
+       return 0;
+}
+
 int mii_link_ok (struct mii_if_info *mii)
 {
        /* first, a dummy read, needed to latch some MII phys */
@@ -394,5 +408,6 @@ EXPORT_SYMBOL(mii_ethtool_gset);
 EXPORT_SYMBOL(mii_ethtool_sset);
 EXPORT_SYMBOL(mii_check_link);
 EXPORT_SYMBOL(mii_check_media);
+EXPORT_SYMBOL(mii_check_gmii_support);
 EXPORT_SYMBOL(generic_mii_ioctl);
 
index f1c01ac..e531a4e 100644 (file)
@@ -372,6 +372,7 @@ static int __devinit ne2k_pci_init_one (struct pci_dev *pdev,
                printk("%2.2X%s", SA_prom[i], i == 5 ? ".\n": ":");
                dev->dev_addr[i] = SA_prom[i];
        }
+       memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
        return 0;
 
@@ -637,6 +638,7 @@ static struct ethtool_ops ne2k_pci_ethtool_ops = {
        .get_drvinfo            = ne2k_pci_get_drvinfo,
        .get_tx_csum            = ethtool_op_get_tx_csum,
        .get_sg                 = ethtool_op_get_sg,
+       .get_perm_addr          = ethtool_op_get_perm_addr,
 };
 
 static void __devexit ne2k_pci_remove_one (struct pci_dev *pdev)
index 83334db..a3ea69b 100644 (file)
@@ -1632,8 +1632,7 @@ static void ns83820_run_bist(struct net_device *ndev, const char *name, u32 enab
                        timed_out = 1;
                        break;
                }
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(1);
+               schedule_timeout_uninterruptible(1);
        }
 
        if (status & fail)
index 113b680..70fe81a 100644 (file)
@@ -22,8 +22,8 @@
  *************************************************************************/
 
 #define DRV_NAME       "pcnet32"
-#define DRV_VERSION    "1.30j"
-#define DRV_RELDATE    "29.04.2005"
+#define DRV_VERSION    "1.31a"
+#define DRV_RELDATE    "12.Sep.2005"
 #define PFX            DRV_NAME ": "
 
 static const char *version =
@@ -257,6 +257,9 @@ static int homepna[MAX_UNITS];
  * v1.30h  24 Jun 2004 Don Fry correctly select auto, speed, duplex in bcr32.
  * v1.30i  28 Jun 2004 Don Fry change to use module_param.
  * v1.30j  29 Apr 2005 Don Fry fix skb/map leak with loopback test.
+ * v1.31   02 Sep 2005 Hubert WS Lin <wslin@tw.ibm.c0m> added set_ringparam().
+ * v1.31a  12 Sep 2005 Hubert WS Lin <wslin@tw.ibm.c0m> set min ring size to 4
+ *        to allow loopback test to work unchanged.
  */
 
 
@@ -266,17 +269,17 @@ static int homepna[MAX_UNITS];
  * That translates to 2 (4 == 2^^2) and 4 (16 == 2^^4).
  */
 #ifndef PCNET32_LOG_TX_BUFFERS
-#define PCNET32_LOG_TX_BUFFERS 4
-#define PCNET32_LOG_RX_BUFFERS 5
+#define PCNET32_LOG_TX_BUFFERS         4
+#define PCNET32_LOG_RX_BUFFERS         5
+#define PCNET32_LOG_MAX_TX_BUFFERS     9       /* 2^9 == 512 */
+#define PCNET32_LOG_MAX_RX_BUFFERS     9
 #endif
 
 #define TX_RING_SIZE           (1 << (PCNET32_LOG_TX_BUFFERS))
-#define TX_RING_MOD_MASK       (TX_RING_SIZE - 1)
-#define TX_RING_LEN_BITS       ((PCNET32_LOG_TX_BUFFERS) << 12)
+#define TX_MAX_RING_SIZE       (1 << (PCNET32_LOG_MAX_TX_BUFFERS))
 
 #define RX_RING_SIZE           (1 << (PCNET32_LOG_RX_BUFFERS))
-#define RX_RING_MOD_MASK       (RX_RING_SIZE - 1)
-#define RX_RING_LEN_BITS       ((PCNET32_LOG_RX_BUFFERS) << 4)
+#define RX_MAX_RING_SIZE       (1 << (PCNET32_LOG_MAX_RX_BUFFERS))
 
 #define PKT_BUF_SZ             1544
 
@@ -334,14 +337,14 @@ struct pcnet32_access {
 };
 
 /*
- * The first three fields of pcnet32_private are read by the ethernet device
- * so we allocate the structure should be allocated by pci_alloc_consistent().
+ * The first field of pcnet32_private is read by the ethernet device
+ * so the structure should be allocated using pci_alloc_consistent().
  */
 struct pcnet32_private {
-    /* The Tx and Rx ring entries must be aligned on 16-byte boundaries in 32bit mode. */
-    struct pcnet32_rx_head    rx_ring[RX_RING_SIZE];
-    struct pcnet32_tx_head    tx_ring[TX_RING_SIZE];
     struct pcnet32_init_block init_block;
+    /* The Tx and Rx ring entries must be aligned on 16-byte boundaries in 32bit mode. */
+    struct pcnet32_rx_head    *rx_ring;
+    struct pcnet32_tx_head    *tx_ring;
     dma_addr_t         dma_addr;       /* DMA address of beginning of this
                                           object, returned by
                                           pci_alloc_consistent */
@@ -349,13 +352,21 @@ struct pcnet32_private {
                                           structure */
     const char         *name;
     /* The saved address of a sent-in-place packet/buffer, for skfree(). */
-    struct sk_buff     *tx_skbuff[TX_RING_SIZE];
-    struct sk_buff     *rx_skbuff[RX_RING_SIZE];
-    dma_addr_t         tx_dma_addr[TX_RING_SIZE];
-    dma_addr_t         rx_dma_addr[RX_RING_SIZE];
+    struct sk_buff     **tx_skbuff;
+    struct sk_buff     **rx_skbuff;
+    dma_addr_t         *tx_dma_addr;
+    dma_addr_t         *rx_dma_addr;
     struct pcnet32_access      a;
     spinlock_t         lock;           /* Guard lock */
     unsigned int       cur_rx, cur_tx; /* The next free ring entry */
+    unsigned int       rx_ring_size;   /* current rx ring size */
+    unsigned int       tx_ring_size;   /* current tx ring size */
+    unsigned int       rx_mod_mask;    /* rx ring modular mask */
+    unsigned int       tx_mod_mask;    /* tx ring modular mask */
+    unsigned short     rx_len_bits;
+    unsigned short     tx_len_bits;
+    dma_addr_t         rx_ring_dma_addr;
+    dma_addr_t         tx_ring_dma_addr;
     unsigned int       dirty_rx, dirty_tx; /* The ring entries to be free()ed. */
     struct net_device_stats stats;
     char               tx_full;
@@ -397,6 +408,9 @@ static int pcnet32_get_regs_len(struct net_device *dev);
 static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs,
        void *ptr);
 static void pcnet32_purge_tx_ring(struct net_device *dev);
+static int pcnet32_alloc_ring(struct net_device *dev);
+static void pcnet32_free_ring(struct net_device *dev);
+
 
 enum pci_flags_bit {
     PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4,
@@ -613,10 +627,62 @@ static void pcnet32_get_ringparam(struct net_device *dev, struct ethtool_ringpar
 {
     struct pcnet32_private *lp = dev->priv;
 
-    ering->tx_max_pending = TX_RING_SIZE - 1;
-    ering->tx_pending = lp->cur_tx - lp->dirty_tx;
-    ering->rx_max_pending = RX_RING_SIZE - 1;
-    ering->rx_pending = lp->cur_rx & RX_RING_MOD_MASK;
+    ering->tx_max_pending = TX_MAX_RING_SIZE - 1;
+    ering->tx_pending = lp->tx_ring_size - 1;
+    ering->rx_max_pending = RX_MAX_RING_SIZE - 1;
+    ering->rx_pending = lp->rx_ring_size - 1;
+}
+
+static int pcnet32_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
+{
+    struct pcnet32_private *lp = dev->priv;
+    unsigned long flags;
+    int i;
+
+    if (ering->rx_mini_pending || ering->rx_jumbo_pending)
+       return -EINVAL;
+
+    if (netif_running(dev))
+       pcnet32_close(dev);
+
+    spin_lock_irqsave(&lp->lock, flags);
+    pcnet32_free_ring(dev);
+    lp->tx_ring_size = min(ering->tx_pending, (unsigned int) TX_MAX_RING_SIZE);
+    lp->rx_ring_size = min(ering->rx_pending, (unsigned int) RX_MAX_RING_SIZE);
+
+    /* set the minimum ring size to 4, to allow the loopback test to work
+     * unchanged.
+     */
+    for (i = 2; i <= PCNET32_LOG_MAX_TX_BUFFERS; i++) {
+       if (lp->tx_ring_size <= (1 << i))
+           break;
+    }
+    lp->tx_ring_size = (1 << i);
+    lp->tx_mod_mask = lp->tx_ring_size - 1;
+    lp->tx_len_bits = (i << 12);
+
+    for (i = 2; i <= PCNET32_LOG_MAX_RX_BUFFERS; i++) {
+       if (lp->rx_ring_size <= (1 << i))
+           break;
+    }
+    lp->rx_ring_size = (1 << i);
+    lp->rx_mod_mask = lp->rx_ring_size - 1;
+    lp->rx_len_bits = (i << 4);
+
+    if (pcnet32_alloc_ring(dev)) {
+       pcnet32_free_ring(dev);
+       return -ENOMEM;
+    }
+
+    spin_unlock_irqrestore(&lp->lock, flags);
+
+    if (pcnet32_debug & NETIF_MSG_DRV)
+       printk(KERN_INFO PFX "Ring Param Settings: RX: %d, TX: %d\n", lp->rx_ring_size, lp->tx_ring_size);
+
+    if (netif_running(dev))
+       pcnet32_open(dev);
+
+    return 0;
 }
 
 static void pcnet32_get_strings(struct net_device *dev, u32 stringset, u8 *data)
@@ -948,6 +1014,7 @@ static struct ethtool_ops pcnet32_ethtool_ops = {
     .nway_reset                = pcnet32_nway_reset,
     .get_link          = pcnet32_get_link,
     .get_ringparam     = pcnet32_get_ringparam,
+    .set_ringparam     = pcnet32_set_ringparam,
     .get_tx_csum       = ethtool_op_get_tx_csum,
     .get_sg            = ethtool_op_get_sg,
     .get_tso           = ethtool_op_get_tso,
@@ -957,6 +1024,7 @@ static struct ethtool_ops pcnet32_ethtool_ops = {
     .phys_id           = pcnet32_phys_id,
     .get_regs_len      = pcnet32_get_regs_len,
     .get_regs          = pcnet32_get_regs,
+    .get_perm_addr     = ethtool_op_get_perm_addr,
 };
 
 /* only probes for non-PCI devices, the rest are handled by
@@ -1185,9 +1253,10 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
            memcpy(dev->dev_addr, promaddr, 6);
        }
     }
+    memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
     /* if the ethernet address is not valid, force to 00:00:00:00:00:00 */
-    if (!is_valid_ether_addr(dev->dev_addr))
+    if (!is_valid_ether_addr(dev->perm_addr))
        memset(dev->dev_addr, 0, sizeof(dev->dev_addr));
 
     if (pcnet32_debug & NETIF_MSG_PROBE) {
@@ -1239,6 +1308,12 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
     dev->priv = lp;
     lp->name = chipname;
     lp->shared_irq = shared;
+    lp->tx_ring_size = TX_RING_SIZE;           /* default tx ring size */
+    lp->rx_ring_size = RX_RING_SIZE;           /* default rx ring size */
+    lp->tx_mod_mask = lp->tx_ring_size - 1;
+    lp->rx_mod_mask = lp->rx_ring_size - 1;
+    lp->tx_len_bits = (PCNET32_LOG_TX_BUFFERS << 12);
+    lp->rx_len_bits = (PCNET32_LOG_RX_BUFFERS << 4);
     lp->mii_if.full_duplex = fdx;
     lp->mii_if.phy_id_mask = 0x1f;
     lp->mii_if.reg_num_mask = 0x1f;
@@ -1265,21 +1340,23 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
     }
     lp->a = *a;
 
+    if (pcnet32_alloc_ring(dev)) {
+       ret = -ENOMEM;
+       goto err_free_ring;
+    }
     /* detect special T1/E1 WAN card by checking for MAC address */
     if (dev->dev_addr[0] == 0x00 && dev->dev_addr[1] == 0xe0
            && dev->dev_addr[2] == 0x75)
        lp->options = PCNET32_PORT_FD | PCNET32_PORT_GPSI;
 
     lp->init_block.mode = le16_to_cpu(0x0003); /* Disable Rx and Tx. */
-    lp->init_block.tlen_rlen = le16_to_cpu(TX_RING_LEN_BITS | RX_RING_LEN_BITS);
+    lp->init_block.tlen_rlen = le16_to_cpu(lp->tx_len_bits | lp->rx_len_bits);
     for (i = 0; i < 6; i++)
        lp->init_block.phys_addr[i] = dev->dev_addr[i];
     lp->init_block.filter[0] = 0x00000000;
     lp->init_block.filter[1] = 0x00000000;
-    lp->init_block.rx_ring = (u32)le32_to_cpu(lp->dma_addr +
-           offsetof(struct pcnet32_private, rx_ring));
-    lp->init_block.tx_ring = (u32)le32_to_cpu(lp->dma_addr +
-           offsetof(struct pcnet32_private, tx_ring));
+    lp->init_block.rx_ring = (u32)le32_to_cpu(lp->rx_ring_dma_addr);
+    lp->init_block.tx_ring = (u32)le32_to_cpu(lp->tx_ring_dma_addr);
 
     /* switch pcnet32 to 32bit mode */
     a->write_bcr(ioaddr, 20, 2);
@@ -1310,7 +1387,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
            if (pcnet32_debug & NETIF_MSG_PROBE)
                printk(", failed to detect IRQ line.\n");
            ret = -ENODEV;
-           goto err_free_consistent;
+           goto err_free_ring;
        }
        if (pcnet32_debug & NETIF_MSG_PROBE)
            printk(", probed IRQ %d.\n", dev->irq);
@@ -1341,7 +1418,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
 
     /* Fill in the generic fields of the device structure. */
     if (register_netdev(dev))
-       goto err_free_consistent;
+       goto err_free_ring;
 
     if (pdev) {
        pci_set_drvdata(pdev, dev);
@@ -1359,6 +1436,8 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
 
     return 0;
 
+err_free_ring:
+    pcnet32_free_ring(dev);
 err_free_consistent:
     pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr);
 err_free_netdev:
@@ -1369,6 +1448,86 @@ err_release_region:
 }
 
 
+static int pcnet32_alloc_ring(struct net_device *dev)
+{
+    struct pcnet32_private *lp = dev->priv;
+
+    if ((lp->tx_ring = pci_alloc_consistent(lp->pci_dev, sizeof(struct pcnet32_tx_head) * lp->tx_ring_size,
+       &lp->tx_ring_dma_addr)) == NULL) {
+       if (pcnet32_debug & NETIF_MSG_DRV)
+           printk(KERN_ERR PFX "Consistent memory allocation failed.\n");
+       return -ENOMEM;
+    }
+
+    if ((lp->rx_ring = pci_alloc_consistent(lp->pci_dev, sizeof(struct pcnet32_rx_head) * lp->rx_ring_size,
+       &lp->rx_ring_dma_addr)) == NULL) {
+       if (pcnet32_debug & NETIF_MSG_DRV)
+           printk(KERN_ERR PFX "Consistent memory allocation failed.\n");
+       return -ENOMEM;
+    }
+
+    if (!(lp->tx_dma_addr = kmalloc(sizeof(dma_addr_t) * lp->tx_ring_size, GFP_ATOMIC))) {
+       if (pcnet32_debug & NETIF_MSG_DRV)
+           printk(KERN_ERR PFX "Memory allocation failed.\n");
+       return -ENOMEM;
+    }
+    memset(lp->tx_dma_addr, 0, sizeof(dma_addr_t) * lp->tx_ring_size);
+
+    if (!(lp->rx_dma_addr = kmalloc(sizeof(dma_addr_t) * lp->rx_ring_size, GFP_ATOMIC))) {
+       if (pcnet32_debug & NETIF_MSG_DRV)
+           printk(KERN_ERR PFX "Memory allocation failed.\n");
+       return -ENOMEM;
+    }
+    memset(lp->rx_dma_addr, 0, sizeof(dma_addr_t) * lp->rx_ring_size);
+
+    if (!(lp->tx_skbuff = kmalloc(sizeof(struct sk_buff *) * lp->tx_ring_size, GFP_ATOMIC))) {
+       if (pcnet32_debug & NETIF_MSG_DRV)
+           printk(KERN_ERR PFX "Memory allocation failed.\n");
+       return -ENOMEM;
+    }
+    memset(lp->tx_skbuff, 0, sizeof(struct sk_buff *) * lp->tx_ring_size);
+
+    if (!(lp->rx_skbuff = kmalloc(sizeof(struct sk_buff *) * lp->rx_ring_size, GFP_ATOMIC))) {
+       if (pcnet32_debug & NETIF_MSG_DRV)
+           printk(KERN_ERR PFX "Memory allocation failed.\n");
+       return -ENOMEM;
+    }
+    memset(lp->rx_skbuff, 0, sizeof(struct sk_buff *) * lp->rx_ring_size);
+
+    return 0;
+}
+
+
+static void pcnet32_free_ring(struct net_device *dev)
+{
+    struct pcnet32_private *lp = dev->priv;
+
+    kfree(lp->tx_skbuff);
+    lp->tx_skbuff = NULL;
+
+    kfree(lp->rx_skbuff);
+    lp->rx_skbuff = NULL;
+
+    kfree(lp->tx_dma_addr);
+    lp->tx_dma_addr = NULL;
+
+    kfree(lp->rx_dma_addr);
+    lp->rx_dma_addr = NULL;
+
+    if (lp->tx_ring) {
+       pci_free_consistent(lp->pci_dev, sizeof(struct pcnet32_tx_head) * lp->tx_ring_size,
+               lp->tx_ring, lp->tx_ring_dma_addr);
+       lp->tx_ring = NULL;
+    }
+
+    if (lp->rx_ring) {
+       pci_free_consistent(lp->pci_dev, sizeof(struct pcnet32_rx_head) * lp->rx_ring_size,
+               lp->rx_ring, lp->rx_ring_dma_addr);
+       lp->rx_ring = NULL;
+    }
+}
+
+
 static int
 pcnet32_open(struct net_device *dev)
 {
@@ -1400,8 +1559,8 @@ pcnet32_open(struct net_device *dev)
     if (netif_msg_ifup(lp))
        printk(KERN_DEBUG "%s: pcnet32_open() irq %d tx/rx rings %#x/%#x init %#x.\n",
               dev->name, dev->irq,
-              (u32) (lp->dma_addr + offsetof(struct pcnet32_private, tx_ring)),
-              (u32) (lp->dma_addr + offsetof(struct pcnet32_private, rx_ring)),
+              (u32) (lp->tx_ring_dma_addr),
+              (u32) (lp->rx_ring_dma_addr),
               (u32) (lp->dma_addr + offsetof(struct pcnet32_private, init_block)));
 
     /* set/reset autoselect bit */
@@ -1521,7 +1680,7 @@ pcnet32_open(struct net_device *dev)
 
 err_free_ring:
     /* free any allocated skbuffs */
-    for (i = 0; i < RX_RING_SIZE; i++) {
+    for (i = 0; i < lp->rx_ring_size; i++) {
        lp->rx_ring[i].status = 0;
        if (lp->rx_skbuff[i]) {
            pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[i], PKT_BUF_SZ-2,
@@ -1531,6 +1690,9 @@ err_free_ring:
        lp->rx_skbuff[i] = NULL;
        lp->rx_dma_addr[i] = 0;
     }
+
+    pcnet32_free_ring(dev);
+
     /*
      * Switch back to 16bit mode to avoid problems with dumb
      * DOS packet driver after a warm reboot
@@ -1562,7 +1724,7 @@ pcnet32_purge_tx_ring(struct net_device *dev)
     struct pcnet32_private *lp = dev->priv;
     int i;
 
-    for (i = 0; i < TX_RING_SIZE; i++) {
+    for (i = 0; i < lp->tx_ring_size; i++) {
        lp->tx_ring[i].status = 0;      /* CPU owns buffer */
        wmb();  /* Make sure adapter sees owner change */
        if (lp->tx_skbuff[i]) {
@@ -1587,7 +1749,7 @@ pcnet32_init_ring(struct net_device *dev)
     lp->cur_rx = lp->cur_tx = 0;
     lp->dirty_rx = lp->dirty_tx = 0;
 
-    for (i = 0; i < RX_RING_SIZE; i++) {
+    for (i = 0; i < lp->rx_ring_size; i++) {
        struct sk_buff *rx_skbuff = lp->rx_skbuff[i];
        if (rx_skbuff == NULL) {
            if (!(rx_skbuff = lp->rx_skbuff[i] = dev_alloc_skb (PKT_BUF_SZ))) {
@@ -1611,20 +1773,18 @@ pcnet32_init_ring(struct net_device *dev)
     }
     /* The Tx buffer address is filled in as needed, but we do need to clear
      * the upper ownership bit. */
-    for (i = 0; i < TX_RING_SIZE; i++) {
+    for (i = 0; i < lp->tx_ring_size; i++) {
        lp->tx_ring[i].status = 0;      /* CPU owns buffer */
        wmb();  /* Make sure adapter sees owner change */
        lp->tx_ring[i].base = 0;
        lp->tx_dma_addr[i] = 0;
     }
 
-    lp->init_block.tlen_rlen = le16_to_cpu(TX_RING_LEN_BITS | RX_RING_LEN_BITS);
+    lp->init_block.tlen_rlen = le16_to_cpu(lp->tx_len_bits | lp->rx_len_bits);
     for (i = 0; i < 6; i++)
        lp->init_block.phys_addr[i] = dev->dev_addr[i];
-    lp->init_block.rx_ring = (u32)le32_to_cpu(lp->dma_addr +
-           offsetof(struct pcnet32_private, rx_ring));
-    lp->init_block.tx_ring = (u32)le32_to_cpu(lp->dma_addr +
-           offsetof(struct pcnet32_private, tx_ring));
+    lp->init_block.rx_ring = (u32)le32_to_cpu(lp->rx_ring_dma_addr);
+    lp->init_block.tx_ring = (u32)le32_to_cpu(lp->tx_ring_dma_addr);
     wmb();     /* Make sure all changes are visible */
     return 0;
 }
@@ -1682,13 +1842,13 @@ pcnet32_tx_timeout (struct net_device *dev)
        printk(KERN_DEBUG " Ring data dump: dirty_tx %d cur_tx %d%s cur_rx %d.",
           lp->dirty_tx, lp->cur_tx, lp->tx_full ? " (full)" : "",
           lp->cur_rx);
-       for (i = 0 ; i < RX_RING_SIZE; i++)
+       for (i = 0 ; i < lp->rx_ring_size; i++)
        printk("%s %08x %04x %08x %04x", i & 1 ? "" : "\n ",
               le32_to_cpu(lp->rx_ring[i].base),
               (-le16_to_cpu(lp->rx_ring[i].buf_length)) & 0xffff,
               le32_to_cpu(lp->rx_ring[i].msg_length),
               le16_to_cpu(lp->rx_ring[i].status));
-       for (i = 0 ; i < TX_RING_SIZE; i++)
+       for (i = 0 ; i < lp->tx_ring_size; i++)
        printk("%s %08x %04x %08x %04x", i & 1 ? "" : "\n ",
               le32_to_cpu(lp->tx_ring[i].base),
               (-le16_to_cpu(lp->tx_ring[i].length)) & 0xffff,
@@ -1729,7 +1889,7 @@ pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev)
     /* Fill in a Tx ring entry */
 
     /* Mask to ring buffer boundary. */
-    entry = lp->cur_tx & TX_RING_MOD_MASK;
+    entry = lp->cur_tx & lp->tx_mod_mask;
 
     /* Caution: the write order is important here, set the status
      * with the "ownership" bits last. */
@@ -1753,7 +1913,7 @@ pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
     dev->trans_start = jiffies;
 
-    if (lp->tx_ring[(entry+1) & TX_RING_MOD_MASK].base != 0) {
+    if (lp->tx_ring[(entry+1) & lp->tx_mod_mask].base != 0) {
        lp->tx_full = 1;
        netif_stop_queue(dev);
     }
@@ -1806,7 +1966,7 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs)
            int delta;
 
            while (dirty_tx != lp->cur_tx) {
-               int entry = dirty_tx & TX_RING_MOD_MASK;
+               int entry = dirty_tx & lp->tx_mod_mask;
                int status = (short)le16_to_cpu(lp->tx_ring[entry].status);
 
                if (status < 0)
@@ -1864,18 +2024,18 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs)
                dirty_tx++;
            }
 
-           delta = (lp->cur_tx - dirty_tx) & (TX_RING_MOD_MASK + TX_RING_SIZE);
-           if (delta > TX_RING_SIZE) {
+           delta = (lp->cur_tx - dirty_tx) & (lp->tx_mod_mask + lp->tx_ring_size);
+           if (delta > lp->tx_ring_size) {
                if (netif_msg_drv(lp))
                    printk(KERN_ERR "%s: out-of-sync dirty pointer, %d vs. %d, full=%d.\n",
                            dev->name, dirty_tx, lp->cur_tx, lp->tx_full);
-               dirty_tx += TX_RING_SIZE;
-               delta -= TX_RING_SIZE;
+               dirty_tx += lp->tx_ring_size;
+               delta -= lp->tx_ring_size;
            }
 
            if (lp->tx_full &&
                netif_queue_stopped(dev) &&
-               delta < TX_RING_SIZE - 2) {
+               delta < lp->tx_ring_size - 2) {
                /* The ring is no longer full, clear tbusy. */
                lp->tx_full = 0;
                netif_wake_queue (dev);
@@ -1932,8 +2092,8 @@ static int
 pcnet32_rx(struct net_device *dev)
 {
     struct pcnet32_private *lp = dev->priv;
-    int entry = lp->cur_rx & RX_RING_MOD_MASK;
-    int boguscnt = RX_RING_SIZE / 2;
+    int entry = lp->cur_rx & lp->rx_mod_mask;
+    int boguscnt = lp->rx_ring_size / 2;
 
     /* If we own the next entry, it's a new packet. Send it up. */
     while ((short)le16_to_cpu(lp->rx_ring[entry].status) >= 0) {
@@ -1998,12 +2158,12 @@ pcnet32_rx(struct net_device *dev)
                    if (netif_msg_drv(lp))
                        printk(KERN_ERR "%s: Memory squeeze, deferring packet.\n",
                                dev->name);
-                   for (i = 0; i < RX_RING_SIZE; i++)
+                   for (i = 0; i < lp->rx_ring_size; i++)
                        if ((short)le16_to_cpu(lp->rx_ring[(entry+i)
-                                   & RX_RING_MOD_MASK].status) < 0)
+                                   & lp->rx_mod_mask].status) < 0)
                            break;
 
-                   if (i > RX_RING_SIZE -2) {
+                   if (i > lp->rx_ring_size -2) {
                        lp->stats.rx_dropped++;
                        lp->rx_ring[entry].status |= le16_to_cpu(0x8000);
                        wmb();  /* Make sure adapter sees owner change */
@@ -2041,7 +2201,7 @@ pcnet32_rx(struct net_device *dev)
        lp->rx_ring[entry].buf_length = le16_to_cpu(2-PKT_BUF_SZ);
        wmb(); /* Make sure owner changes after all others are visible */
        lp->rx_ring[entry].status |= le16_to_cpu(0x8000);
-       entry = (++lp->cur_rx) & RX_RING_MOD_MASK;
+       entry = (++lp->cur_rx) & lp->rx_mod_mask;
        if (--boguscnt <= 0) break;     /* don't stay in loop forever */
     }
 
@@ -2084,7 +2244,7 @@ pcnet32_close(struct net_device *dev)
     spin_lock_irqsave(&lp->lock, flags);
 
     /* free all allocated skbuffs */
-    for (i = 0; i < RX_RING_SIZE; i++) {
+    for (i = 0; i < lp->rx_ring_size; i++) {
        lp->rx_ring[i].status = 0;
        wmb();          /* Make sure adapter sees owner change */
        if (lp->rx_skbuff[i]) {
@@ -2096,7 +2256,7 @@ pcnet32_close(struct net_device *dev)
        lp->rx_dma_addr[i] = 0;
     }
 
-    for (i = 0; i < TX_RING_SIZE; i++) {
+    for (i = 0; i < lp->tx_ring_size; i++) {
        lp->tx_ring[i].status = 0;      /* CPU owns buffer */
        wmb();          /* Make sure adapter sees owner change */
        if (lp->tx_skbuff[i]) {
@@ -2265,6 +2425,7 @@ static void __devexit pcnet32_remove_one(struct pci_dev *pdev)
        struct pcnet32_private *lp = dev->priv;
 
        unregister_netdev(dev);
+       pcnet32_free_ring(dev);
        release_region(dev->base_addr, PCNET32_TOTAL_SIZE);
        pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr);
        free_netdev(dev);
@@ -2340,6 +2501,7 @@ static void __exit pcnet32_cleanup_module(void)
        struct pcnet32_private *lp = pcnet32_dev->priv;
        next_dev = lp->next;
        unregister_netdev(pcnet32_dev);
+       pcnet32_free_ring(pcnet32_dev);
        release_region(pcnet32_dev->base_addr, PCNET32_TOTAL_SIZE);
        pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr);
        free_netdev(pcnet32_dev);
index 14f4de1..c782a63 100644 (file)
@@ -12,14 +12,6 @@ config PHYLIB
          devices.  This option provides infrastructure for
          managing PHY devices.
 
-config PHYCONTROL
-       bool "  Support for automatically handling PHY state changes"
-       depends on PHYLIB
-       help
-         Adds code to perform all the work for keeping PHY link
-         state (speed/duplex/etc) up-to-date.  Also handles
-         interrupts.
-
 comment "MII PHY device drivers"
        depends on PHYLIB
 
index d9e11f9..9209da9 100644 (file)
@@ -242,10 +242,6 @@ EXPORT_SYMBOL(phy_sanitize_settings);
  *   choose the next best ones from the ones selected, so we don't
  *   care if ethtool tries to give us bad values
  *
- * A note about the PHYCONTROL Layer.  If you turn off
- * CONFIG_PHYCONTROL, you will need to read the PHY status
- * registers after this function completes, and update your
- * controller manually.
  */
 int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd)
 {
@@ -380,7 +376,6 @@ int phy_start_aneg(struct phy_device *phydev)
 
        err = phydev->drv->config_aneg(phydev);
 
-#ifdef CONFIG_PHYCONTROL
        if (err < 0)
                goto out_unlock;
 
@@ -395,14 +390,12 @@ int phy_start_aneg(struct phy_device *phydev)
        }
 
 out_unlock:
-#endif
        spin_unlock(&phydev->lock);
        return err;
 }
 EXPORT_SYMBOL(phy_start_aneg);
 
 
-#ifdef CONFIG_PHYCONTROL
 static void phy_change(void *data);
 static void phy_timer(unsigned long data);
 
@@ -868,4 +861,3 @@ static void phy_timer(unsigned long data)
        mod_timer(&phydev->phy_timer, jiffies + PHY_STATE_TIME * HZ);
 }
 
-#endif /* CONFIG_PHYCONTROL */
index 33f7bdb..6da1aa0 100644 (file)
@@ -101,7 +101,6 @@ struct phy_device * get_phy_device(struct mii_bus *bus, int addr)
        return dev;
 }
 
-#ifdef CONFIG_PHYCONTROL
 /* phy_prepare_link:
  *
  * description: Tells the PHY infrastructure to handle the
@@ -160,8 +159,6 @@ void phy_disconnect(struct phy_device *phydev)
 }
 EXPORT_SYMBOL(phy_disconnect);
 
-#endif /* CONFIG_PHYCONTROL */
-
 /* phy_attach:
  *
  *   description: Called by drivers to attach to a particular PHY
index afb3f18..159b56a 100644 (file)
@@ -1027,6 +1027,7 @@ static struct ethtool_ops rtl8169_ethtool_ops = {
        .get_strings            = rtl8169_get_strings,
        .get_stats_count        = rtl8169_get_stats_count,
        .get_ethtool_stats      = rtl8169_get_ethtool_stats,
+       .get_perm_addr          = ethtool_op_get_perm_addr,
 };
 
 static void rtl8169_write_gmii_reg_bit(void __iomem *ioaddr, int reg, int bitnum,
@@ -1511,6 +1512,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        /* Get MAC address.  FIXME: read EEPROM */
        for (i = 0; i < MAC_ADDR_LEN; i++)
                dev->dev_addr[i] = RTL_R8(MAC0 + i);
+       memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
        dev->open = rtl8169_open;
        dev->hard_start_xmit = rtl8169_start_xmit;
diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
new file mode 100644 (file)
index 0000000..12cde06
--- /dev/null
@@ -0,0 +1,574 @@
+/*
+ * rionet - Ethernet driver over RapidIO messaging services
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/dma-mapping.h>
+#include <linux/delay.h>
+#include <linux/rio.h>
+#include <linux/rio_drv.h>
+#include <linux/rio_ids.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/crc32.h>
+#include <linux/ethtool.h>
+
+#define DRV_NAME        "rionet"
+#define DRV_VERSION     "0.2"
+#define DRV_AUTHOR      "Matt Porter <mporter@kernel.crashing.org>"
+#define DRV_DESC        "Ethernet over RapidIO"
+
+MODULE_AUTHOR(DRV_AUTHOR);
+MODULE_DESCRIPTION(DRV_DESC);
+MODULE_LICENSE("GPL");
+
+#define RIONET_DEFAULT_MSGLEVEL \
+                       (NETIF_MSG_DRV          | \
+                        NETIF_MSG_LINK         | \
+                        NETIF_MSG_RX_ERR       | \
+                        NETIF_MSG_TX_ERR)
+
+#define RIONET_DOORBELL_JOIN   0x1000
+#define RIONET_DOORBELL_LEAVE  0x1001
+
+#define RIONET_MAILBOX         0
+
+#define RIONET_TX_RING_SIZE    CONFIG_RIONET_TX_SIZE
+#define RIONET_RX_RING_SIZE    CONFIG_RIONET_RX_SIZE
+
+static LIST_HEAD(rionet_peers);
+
+struct rionet_private {
+       struct rio_mport *mport;
+       struct sk_buff *rx_skb[RIONET_RX_RING_SIZE];
+       struct sk_buff *tx_skb[RIONET_TX_RING_SIZE];
+       struct net_device_stats stats;
+       int rx_slot;
+       int tx_slot;
+       int tx_cnt;
+       int ack_slot;
+       spinlock_t lock;
+       spinlock_t tx_lock;
+       u32 msg_enable;
+};
+
+struct rionet_peer {
+       struct list_head node;
+       struct rio_dev *rdev;
+       struct resource *res;
+};
+
+static int rionet_check = 0;
+static int rionet_capable = 1;
+
+/*
+ * This is a fast lookup table for for translating TX
+ * Ethernet packets into a destination RIO device. It
+ * could be made into a hash table to save memory depending
+ * on system trade-offs.
+ */
+static struct rio_dev *rionet_active[RIO_MAX_ROUTE_ENTRIES];
+
+#define is_rionet_capable(pef, src_ops, dst_ops)               \
+                       ((pef & RIO_PEF_INB_MBOX) &&            \
+                        (pef & RIO_PEF_INB_DOORBELL) &&        \
+                        (src_ops & RIO_SRC_OPS_DOORBELL) &&    \
+                        (dst_ops & RIO_DST_OPS_DOORBELL))
+#define dev_rionet_capable(dev) \
+       is_rionet_capable(dev->pef, dev->src_ops, dev->dst_ops)
+
+#define RIONET_MAC_MATCH(x)    (*(u32 *)x == 0x00010001)
+#define RIONET_GET_DESTID(x)   (*(u16 *)(x + 4))
+
+static struct net_device_stats *rionet_stats(struct net_device *ndev)
+{
+       struct rionet_private *rnet = ndev->priv;
+       return &rnet->stats;
+}
+
+static int rionet_rx_clean(struct net_device *ndev)
+{
+       int i;
+       int error = 0;
+       struct rionet_private *rnet = ndev->priv;
+       void *data;
+
+       i = rnet->rx_slot;
+
+       do {
+               if (!rnet->rx_skb[i])
+                       continue;
+
+               if (!(data = rio_get_inb_message(rnet->mport, RIONET_MAILBOX)))
+                       break;
+
+               rnet->rx_skb[i]->data = data;
+               skb_put(rnet->rx_skb[i], RIO_MAX_MSG_SIZE);
+               rnet->rx_skb[i]->dev = ndev;
+               rnet->rx_skb[i]->protocol =
+                   eth_type_trans(rnet->rx_skb[i], ndev);
+               error = netif_rx(rnet->rx_skb[i]);
+
+               if (error == NET_RX_DROP) {
+                       rnet->stats.rx_dropped++;
+               } else if (error == NET_RX_BAD) {
+                       if (netif_msg_rx_err(rnet))
+                               printk(KERN_WARNING "%s: bad rx packet\n",
+                                      DRV_NAME);
+                       rnet->stats.rx_errors++;
+               } else {
+                       rnet->stats.rx_packets++;
+                       rnet->stats.rx_bytes += RIO_MAX_MSG_SIZE;
+               }
+
+       } while ((i = (i + 1) % RIONET_RX_RING_SIZE) != rnet->rx_slot);
+
+       return i;
+}
+
+static void rionet_rx_fill(struct net_device *ndev, int end)
+{
+       int i;
+       struct rionet_private *rnet = ndev->priv;
+
+       i = rnet->rx_slot;
+       do {
+               rnet->rx_skb[i] = dev_alloc_skb(RIO_MAX_MSG_SIZE);
+
+               if (!rnet->rx_skb[i])
+                       break;
+
+               rio_add_inb_buffer(rnet->mport, RIONET_MAILBOX,
+                                  rnet->rx_skb[i]->data);
+       } while ((i = (i + 1) % RIONET_RX_RING_SIZE) != end);
+
+       rnet->rx_slot = i;
+}
+
+static int rionet_queue_tx_msg(struct sk_buff *skb, struct net_device *ndev,
+                              struct rio_dev *rdev)
+{
+       struct rionet_private *rnet = ndev->priv;
+
+       rio_add_outb_message(rnet->mport, rdev, 0, skb->data, skb->len);
+       rnet->tx_skb[rnet->tx_slot] = skb;
+
+       rnet->stats.tx_packets++;
+       rnet->stats.tx_bytes += skb->len;
+
+       if (++rnet->tx_cnt == RIONET_TX_RING_SIZE)
+               netif_stop_queue(ndev);
+
+       ++rnet->tx_slot;
+       rnet->tx_slot &= (RIONET_TX_RING_SIZE - 1);
+
+       if (netif_msg_tx_queued(rnet))
+               printk(KERN_INFO "%s: queued skb %8.8x len %8.8x\n", DRV_NAME,
+                      (u32) skb, skb->len);
+
+       return 0;
+}
+
+static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+       int i;
+       struct rionet_private *rnet = ndev->priv;
+       struct ethhdr *eth = (struct ethhdr *)skb->data;
+       u16 destid;
+       unsigned long flags;
+
+       local_irq_save(flags);
+       if (!spin_trylock(&rnet->tx_lock)) {
+               local_irq_restore(flags);
+               return NETDEV_TX_LOCKED;
+       }
+
+       if ((rnet->tx_cnt + 1) > RIONET_TX_RING_SIZE) {
+               netif_stop_queue(ndev);
+               spin_unlock_irqrestore(&rnet->tx_lock, flags);
+               printk(KERN_ERR "%s: BUG! Tx Ring full when queue awake!\n",
+                      ndev->name);
+               return NETDEV_TX_BUSY;
+       }
+
+       if (eth->h_dest[0] & 0x01) {
+               for (i = 0; i < RIO_MAX_ROUTE_ENTRIES; i++)
+                       if (rionet_active[i])
+                               rionet_queue_tx_msg(skb, ndev,
+                                                   rionet_active[i]);
+       } else if (RIONET_MAC_MATCH(eth->h_dest)) {
+               destid = RIONET_GET_DESTID(eth->h_dest);
+               if (rionet_active[destid])
+                       rionet_queue_tx_msg(skb, ndev, rionet_active[destid]);
+       }
+
+       spin_unlock_irqrestore(&rnet->tx_lock, flags);
+
+       return 0;
+}
+
+static void rionet_dbell_event(struct rio_mport *mport, void *dev_id, u16 sid, u16 tid,
+                              u16 info)
+{
+       struct net_device *ndev = dev_id;
+       struct rionet_private *rnet = ndev->priv;
+       struct rionet_peer *peer;
+
+       if (netif_msg_intr(rnet))
+               printk(KERN_INFO "%s: doorbell sid %4.4x tid %4.4x info %4.4x",
+                      DRV_NAME, sid, tid, info);
+       if (info == RIONET_DOORBELL_JOIN) {
+               if (!rionet_active[sid]) {
+                       list_for_each_entry(peer, &rionet_peers, node) {
+                               if (peer->rdev->destid == sid)
+                                       rionet_active[sid] = peer->rdev;
+                       }
+                       rio_mport_send_doorbell(mport, sid,
+                                               RIONET_DOORBELL_JOIN);
+               }
+       } else if (info == RIONET_DOORBELL_LEAVE) {
+               rionet_active[sid] = NULL;
+       } else {
+               if (netif_msg_intr(rnet))
+                       printk(KERN_WARNING "%s: unhandled doorbell\n",
+                              DRV_NAME);
+       }
+}
+
+static void rionet_inb_msg_event(struct rio_mport *mport, void *dev_id, int mbox, int slot)
+{
+       int n;
+       struct net_device *ndev = dev_id;
+       struct rionet_private *rnet = (struct rionet_private *)ndev->priv;
+
+       if (netif_msg_intr(rnet))
+               printk(KERN_INFO "%s: inbound message event, mbox %d slot %d\n",
+                      DRV_NAME, mbox, slot);
+
+       spin_lock(&rnet->lock);
+       if ((n = rionet_rx_clean(ndev)) != rnet->rx_slot)
+               rionet_rx_fill(ndev, n);
+       spin_unlock(&rnet->lock);
+}
+
+static void rionet_outb_msg_event(struct rio_mport *mport, void *dev_id, int mbox, int slot)
+{
+       struct net_device *ndev = dev_id;
+       struct rionet_private *rnet = ndev->priv;
+
+       spin_lock(&rnet->lock);
+
+       if (netif_msg_intr(rnet))
+               printk(KERN_INFO
+                      "%s: outbound message event, mbox %d slot %d\n",
+                      DRV_NAME, mbox, slot);
+
+       while (rnet->tx_cnt && (rnet->ack_slot != slot)) {
+               /* dma unmap single */
+               dev_kfree_skb_irq(rnet->tx_skb[rnet->ack_slot]);
+               rnet->tx_skb[rnet->ack_slot] = NULL;
+               ++rnet->ack_slot;
+               rnet->ack_slot &= (RIONET_TX_RING_SIZE - 1);
+               rnet->tx_cnt--;
+       }
+
+       if (rnet->tx_cnt < RIONET_TX_RING_SIZE)
+               netif_wake_queue(ndev);
+
+       spin_unlock(&rnet->lock);
+}
+
+static int rionet_open(struct net_device *ndev)
+{
+       int i, rc = 0;
+       struct rionet_peer *peer, *tmp;
+       u32 pwdcsr;
+       struct rionet_private *rnet = ndev->priv;
+
+       if (netif_msg_ifup(rnet))
+               printk(KERN_INFO "%s: open\n", DRV_NAME);
+
+       if ((rc = rio_request_inb_dbell(rnet->mport,
+                                       (void *)ndev,
+                                       RIONET_DOORBELL_JOIN,
+                                       RIONET_DOORBELL_LEAVE,
+                                       rionet_dbell_event)) < 0)
+               goto out;
+
+       if ((rc = rio_request_inb_mbox(rnet->mport,
+                                      (void *)ndev,
+                                      RIONET_MAILBOX,
+                                      RIONET_RX_RING_SIZE,
+                                      rionet_inb_msg_event)) < 0)
+               goto out;
+
+       if ((rc = rio_request_outb_mbox(rnet->mport,
+                                       (void *)ndev,
+                                       RIONET_MAILBOX,
+                                       RIONET_TX_RING_SIZE,
+                                       rionet_outb_msg_event)) < 0)
+               goto out;
+
+       /* Initialize inbound message ring */
+       for (i = 0; i < RIONET_RX_RING_SIZE; i++)
+               rnet->rx_skb[i] = NULL;
+       rnet->rx_slot = 0;
+       rionet_rx_fill(ndev, 0);
+
+       rnet->tx_slot = 0;
+       rnet->tx_cnt = 0;
+       rnet->ack_slot = 0;
+
+       netif_carrier_on(ndev);
+       netif_start_queue(ndev);
+
+       list_for_each_entry_safe(peer, tmp, &rionet_peers, node) {
+               if (!(peer->res = rio_request_outb_dbell(peer->rdev,
+                                                        RIONET_DOORBELL_JOIN,
+                                                        RIONET_DOORBELL_LEAVE)))
+               {
+                       printk(KERN_ERR "%s: error requesting doorbells\n",
+                              DRV_NAME);
+                       continue;
+               }
+
+               /*
+                * If device has initialized inbound doorbells,
+                * send a join message
+                */
+               rio_read_config_32(peer->rdev, RIO_WRITE_PORT_CSR, &pwdcsr);
+               if (pwdcsr & RIO_DOORBELL_AVAIL)
+                       rio_send_doorbell(peer->rdev, RIONET_DOORBELL_JOIN);
+       }
+
+      out:
+       return rc;
+}
+
+static int rionet_close(struct net_device *ndev)
+{
+       struct rionet_private *rnet = (struct rionet_private *)ndev->priv;
+       struct rionet_peer *peer, *tmp;
+       int i;
+
+       if (netif_msg_ifup(rnet))
+               printk(KERN_INFO "%s: close\n", DRV_NAME);
+
+       netif_stop_queue(ndev);
+       netif_carrier_off(ndev);
+
+       for (i = 0; i < RIONET_RX_RING_SIZE; i++)
+               if (rnet->rx_skb[i])
+                       kfree_skb(rnet->rx_skb[i]);
+
+       list_for_each_entry_safe(peer, tmp, &rionet_peers, node) {
+               if (rionet_active[peer->rdev->destid]) {
+                       rio_send_doorbell(peer->rdev, RIONET_DOORBELL_LEAVE);
+                       rionet_active[peer->rdev->destid] = NULL;
+               }
+               rio_release_outb_dbell(peer->rdev, peer->res);
+       }
+
+       rio_release_inb_dbell(rnet->mport, RIONET_DOORBELL_JOIN,
+                             RIONET_DOORBELL_LEAVE);
+       rio_release_inb_mbox(rnet->mport, RIONET_MAILBOX);
+       rio_release_outb_mbox(rnet->mport, RIONET_MAILBOX);
+
+       return 0;
+}
+
+static void rionet_remove(struct rio_dev *rdev)
+{
+       struct net_device *ndev = NULL;
+       struct rionet_peer *peer, *tmp;
+
+       unregister_netdev(ndev);
+       kfree(ndev);
+
+       list_for_each_entry_safe(peer, tmp, &rionet_peers, node) {
+               list_del(&peer->node);
+               kfree(peer);
+       }
+}
+
+static void rionet_get_drvinfo(struct net_device *ndev,
+                              struct ethtool_drvinfo *info)
+{
+       struct rionet_private *rnet = ndev->priv;
+
+       strcpy(info->driver, DRV_NAME);
+       strcpy(info->version, DRV_VERSION);
+       strcpy(info->fw_version, "n/a");
+       strcpy(info->bus_info, rnet->mport->name);
+}
+
+static u32 rionet_get_msglevel(struct net_device *ndev)
+{
+       struct rionet_private *rnet = ndev->priv;
+
+       return rnet->msg_enable;
+}
+
+static void rionet_set_msglevel(struct net_device *ndev, u32 value)
+{
+       struct rionet_private *rnet = ndev->priv;
+
+       rnet->msg_enable = value;
+}
+
+static struct ethtool_ops rionet_ethtool_ops = {
+       .get_drvinfo = rionet_get_drvinfo,
+       .get_msglevel = rionet_get_msglevel,
+       .set_msglevel = rionet_set_msglevel,
+       .get_link = ethtool_op_get_link,
+};
+
+static int rionet_setup_netdev(struct rio_mport *mport)
+{
+       int rc = 0;
+       struct net_device *ndev = NULL;
+       struct rionet_private *rnet;
+       u16 device_id;
+
+       /* Allocate our net_device structure */
+       ndev = alloc_etherdev(sizeof(struct rionet_private));
+       if (ndev == NULL) {
+               printk(KERN_INFO "%s: could not allocate ethernet device.\n",
+                      DRV_NAME);
+               rc = -ENOMEM;
+               goto out;
+       }
+
+       /* Set up private area */
+       rnet = (struct rionet_private *)ndev->priv;
+       rnet->mport = mport;
+
+       /* Set the default MAC address */
+       device_id = rio_local_get_device_id(mport);
+       ndev->dev_addr[0] = 0x00;
+       ndev->dev_addr[1] = 0x01;
+       ndev->dev_addr[2] = 0x00;
+       ndev->dev_addr[3] = 0x01;
+       ndev->dev_addr[4] = device_id >> 8;
+       ndev->dev_addr[5] = device_id & 0xff;
+
+       /* Fill in the driver function table */
+       ndev->open = &rionet_open;
+       ndev->hard_start_xmit = &rionet_start_xmit;
+       ndev->stop = &rionet_close;
+       ndev->get_stats = &rionet_stats;
+       ndev->mtu = RIO_MAX_MSG_SIZE - 14;
+       ndev->features = NETIF_F_LLTX;
+       SET_ETHTOOL_OPS(ndev, &rionet_ethtool_ops);
+
+       SET_MODULE_OWNER(ndev);
+
+       spin_lock_init(&rnet->lock);
+       spin_lock_init(&rnet->tx_lock);
+
+       rnet->msg_enable = RIONET_DEFAULT_MSGLEVEL;
+
+       rc = register_netdev(ndev);
+       if (rc != 0)
+               goto out;
+
+       printk("%s: %s %s Version %s, MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
+              ndev->name,
+              DRV_NAME,
+              DRV_DESC,
+              DRV_VERSION,
+              ndev->dev_addr[0], ndev->dev_addr[1], ndev->dev_addr[2],
+              ndev->dev_addr[3], ndev->dev_addr[4], ndev->dev_addr[5]);
+
+      out:
+       return rc;
+}
+
+/*
+ * XXX Make multi-net safe
+ */
+static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id)
+{
+       int rc = -ENODEV;
+       u32 lpef, lsrc_ops, ldst_ops;
+       struct rionet_peer *peer;
+
+       /* If local device is not rionet capable, give up quickly */
+       if (!rionet_capable)
+               goto out;
+
+       /*
+        * First time through, make sure local device is rionet
+        * capable, setup netdev,  and set flags so this is skipped
+        * on later probes
+        */
+       if (!rionet_check) {
+               rio_local_read_config_32(rdev->net->hport, RIO_PEF_CAR, &lpef);
+               rio_local_read_config_32(rdev->net->hport, RIO_SRC_OPS_CAR,
+                                        &lsrc_ops);
+               rio_local_read_config_32(rdev->net->hport, RIO_DST_OPS_CAR,
+                                        &ldst_ops);
+               if (!is_rionet_capable(lpef, lsrc_ops, ldst_ops)) {
+                       printk(KERN_ERR
+                              "%s: local device is not network capable\n",
+                              DRV_NAME);
+                       rionet_check = 1;
+                       rionet_capable = 0;
+                       goto out;
+               }
+
+               rc = rionet_setup_netdev(rdev->net->hport);
+               rionet_check = 1;
+       }
+
+       /*
+        * If the remote device has mailbox/doorbell capabilities,
+        * add it to the peer list.
+        */
+       if (dev_rionet_capable(rdev)) {
+               if (!(peer = kmalloc(sizeof(struct rionet_peer), GFP_KERNEL))) {
+                       rc = -ENOMEM;
+                       goto out;
+               }
+               peer->rdev = rdev;
+               list_add_tail(&peer->node, &rionet_peers);
+       }
+
+      out:
+       return rc;
+}
+
+static struct rio_device_id rionet_id_table[] = {
+       {RIO_DEVICE(RIO_ANY_ID, RIO_ANY_ID)}
+};
+
+static struct rio_driver rionet_driver = {
+       .name = "rionet",
+       .id_table = rionet_id_table,
+       .probe = rionet_probe,
+       .remove = rionet_remove,
+};
+
+static int __init rionet_init(void)
+{
+       return rio_register_driver(&rionet_driver);
+}
+
+static void __exit rionet_exit(void)
+{
+       rio_unregister_driver(&rionet_driver);
+}
+
+module_init(rionet_init);
+module_exit(rionet_exit);
index c2e6484..572f121 100644 (file)
@@ -730,6 +730,7 @@ static struct ethtool_ops skge_ethtool_ops = {
        .phys_id        = skge_phys_id,
        .get_stats_count = skge_get_stats_count,
        .get_ethtool_stats = skge_get_ethtool_stats,
+       .get_perm_addr  = ethtool_op_get_perm_addr,
 };
 
 /*
@@ -3096,6 +3097,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
 
        /* read the mac address */
        memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port*8, ETH_ALEN);
+       memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
        /* device is off until link detection */
        netif_carrier_off(dev);
index d500a57..e148a72 100644 (file)
@@ -549,6 +549,7 @@ static int __devinit sundance_probe1 (struct pci_dev *pdev,
        for (i = 0; i < 3; i++)
                ((u16 *)dev->dev_addr)[i] =
                        le16_to_cpu(eeprom_read(ioaddr, i + EEPROM_SA_OFFSET));
+       memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
        dev->base_addr = (unsigned long)ioaddr;
        dev->irq = irq;
@@ -1619,6 +1620,7 @@ static struct ethtool_ops ethtool_ops = {
        .get_link = get_link,
        .get_msglevel = get_msglevel,
        .set_msglevel = set_msglevel,
+       .get_perm_addr = ethtool_op_get_perm_addr,
 };
 
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
index e7b0010..8154bbb 100644 (file)
@@ -318,7 +318,7 @@ static void ibmtr_cleanup_card(struct net_device *dev)
        if (dev->base_addr) {
                outb(0,dev->base_addr+ADAPTRESET);
                
-               schedule_timeout(TR_RST_TIME); /* wait 50ms */
+               schedule_timeout_uninterruptible(TR_RST_TIME); /* wait 50ms */
 
                outb(0,dev->base_addr+ADAPTRESETREL);
        }
@@ -859,8 +859,7 @@ static int tok_init_card(struct net_device *dev)
        writeb(~INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
        outb(0, PIOaddr + ADAPTRESET);
 
-       current->state=TASK_UNINTERRUPTIBLE;
-       schedule_timeout(TR_RST_TIME); /* wait 50ms */
+       schedule_timeout_uninterruptible(TR_RST_TIME); /* wait 50ms */
 
        outb(0, PIOaddr + ADAPTRESETREL);
 #ifdef ENABLE_PAGING
@@ -908,8 +907,8 @@ static int tok_open(struct net_device *dev)
                        DPRINTK("Adapter is up and running\n");
                        return 0;
                }
-               current->state=TASK_INTERRUPTIBLE;
-               i=schedule_timeout(TR_RETRY_INTERVAL); /* wait 30 seconds */
+               i=schedule_timeout_interruptible(TR_RETRY_INTERVAL);
+                                                       /* wait 30 seconds */
                if(i!=0) break; /*prob. a signal, like the i>24*HZ case above */
        }
        outb(0, dev->base_addr + ADAPTRESET);/* kill pending interrupts*/
index 9e79231..05477d2 100644 (file)
@@ -1101,7 +1101,7 @@ static int olympic_close(struct net_device *dev)
 
        while(olympic_priv->srb_queued) {
 
-               t = schedule_timeout(60*HZ); 
+               t = schedule_timeout_interruptible(60*HZ);
 
                if(signal_pending(current))     {            
                        printk(KERN_WARNING "%s: SRB timed out.\n",dev->name);
index 2e39bf1..c192559 100644 (file)
@@ -1243,8 +1243,7 @@ void tms380tr_wait(unsigned long time)
        
        tmp = jiffies + time/(1000000/HZ);
        do {
-               current->state          = TASK_INTERRUPTIBLE;
-               tmp = schedule_timeout(tmp);
+               tmp = schedule_timeout_interruptible(tmp);
        } while(time_after(tmp, jiffies));
 #else
        udelay(time);
index ecfa6f8..4c76cb7 100644 (file)
@@ -419,10 +419,9 @@ typhoon_reset(void __iomem *ioaddr, int wait_type)
                           TYPHOON_STATUS_WAITING_FOR_HOST)
                                goto out;
 
-                       if(wait_type == WaitSleep) {
-                               set_current_state(TASK_UNINTERRUPTIBLE);
-                               schedule_timeout(1);
-                       } else
+                       if(wait_type == WaitSleep)
+                               schedule_timeout_uninterruptible(1);
+                       else
                                udelay(TYPHOON_UDELAY);
                }
 
index fc7738f..e7b4bc3 100644 (file)
@@ -814,8 +814,9 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
 
        for (i = 0; i < 6; i++)
                dev->dev_addr[i] = ioread8(ioaddr + StationAddr + i);
+       memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
-       if (!is_valid_ether_addr(dev->dev_addr)) {
+       if (!is_valid_ether_addr(dev->perm_addr)) {
                rc = -EIO;
                printk(KERN_ERR "Invalid MAC address\n");
                goto err_out_unmap;
@@ -1829,6 +1830,7 @@ static struct ethtool_ops netdev_ethtool_ops = {
        .set_wol                = rhine_set_wol,
        .get_sg                 = ethtool_op_get_sg,
        .get_tx_csum            = ethtool_op_get_tx_csum,
+       .get_perm_addr          = ethtool_op_get_perm_addr,
 };
 
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
index 7ff814f..ae9e897 100644 (file)
@@ -1617,8 +1617,7 @@ static int get_wait_data(struct cosa_data *cosa)
                        return r;
                }
                /* sleep if not ready to read */
-               set_current_state(TASK_INTERRUPTIBLE);
-               schedule_timeout(1);
+               schedule_timeout_interruptible(1);
        }
        printk(KERN_INFO "cosa: timeout in get_wait_data (status 0x%x)\n",
                cosa_getstatus(cosa));
@@ -1644,8 +1643,7 @@ static int put_wait_data(struct cosa_data *cosa, int data)
                }
 #if 0
                /* sleep if not ready to read */
-               current->state = TASK_INTERRUPTIBLE;
-               schedule_timeout(1);
+               schedule_timeout_interruptible(1);
 #endif
        }
        printk(KERN_INFO "cosa%d: timeout in put_wait_data (status 0x%x)\n",
index 9e56fc3..e6d0057 100644 (file)
@@ -109,7 +109,7 @@ static long cycx_2x_irq_options[]  = { 7, 3, 5, 9, 10, 11, 12, 15 };
  *             < 0     error.
  * Context:    process */
 
-int __init cycx_drv_init(void)
+static int __init cycx_drv_init(void)
 {
        printk(KERN_INFO "%s v%u.%u %s\n", fullname, MOD_VERSION, MOD_RELEASE,
                         copyright);
@@ -119,7 +119,7 @@ int __init cycx_drv_init(void)
 
 /* Module 'remove' entry point.
  * o release all remaining system resources */
-void cycx_drv_cleanup(void)
+static void cycx_drv_cleanup(void)
 {
 }
 
@@ -184,8 +184,7 @@ int cycx_down(struct cycx_hw *hw)
 }
 
 /* Enable interrupt generation.  */
-EXPORT_SYMBOL(cycx_inten);
-void cycx_inten(struct cycx_hw *hw)
+static void cycx_inten(struct cycx_hw *hw)
 {
        writeb(0, hw->dpmbase);
 }
index 7b48064..430b1f6 100644 (file)
@@ -103,7 +103,7 @@ static struct cycx_device *cycx_card_array; /* adapter data space */
  *             < 0     error.
  * Context:    process
  */
-int __init cycx_init(void)
+static int __init cycx_init(void)
 {
        int cnt, err = -ENOMEM;
 
index 02d57c0..a631d1c 100644 (file)
@@ -78,6 +78,7 @@
 
 #define CYCLOMX_X25_DEBUG 1
 
+#include <linux/ctype.h>       /* isdigit() */
 #include <linux/errno.h>       /* return codes */
 #include <linux/if_arp.h>       /* ARPHRD_HWX25 */
 #include <linux/kernel.h>      /* printk(), and other useful stuff */
@@ -418,7 +419,7 @@ static int cycx_wan_new_if(struct wan_device *wandev, struct net_device *dev,
 
                /* Set channel timeouts (default if not specified) */
                chan->idle_tmout = conf->idle_timeout ? conf->idle_timeout : 90;
-       } else if (is_digit(conf->addr[0])) {   /* PVC */
+       } else if (isdigit(conf->addr[0])) {    /* PVC */
                s16 lcn = dec_to_uint(conf->addr, 0);
 
                if (lcn >= card->u.x.lo_pvc && lcn <= card->u.x.hi_pvc)
@@ -1531,7 +1532,7 @@ static unsigned dec_to_uint(u8 *str, int len)
        if (!len)
                len = strlen(str);
 
-       for (; len && is_digit(*str); ++str, --len)
+       for (; len && isdigit(*str); ++str, --len)
                val = (val * 10) + (*str - (unsigned) '0');
 
        return val;
index 520a77a..2f61a47 100644 (file)
@@ -446,8 +446,8 @@ static inline unsigned int dscc4_tx_quiescent(struct dscc4_dev_priv *dpriv,
        return readl(dpriv->base_addr + CH0FTDA + dpriv->dev_id*4) == dpriv->ltda;
 }
 
-int state_check(u32 state, struct dscc4_dev_priv *dpriv, struct net_device *dev,
-               const char *msg)
+static int state_check(u32 state, struct dscc4_dev_priv *dpriv,
+                      struct net_device *dev, const char *msg)
 {
        int ret = 0;
 
@@ -466,8 +466,9 @@ int state_check(u32 state, struct dscc4_dev_priv *dpriv, struct net_device *dev,
        return ret;
 }
 
-void dscc4_tx_print(struct net_device *dev, struct dscc4_dev_priv *dpriv,
-                   char *msg)
+static void dscc4_tx_print(struct net_device *dev,
+                          struct dscc4_dev_priv *dpriv,
+                          char *msg)
 {
        printk(KERN_DEBUG "%s: tx_current=%02d tx_dirty=%02d (%s)\n",
               dev->name, dpriv->tx_current, dpriv->tx_dirty, msg);
@@ -507,7 +508,8 @@ static void dscc4_release_ring(struct dscc4_dev_priv *dpriv)
        }
 }
 
-inline int try_get_rx_skb(struct dscc4_dev_priv *dpriv, struct net_device *dev)
+static inline int try_get_rx_skb(struct dscc4_dev_priv *dpriv,
+                                struct net_device *dev)
 {
        unsigned int dirty = dpriv->rx_dirty%RX_RING_SIZE;
        struct RxFD *rx_fd = dpriv->rx_fd + dirty;
@@ -542,8 +544,7 @@ static int dscc4_wait_ack_cec(struct dscc4_dev_priv *dpriv,
                               msg, i);
                        goto done;
                }
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(10);
+               schedule_timeout_uninterruptible(10);
                rmb();
        } while (++i > 0);
        printk(KERN_ERR "%s: %s timeout\n", dev->name, msg);
@@ -588,8 +589,7 @@ static inline int dscc4_xpr_ack(struct dscc4_dev_priv *dpriv)
                    (dpriv->iqtx[cur] & Xpr))
                        break;
                smp_rmb();
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(10);
+               schedule_timeout_uninterruptible(10);
        } while (++i > 0);
 
        return (i >= 0 ) ? i : -EAGAIN;
@@ -1035,8 +1035,7 @@ static void dscc4_pci_reset(struct pci_dev *pdev, void __iomem *ioaddr)
        /* Flush posted writes */
        readl(ioaddr + GSTAR);
 
-       set_current_state(TASK_UNINTERRUPTIBLE);
-       schedule_timeout(10);
+       schedule_timeout_uninterruptible(10);
 
        for (i = 0; i < 16; i++)
                pci_write_config_dword(pdev, i << 2, dscc4_pci_config_store[i]);
@@ -1894,7 +1893,7 @@ try:
  * It failed and locked solid. Thus the introduction of a dummy skb.
  * Problem is acknowledged in errata sheet DS5. Joy :o/
  */
-struct sk_buff *dscc4_init_dummy_skb(struct dscc4_dev_priv *dpriv)
+static struct sk_buff *dscc4_init_dummy_skb(struct dscc4_dev_priv *dpriv)
 {
        struct sk_buff *skb;
 
index 2c83cca..7981a2c 100644 (file)
@@ -74,11 +74,11 @@ MODULE_LICENSE("GPL");
 /*
  * Modules parameters and associated varaibles
  */
-int fst_txq_low = FST_LOW_WATER_MARK;
-int fst_txq_high = FST_HIGH_WATER_MARK;
-int fst_max_reads = 7;
-int fst_excluded_cards = 0;
-int fst_excluded_list[FST_MAX_CARDS];
+static int fst_txq_low = FST_LOW_WATER_MARK;
+static int fst_txq_high = FST_HIGH_WATER_MARK;
+static int fst_max_reads = 7;
+static int fst_excluded_cards = 0;
+static int fst_excluded_list[FST_MAX_CARDS];
 
 module_param(fst_txq_low, int, 0);
 module_param(fst_txq_high, int, 0);
@@ -572,13 +572,13 @@ static void do_bottom_half_rx(struct fst_card_info *card);
 static void fst_process_tx_work_q(unsigned long work_q);
 static void fst_process_int_work_q(unsigned long work_q);
 
-DECLARE_TASKLET(fst_tx_task, fst_process_tx_work_q, 0);
-DECLARE_TASKLET(fst_int_task, fst_process_int_work_q, 0);
+static DECLARE_TASKLET(fst_tx_task, fst_process_tx_work_q, 0);
+static DECLARE_TASKLET(fst_int_task, fst_process_int_work_q, 0);
 
-struct fst_card_info *fst_card_array[FST_MAX_CARDS];
-spinlock_t fst_work_q_lock;
-u64 fst_work_txq;
-u64 fst_work_intq;
+static struct fst_card_info *fst_card_array[FST_MAX_CARDS];
+static spinlock_t fst_work_q_lock;
+static u64 fst_work_txq;
+static u64 fst_work_intq;
 
 static void
 fst_q_work_item(u64 * queue, int card_index)
@@ -980,8 +980,7 @@ fst_issue_cmd(struct fst_port_info *port, unsigned short cmd)
        /* Wait for any previous command to complete */
        while (mbval > NAK) {
                spin_unlock_irqrestore(&card->card_lock, flags);
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(1);
+               schedule_timeout_uninterruptible(1);
                spin_lock_irqsave(&card->card_lock, flags);
 
                if (++safety > 2000) {
@@ -1498,7 +1497,7 @@ do_bottom_half_rx(struct fst_card_info *card)
  *      The interrupt service routine
  *      Dev_id is our fst_card_info pointer
  */
-irqreturn_t
+static irqreturn_t
 fst_intr(int irq, void *dev_id, struct pt_regs *regs)
 {
        struct fst_card_info *card;
index a5d6891..e1601d3 100644 (file)
@@ -330,7 +330,7 @@ static int pvc_close(struct net_device *dev)
 
 
 
-int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+static int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
        pvc_device *pvc = dev_to_pvc(dev);
        fr_proto_pvc_info info;
index 9dccd95..3b94352 100644 (file)
@@ -8,10 +8,10 @@
 /*
  * Prints out len, max to 80 octets using printk, 20 per line
  */
-void lmcConsoleLog(char *type, unsigned char *ucData, int iLen)
-{
 #ifdef DEBUG
 #ifdef LMC_PACKET_LOG
+void lmcConsoleLog(char *type, unsigned char *ucData, int iLen)
+{
   int iNewLine = 1;
   char str[80], *pstr;
   
@@ -43,26 +43,24 @@ void lmcConsoleLog(char *type, unsigned char *ucData, int iLen)
     }
   sprintf(pstr, "\n");
   printk(str);
+}
 #endif
 #endif
-}
 
 #ifdef DEBUG
 u_int32_t lmcEventLogIndex = 0;
 u_int32_t lmcEventLogBuf[LMC_EVENTLOGSIZE * LMC_EVENTLOGARGS];
-#endif
 
 void lmcEventLog (u_int32_t EventNum, u_int32_t arg2, u_int32_t arg3)
 {
-#ifdef DEBUG
   lmcEventLogBuf[lmcEventLogIndex++] = EventNum;
   lmcEventLogBuf[lmcEventLogIndex++] = arg2;
   lmcEventLogBuf[lmcEventLogIndex++] = arg3;
   lmcEventLogBuf[lmcEventLogIndex++] = jiffies;
 
   lmcEventLogIndex &= (LMC_EVENTLOGSIZE * LMC_EVENTLOGARGS) - 1;
-#endif
 }
+#endif  /*  DEBUG  */
 
 void lmc_trace(struct net_device *dev, char *msg){
 #ifdef LMC_TRACE
index f55ce76..af8b55f 100644 (file)
   */
 
 /*
- * For lack of a better place, put the SSI cable stuff here.
- */
-char *lmc_t1_cables[] = {
-  "V.10/RS423", "EIA530A", "reserved", "X.21", "V.35",
-  "EIA449/EIA530/V.36", "V.28/EIA232", "none", NULL
-};
-
-/*
  * protocol independent method.
  */
 static void lmc_set_protocol (lmc_softc_t * const, lmc_ctl_t *);
index 73401b0..2024b26 100644 (file)
@@ -472,24 +472,8 @@ enum pc300_loopback_cmds {
 
 #ifdef __KERNEL__
 /* Function Prototypes */
-int dma_buf_write(pc300_t *, int, ucchar *, int);
-int dma_buf_read(pc300_t *, int, struct sk_buff *);
 void tx_dma_start(pc300_t *, int);
-void rx_dma_start(pc300_t *, int);
-void tx_dma_stop(pc300_t *, int);
-void rx_dma_stop(pc300_t *, int);
-int cpc_queue_xmit(struct sk_buff *, struct net_device *);
-void cpc_net_rx(struct net_device *);
-void cpc_sca_status(pc300_t *, int);
-int cpc_change_mtu(struct net_device *, int);
-int cpc_ioctl(struct net_device *, struct ifreq *, int);
-int ch_config(pc300dev_t *);
-int rx_config(pc300dev_t *);
-int tx_config(pc300dev_t *);
-void cpc_opench(pc300dev_t *);
-void cpc_closech(pc300dev_t *);
 int cpc_open(struct net_device *dev);
-int cpc_close(struct net_device *dev);
 int cpc_set_media(hdlc_device *, int);
 #endif /* __KERNEL__ */
 
index 3e7753b..a3e65d1 100644 (file)
@@ -291,6 +291,7 @@ static uclong detect_ram(pc300_t *);
 static void plx_init(pc300_t *);
 static void cpc_trace(struct net_device *, struct sk_buff *, char);
 static int cpc_attach(struct net_device *, unsigned short, unsigned short);
+static int cpc_close(struct net_device *dev);
 
 #ifdef CONFIG_PC300_MLPPP
 void cpc_tty_init(pc300dev_t * dev);
@@ -437,7 +438,7 @@ static void rx_dma_buf_check(pc300_t * card, int ch)
        printk("\n");
 }
 
-int dma_get_rx_frame_size(pc300_t * card, int ch)
+static int dma_get_rx_frame_size(pc300_t * card, int ch)
 {
        volatile pcsca_bd_t __iomem *ptdescr;
        ucshort first_bd = card->chan[ch].rx_first_bd;
@@ -462,7 +463,7 @@ int dma_get_rx_frame_size(pc300_t * card, int ch)
  * dma_buf_write: writes a frame to the Tx DMA buffers
  * NOTE: this function writes one frame at a time.
  */
-int dma_buf_write(pc300_t * card, int ch, ucchar * ptdata, int len)
+static int dma_buf_write(pc300_t * card, int ch, ucchar * ptdata, int len)
 {
        int i, nchar;
        volatile pcsca_bd_t __iomem *ptdescr;
@@ -503,7 +504,7 @@ int dma_buf_write(pc300_t * card, int ch, ucchar * ptdata, int len)
  * dma_buf_read: reads a frame from the Rx DMA buffers
  * NOTE: this function reads one frame at a time.
  */
-int dma_buf_read(pc300_t * card, int ch, struct sk_buff *skb)
+static int dma_buf_read(pc300_t * card, int ch, struct sk_buff *skb)
 {
        int nchar;
        pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
@@ -560,7 +561,7 @@ int dma_buf_read(pc300_t * card, int ch, struct sk_buff *skb)
        return (rcvd);
 }
 
-void tx_dma_stop(pc300_t * card, int ch)
+static void tx_dma_stop(pc300_t * card, int ch)
 {
        void __iomem *scabase = card->hw.scabase;
        ucchar drr_ena_bit = 1 << (5 + 2 * ch);
@@ -571,7 +572,7 @@ void tx_dma_stop(pc300_t * card, int ch)
        cpc_writeb(scabase + DRR, drr_rst_bit & ~drr_ena_bit);
 }
 
-void rx_dma_stop(pc300_t * card, int ch)
+static void rx_dma_stop(pc300_t * card, int ch)
 {
        void __iomem *scabase = card->hw.scabase;
        ucchar drr_ena_bit = 1 << (4 + 2 * ch);
@@ -582,7 +583,7 @@ void rx_dma_stop(pc300_t * card, int ch)
        cpc_writeb(scabase + DRR, drr_rst_bit & ~drr_ena_bit);
 }
 
-void rx_dma_start(pc300_t * card, int ch)
+static void rx_dma_start(pc300_t * card, int ch)
 {
        void __iomem *scabase = card->hw.scabase;
        pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
@@ -607,7 +608,7 @@ void rx_dma_start(pc300_t * card, int ch)
 /*************************/
 /***   FALC Routines   ***/
 /*************************/
-void falc_issue_cmd(pc300_t * card, int ch, ucchar cmd)
+static void falc_issue_cmd(pc300_t * card, int ch, ucchar cmd)
 {
        void __iomem *falcbase = card->hw.falcbase;
        unsigned long i = 0;
@@ -622,7 +623,7 @@ void falc_issue_cmd(pc300_t * card, int ch, ucchar cmd)
        cpc_writeb(falcbase + F_REG(CMDR, ch), cmd);
 }
 
-void falc_intr_enable(pc300_t * card, int ch)
+static void falc_intr_enable(pc300_t * card, int ch)
 {
        pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
        pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -672,7 +673,7 @@ void falc_intr_enable(pc300_t * card, int ch)
        }
 }
 
-void falc_open_timeslot(pc300_t * card, int ch, int timeslot)
+static void falc_open_timeslot(pc300_t * card, int ch, int timeslot)
 {
        void __iomem *falcbase = card->hw.falcbase;
        ucchar tshf = card->chan[ch].falc.offset;
@@ -688,7 +689,7 @@ void falc_open_timeslot(pc300_t * card, int ch, int timeslot)
                        (0x80 >> (timeslot & 0x07)));
 }
 
-void falc_close_timeslot(pc300_t * card, int ch, int timeslot)
+static void falc_close_timeslot(pc300_t * card, int ch, int timeslot)
 {
        void __iomem *falcbase = card->hw.falcbase;
        ucchar tshf = card->chan[ch].falc.offset;
@@ -704,7 +705,7 @@ void falc_close_timeslot(pc300_t * card, int ch, int timeslot)
                   ~(0x80 >> (timeslot & 0x07)));
 }
 
-void falc_close_all_timeslots(pc300_t * card, int ch)
+static void falc_close_all_timeslots(pc300_t * card, int ch)
 {
        pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
        pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -726,7 +727,7 @@ void falc_close_all_timeslots(pc300_t * card, int ch)
        }
 }
 
-void falc_open_all_timeslots(pc300_t * card, int ch)
+static void falc_open_all_timeslots(pc300_t * card, int ch)
 {
        pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
        pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -758,7 +759,7 @@ void falc_open_all_timeslots(pc300_t * card, int ch)
        }
 }
 
-void falc_init_timeslot(pc300_t * card, int ch)
+static void falc_init_timeslot(pc300_t * card, int ch)
 {
        pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
        pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -776,7 +777,7 @@ void falc_init_timeslot(pc300_t * card, int ch)
        }
 }
 
-void falc_enable_comm(pc300_t * card, int ch)
+static void falc_enable_comm(pc300_t * card, int ch)
 {
        pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
        falc_t *pfalc = (falc_t *) & chan->falc;
@@ -792,7 +793,7 @@ void falc_enable_comm(pc300_t * card, int ch)
                   ~((CPLD_REG1_FALC_DCD | CPLD_REG1_FALC_CTS) << (2 * ch)));
 }
 
-void falc_disable_comm(pc300_t * card, int ch)
+static void falc_disable_comm(pc300_t * card, int ch)
 {
        pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
        falc_t *pfalc = (falc_t *) & chan->falc;
@@ -806,7 +807,7 @@ void falc_disable_comm(pc300_t * card, int ch)
                   ((CPLD_REG1_FALC_DCD | CPLD_REG1_FALC_CTS) << (2 * ch)));
 }
 
-void falc_init_t1(pc300_t * card, int ch)
+static void falc_init_t1(pc300_t * card, int ch)
 {
        pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
        pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -975,7 +976,7 @@ void falc_init_t1(pc300_t * card, int ch)
        falc_close_all_timeslots(card, ch);
 }
 
-void falc_init_e1(pc300_t * card, int ch)
+static void falc_init_e1(pc300_t * card, int ch)
 {
        pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
        pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1155,7 +1156,7 @@ void falc_init_e1(pc300_t * card, int ch)
        falc_close_all_timeslots(card, ch);
 }
 
-void falc_init_hdlc(pc300_t * card, int ch)
+static void falc_init_hdlc(pc300_t * card, int ch)
 {
        void __iomem *falcbase = card->hw.falcbase;
        pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
@@ -1181,7 +1182,7 @@ void falc_init_hdlc(pc300_t * card, int ch)
        falc_intr_enable(card, ch);
 }
 
-void te_config(pc300_t * card, int ch)
+static void te_config(pc300_t * card, int ch)
 {
        pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
        pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1241,7 +1242,7 @@ void te_config(pc300_t * card, int ch)
        CPC_UNLOCK(card, flags);
 }
 
-void falc_check_status(pc300_t * card, int ch, unsigned char frs0)
+static void falc_check_status(pc300_t * card, int ch, unsigned char frs0)
 {
        pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
        pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1397,7 +1398,7 @@ void falc_check_status(pc300_t * card, int ch, unsigned char frs0)
        }
 }
 
-void falc_update_stats(pc300_t * card, int ch)
+static void falc_update_stats(pc300_t * card, int ch)
 {
        pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
        pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1450,7 +1451,7 @@ void falc_update_stats(pc300_t * card, int ch)
  *             the synchronizer and then sent to the system interface.
  *----------------------------------------------------------------------------
  */
-void falc_remote_loop(pc300_t * card, int ch, int loop_on)
+static void falc_remote_loop(pc300_t * card, int ch, int loop_on)
 {
        pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
        pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1495,7 +1496,7 @@ void falc_remote_loop(pc300_t * card, int ch, int loop_on)
  *             coding must be identical.
  *----------------------------------------------------------------------------
  */
-void falc_local_loop(pc300_t * card, int ch, int loop_on)
+static void falc_local_loop(pc300_t * card, int ch, int loop_on)
 {
        pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
        falc_t *pfalc = (falc_t *) & chan->falc;
@@ -1522,7 +1523,7 @@ void falc_local_loop(pc300_t * card, int ch, int loop_on)
  *             looped. They are originated by the FALC-LH transmitter.
  *----------------------------------------------------------------------------
  */
-void falc_payload_loop(pc300_t * card, int ch, int loop_on)
+static void falc_payload_loop(pc300_t * card, int ch, int loop_on)
 {
        pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
        pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1576,7 +1577,7 @@ void falc_payload_loop(pc300_t * card, int ch, int loop_on)
  * Description:        Turns XLU bit off in the proper register
  *----------------------------------------------------------------------------
  */
-void turn_off_xlu(pc300_t * card, int ch)
+static void turn_off_xlu(pc300_t * card, int ch)
 {
        pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
        pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1597,7 +1598,7 @@ void turn_off_xlu(pc300_t * card, int ch)
  * Description: Turns XLD bit off in the proper register
  *----------------------------------------------------------------------------
  */
-void turn_off_xld(pc300_t * card, int ch)
+static void turn_off_xld(pc300_t * card, int ch)
 {
        pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
        pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1619,7 +1620,7 @@ void turn_off_xld(pc300_t * card, int ch)
  *             to generate a LOOP activation code over a T1/E1 line.
  *----------------------------------------------------------------------------
  */
-void falc_generate_loop_up_code(pc300_t * card, int ch)
+static void falc_generate_loop_up_code(pc300_t * card, int ch)
 {
        pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
        pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1652,7 +1653,7 @@ void falc_generate_loop_up_code(pc300_t * card, int ch)
  *             to generate a LOOP deactivation code over a T1/E1 line.
  *----------------------------------------------------------------------------
  */
-void falc_generate_loop_down_code(pc300_t * card, int ch)
+static void falc_generate_loop_down_code(pc300_t * card, int ch)
 {
        pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
        pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1682,7 +1683,7 @@ void falc_generate_loop_down_code(pc300_t * card, int ch)
  *             it on the reception side.
  *----------------------------------------------------------------------------
  */
-void falc_pattern_test(pc300_t * card, int ch, unsigned int activate)
+static void falc_pattern_test(pc300_t * card, int ch, unsigned int activate)
 {
        pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
        pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1729,7 +1730,7 @@ void falc_pattern_test(pc300_t * card, int ch, unsigned int activate)
  * Description:        This routine returns the bit error counter value
  *----------------------------------------------------------------------------
  */
-ucshort falc_pattern_test_error(pc300_t * card, int ch)
+static ucshort falc_pattern_test_error(pc300_t * card, int ch)
 {
        pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
        falc_t *pfalc = (falc_t *) & chan->falc;
@@ -1769,7 +1770,7 @@ cpc_trace(struct net_device *dev, struct sk_buff *skb_main, char rx_tx)
        netif_rx(skb);
 }
 
-void cpc_tx_timeout(struct net_device *dev)
+static void cpc_tx_timeout(struct net_device *dev)
 {
        pc300dev_t *d = (pc300dev_t *) dev->priv;
        pc300ch_t *chan = (pc300ch_t *) d->chan;
@@ -1797,7 +1798,7 @@ void cpc_tx_timeout(struct net_device *dev)
        netif_wake_queue(dev);
 }
 
-int cpc_queue_xmit(struct sk_buff *skb, struct net_device *dev)
+static int cpc_queue_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        pc300dev_t *d = (pc300dev_t *) dev->priv;
        pc300ch_t *chan = (pc300ch_t *) d->chan;
@@ -1880,7 +1881,7 @@ int cpc_queue_xmit(struct sk_buff *skb, struct net_device *dev)
        return 0;
 }
 
-void cpc_net_rx(struct net_device *dev)
+static void cpc_net_rx(struct net_device *dev)
 {
        pc300dev_t *d = (pc300dev_t *) dev->priv;
        pc300ch_t *chan = (pc300ch_t *) d->chan;
@@ -2403,7 +2404,7 @@ static irqreturn_t cpc_intr(int irq, void *dev_id, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-void cpc_sca_status(pc300_t * card, int ch)
+static void cpc_sca_status(pc300_t * card, int ch)
 {
        ucchar ilar;
        void __iomem *scabase = card->hw.scabase;
@@ -2495,7 +2496,7 @@ void cpc_sca_status(pc300_t * card, int ch)
        }
 }
 
-void cpc_falc_status(pc300_t * card, int ch)
+static void cpc_falc_status(pc300_t * card, int ch)
 {
        pc300ch_t *chan = &card->chan[ch];
        falc_t *pfalc = (falc_t *) & chan->falc;
@@ -2523,7 +2524,7 @@ void cpc_falc_status(pc300_t * card, int ch)
        CPC_UNLOCK(card, flags);
 }
 
-int cpc_change_mtu(struct net_device *dev, int new_mtu)
+static int cpc_change_mtu(struct net_device *dev, int new_mtu)
 {
        if ((new_mtu < 128) || (new_mtu > PC300_DEF_MTU))
                return -EINVAL;
@@ -2531,7 +2532,7 @@ int cpc_change_mtu(struct net_device *dev, int new_mtu)
        return 0;
 }
 
-int cpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+static int cpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
        hdlc_device *hdlc = dev_to_hdlc(dev);
        pc300dev_t *d = (pc300dev_t *) dev->priv;
@@ -2856,7 +2857,7 @@ static int clock_rate_calc(uclong rate, uclong clock, int *br_io)
        }
 }
 
-int ch_config(pc300dev_t * d)
+static int ch_config(pc300dev_t * d)
 {
        pc300ch_t *chan = (pc300ch_t *) d->chan;
        pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -3004,7 +3005,7 @@ int ch_config(pc300dev_t * d)
        return 0;
 }
 
-int rx_config(pc300dev_t * d)
+static int rx_config(pc300dev_t * d)
 {
        pc300ch_t *chan = (pc300ch_t *) d->chan;
        pc300_t *card = (pc300_t *) chan->card;
@@ -3035,7 +3036,7 @@ int rx_config(pc300dev_t * d)
        return 0;
 }
 
-int tx_config(pc300dev_t * d)
+static int tx_config(pc300dev_t * d)
 {
        pc300ch_t *chan = (pc300ch_t *) d->chan;
        pc300_t *card = (pc300_t *) chan->card;
@@ -3098,7 +3099,7 @@ static int cpc_attach(struct net_device *dev, unsigned short encoding,
        return 0;
 }
 
-void cpc_opench(pc300dev_t * d)
+static void cpc_opench(pc300dev_t * d)
 {
        pc300ch_t *chan = (pc300ch_t *) d->chan;
        pc300_t *card = (pc300_t *) chan->card;
@@ -3116,7 +3117,7 @@ void cpc_opench(pc300dev_t * d)
                   cpc_readb(scabase + M_REG(CTL, ch)) & ~(CTL_RTS | CTL_DTR));
 }
 
-void cpc_closech(pc300dev_t * d)
+static void cpc_closech(pc300dev_t * d)
 {
        pc300ch_t *chan = (pc300ch_t *) d->chan;
        pc300_t *card = (pc300_t *) chan->card;
@@ -3173,7 +3174,7 @@ int cpc_open(struct net_device *dev)
        return 0;
 }
 
-int cpc_close(struct net_device *dev)
+static int cpc_close(struct net_device *dev)
 {
        hdlc_device *hdlc = dev_to_hdlc(dev);
        pc300dev_t *d = (pc300dev_t *) dev->priv;
index 8454bf6..52f26b9 100644 (file)
@@ -112,10 +112,10 @@ typedef   struct _st_cpc_tty_area {
 static struct tty_driver serial_drv;
 
 /* local variables */
-st_cpc_tty_area        cpc_tty_area[CPC_TTY_NPORTS];
+static st_cpc_tty_area cpc_tty_area[CPC_TTY_NPORTS];
 
-int cpc_tty_cnt=0;     /* number of intrfaces configured with MLPPP */
-int cpc_tty_unreg_flag = 0;
+static int cpc_tty_cnt = 0;    /* number of intrfaces configured with MLPPP */
+static int cpc_tty_unreg_flag = 0;
 
 /* TTY functions prototype */
 static int cpc_tty_open(struct tty_struct *tty, struct file *flip);
@@ -132,9 +132,9 @@ static void cpc_tty_trace(pc300dev_t *dev, char* buf, int len, char rxtx);
 static void cpc_tty_signal_off(pc300dev_t *pc300dev, unsigned char);
 static void cpc_tty_signal_on(pc300dev_t *pc300dev, unsigned char);
 
-int pc300_tiocmset(struct tty_struct *, struct file *,
-                       unsigned int, unsigned int);
-int pc300_tiocmget(struct tty_struct *, struct file *);
+static int pc300_tiocmset(struct tty_struct *, struct file *,
+                         unsigned int, unsigned int);
+static int pc300_tiocmget(struct tty_struct *, struct file *);
 
 /* functions called by PC300 driver */
 void cpc_tty_init(pc300dev_t *dev);
@@ -538,8 +538,8 @@ static int cpc_tty_chars_in_buffer(struct tty_struct *tty)
        return(0); 
 } 
 
-int pc300_tiocmset(struct tty_struct *tty, struct file *file,
-                       unsigned int set, unsigned int clear)
+static int pc300_tiocmset(struct tty_struct *tty, struct file *file,
+                         unsigned int set, unsigned int clear)
 {
        st_cpc_tty_area    *cpc_tty; 
 
@@ -565,7 +565,7 @@ int pc300_tiocmset(struct tty_struct *tty, struct file *file,
        return 0;
 }
 
-int pc300_tiocmget(struct tty_struct *tty, struct file *file)
+static int pc300_tiocmget(struct tty_struct *tty, struct file *file)
 {
        unsigned int result;
        unsigned char status;
index 3ac9a45..036adc4 100644 (file)
@@ -182,7 +182,7 @@ static char sdla_byte(struct net_device *dev, int addr)
        return(byte);
 }
 
-void sdla_stop(struct net_device *dev)
+static void sdla_stop(struct net_device *dev)
 {
        struct frad_local *flp;
 
@@ -209,7 +209,7 @@ void sdla_stop(struct net_device *dev)
        }
 }
 
-void sdla_start(struct net_device *dev)
+static void sdla_start(struct net_device *dev)
 {
        struct frad_local *flp;
 
@@ -247,7 +247,7 @@ void sdla_start(struct net_device *dev)
  *
  ***************************************************/
 
-int sdla_z80_poll(struct net_device *dev, int z80_addr, int jiffs, char resp1, char resp2)
+static int sdla_z80_poll(struct net_device *dev, int z80_addr, int jiffs, char resp1, char resp2)
 {
        unsigned long start, done, now;
        char          resp, *temp;
@@ -505,7 +505,7 @@ static int sdla_cmd(struct net_device *dev, int cmd, short dlci, short flags,
 
 static int sdla_reconfig(struct net_device *dev);
 
-int sdla_activate(struct net_device *slave, struct net_device *master)
+static int sdla_activate(struct net_device *slave, struct net_device *master)
 {
        struct frad_local *flp;
        int i;
@@ -527,7 +527,7 @@ int sdla_activate(struct net_device *slave, struct net_device *master)
        return(0);
 }
 
-int sdla_deactivate(struct net_device *slave, struct net_device *master)
+static int sdla_deactivate(struct net_device *slave, struct net_device *master)
 {
        struct frad_local *flp;
        int               i;
@@ -549,7 +549,7 @@ int sdla_deactivate(struct net_device *slave, struct net_device *master)
        return(0);
 }
 
-int sdla_assoc(struct net_device *slave, struct net_device *master)
+static int sdla_assoc(struct net_device *slave, struct net_device *master)
 {
        struct frad_local *flp;
        int               i;
@@ -585,7 +585,7 @@ int sdla_assoc(struct net_device *slave, struct net_device *master)
        return(0);
 }
 
-int sdla_deassoc(struct net_device *slave, struct net_device *master)
+static int sdla_deassoc(struct net_device *slave, struct net_device *master)
 {
        struct frad_local *flp;
        int               i;
@@ -613,7 +613,7 @@ int sdla_deassoc(struct net_device *slave, struct net_device *master)
        return(0);
 }
 
-int sdla_dlci_conf(struct net_device *slave, struct net_device *master, int get)
+static int sdla_dlci_conf(struct net_device *slave, struct net_device *master, int get)
 {
        struct frad_local *flp;
        struct dlci_local *dlp;
@@ -1324,7 +1324,7 @@ NOTE:  This is rather a useless action right now, as the
        return(0);
 }
 
-int sdla_change_mtu(struct net_device *dev, int new_mtu)
+static int sdla_change_mtu(struct net_device *dev, int new_mtu)
 {
        struct frad_local *flp;
 
@@ -1337,7 +1337,7 @@ int sdla_change_mtu(struct net_device *dev, int new_mtu)
        return(-EOPNOTSUPP);
 }
 
-int sdla_set_config(struct net_device *dev, struct ifmap *map)
+static int sdla_set_config(struct net_device *dev, struct ifmap *map)
 {
        struct frad_local *flp;
        int               i;
index 0497dbd..7f1ce9d 100644 (file)
@@ -822,7 +822,7 @@ static int new_if(struct wan_device* wandev, struct net_device* dev,
        chan->card = card;
 
        /* verify media address */
-       if (is_digit(conf->addr[0])) {
+       if (isdigit(conf->addr[0])) {
 
                dlci = dec_to_uint(conf->addr, 0);
 
@@ -3456,7 +3456,7 @@ static unsigned int dec_to_uint (unsigned char* str, int len)
        if (!len) 
                len = strlen(str);
 
-       for (val = 0; len && is_digit(*str); ++str, --len)
+       for (val = 0; len && isdigit(*str); ++str, --len)
                val = (val * 10) + (*str - (unsigned)'0');
 
        return val;
index 8a95d61..63f846d 100644 (file)
@@ -957,7 +957,7 @@ static int new_if(struct wan_device* wandev, struct net_device* dev,
                chan->hold_timeout = (conf->hold_timeout) ? 
                                        conf->hold_timeout : 10;
 
-       }else if (is_digit(conf->addr[0])){     /* PVC */
+       }else if (isdigit(conf->addr[0])){      /* PVC */
                int lcn = dec_to_uint(conf->addr, 0);
 
                if ((lcn >= card->u.x.lo_pvc) && (lcn <= card->u.x.hi_pvc)){
@@ -3875,7 +3875,7 @@ static unsigned int dec_to_uint (unsigned char* str, int len)
        if (!len) 
                len = strlen(str);
 
-       for (val = 0; len && is_digit(*str); ++str, --len)
+       for (val = 0; len && isdigit(*str); ++str, --len)
                val = (val * 10) + (*str - (unsigned)'0');
        
        return val;
@@ -3896,9 +3896,9 @@ static unsigned int hex_to_uint (unsigned char* str, int len)
        for (val = 0; len; ++str, --len)
        {
                ch = *str;
-               if (is_digit(ch))
+               if (isdigit(ch))
                        val = (val << 4) + (ch - (unsigned)'0');
-               else if (is_hex_digit(ch))
+               else if (isxdigit(ch))
                        val = (val << 4) + ((ch & 0xDF) - (unsigned)'A' + 10);
                else break;
        }
index c8bc6da..7c2cf2e 100644 (file)
@@ -642,9 +642,7 @@ int sdla_mapmem (sdlahw_t* hw, unsigned long addr)
  * Enable interrupt generation.
  */
 
-EXPORT_SYMBOL(sdla_inten);
-
-int sdla_inten (sdlahw_t* hw)
+static int sdla_inten (sdlahw_t* hw)
 {
        unsigned port = hw->port;
        int tmp, i;
@@ -698,8 +696,7 @@ int sdla_inten (sdlahw_t* hw)
  * Disable interrupt generation.
  */
 
-EXPORT_SYMBOL(sdla_intde);
-
+#if 0
 int sdla_intde (sdlahw_t* hw)
 {
        unsigned port = hw->port;
@@ -748,14 +745,13 @@ int sdla_intde (sdlahw_t* hw)
        }
        return 0;
 }
+#endif  /*  0  */
 
 /*============================================================================
  * Acknowledge SDLA hardware interrupt.
  */
 
-EXPORT_SYMBOL(sdla_intack);
-
-int sdla_intack (sdlahw_t* hw)
+static int sdla_intack (sdlahw_t* hw)
 {
        unsigned port = hw->port;
        int tmp;
@@ -827,8 +823,7 @@ void read_S514_int_stat (sdlahw_t* hw, u32* int_status)
  * Generate an interrupt to adapter's CPU.
  */
 
-EXPORT_SYMBOL(sdla_intr);
-
+#if 0
 int sdla_intr (sdlahw_t* hw)
 {
        unsigned port = hw->port;
@@ -863,6 +858,7 @@ int sdla_intr (sdlahw_t* hw)
        }
        return 0;
 }
+#endif  /*  0  */
 
 /*============================================================================
  * Execute Adapter Command.
index a6d3b55..2d1bba0 100644 (file)
@@ -221,7 +221,7 @@ static void sppp_clear_timeout(struct sppp *p)
  *     here.
  */
  
-void sppp_input (struct net_device *dev, struct sk_buff *skb)
+static void sppp_input (struct net_device *dev, struct sk_buff *skb)
 {
        struct ppp_header *h;
        struct sppp *sp = (struct sppp *)sppp_of(dev);
@@ -355,8 +355,6 @@ done:
        return;
 }
 
-EXPORT_SYMBOL(sppp_input);
-
 /*
  *     Handle transmit packets.
  */
@@ -990,7 +988,7 @@ EXPORT_SYMBOL(sppp_reopen);
  *     the mtu is out of range.
  */
  
-int sppp_change_mtu(struct net_device *dev, int new_mtu)
+static int sppp_change_mtu(struct net_device *dev, int new_mtu)
 {
        if(new_mtu<128||new_mtu>PPP_MTU||(dev->flags&IFF_UP))
                return -EINVAL;
@@ -998,8 +996,6 @@ int sppp_change_mtu(struct net_device *dev, int new_mtu)
        return 0;
 }
 
-EXPORT_SYMBOL(sppp_change_mtu);
-
 /**
  *     sppp_do_ioctl - Ioctl handler for ppp/hdlc
  *     @dev: Device subject to ioctl
@@ -1456,7 +1452,7 @@ static int sppp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_t
        return 0;
 }
 
-struct packet_type sppp_packet_type = {
+static struct packet_type sppp_packet_type = {
        .type   = __constant_htons(ETH_P_WAN_PPP),
        .func   = sppp_rcv,
 };
index 06998c2..746456c 100644 (file)
@@ -1046,7 +1046,6 @@ static WifiCtlHdr wifictlhdr8023 = {
        }
 };
 
-#ifdef WIRELESS_EXT
 // Frequency list (map channels to frequencies)
 static const long frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
                                2447, 2452, 2457, 2462, 2467, 2472, 2484 };
@@ -1067,7 +1066,6 @@ typedef struct wep_key_t {
 
 /* List of Wireless Handlers (new API) */
 static const struct iw_handler_def     airo_handler_def;
-#endif /* WIRELESS_EXT */
 
 static const char version[] = "airo.c 0.6 (Ben Reed & Javier Achirica)";
 
@@ -1110,10 +1108,8 @@ static irqreturn_t airo_interrupt( int irq, void* dev_id, struct pt_regs
 static int airo_thread(void *data);
 static void timer_func( struct net_device *dev );
 static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-#ifdef WIRELESS_EXT
 static struct iw_statistics *airo_get_wireless_stats (struct net_device *dev);
 static void airo_read_wireless_stats (struct airo_info *local);
-#endif /* WIRELESS_EXT */
 #ifdef CISCO_EXT
 static int readrids(struct net_device *dev, aironet_ioctl *comp);
 static int writerids(struct net_device *dev, aironet_ioctl *comp);
@@ -1187,12 +1183,10 @@ struct airo_info {
                int fid;
        } xmit, xmit11;
        struct net_device *wifidev;
-#ifdef WIRELESS_EXT
        struct iw_statistics    wstats;         // wireless stats
        unsigned long           scan_timestamp; /* Time started to scan */
        struct iw_spy_data      spy_data;
        struct iw_public_data   wireless_data;
-#endif /* WIRELESS_EXT */
 #ifdef MICSUPPORT
        /* MIC stuff */
        struct crypto_tfm       *tfm;
@@ -2527,7 +2521,8 @@ static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci,
        unsigned long mem_start, mem_len, aux_start, aux_len;
        int rc = -1;
        int i;
-       unsigned char *busaddroff,*vpackoff;
+       dma_addr_t busaddroff;
+       unsigned char *vpackoff;
        unsigned char __iomem *pciaddroff;
 
        mem_start = pci_resource_start(pci, 1);
@@ -2570,7 +2565,7 @@ static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci,
        /*
         * Setup descriptor RX, TX, CONFIG
         */
-       busaddroff = (unsigned char *)ai->shared_dma;
+       busaddroff = ai->shared_dma;
        pciaddroff = ai->pciaux + AUX_OFFSET;
        vpackoff   = ai->shared;
 
@@ -2579,7 +2574,7 @@ static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci,
                ai->rxfids[i].pending = 0;
                ai->rxfids[i].card_ram_off = pciaddroff;
                ai->rxfids[i].virtual_host_addr = vpackoff;
-               ai->rxfids[i].rx_desc.host_addr = (dma_addr_t) busaddroff;
+               ai->rxfids[i].rx_desc.host_addr = busaddroff;
                ai->rxfids[i].rx_desc.valid = 1;
                ai->rxfids[i].rx_desc.len = PKTSIZE;
                ai->rxfids[i].rx_desc.rdy = 0;
@@ -2594,7 +2589,7 @@ static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci,
                ai->txfids[i].card_ram_off = pciaddroff;
                ai->txfids[i].virtual_host_addr = vpackoff;
                ai->txfids[i].tx_desc.valid = 1;
-               ai->txfids[i].tx_desc.host_addr = (dma_addr_t) busaddroff;
+               ai->txfids[i].tx_desc.host_addr = busaddroff;
                memcpy(ai->txfids[i].virtual_host_addr,
                        &wifictlhdr8023, sizeof(wifictlhdr8023));
 
@@ -2607,8 +2602,8 @@ static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci,
        /* Rid descriptor setup */
        ai->config_desc.card_ram_off = pciaddroff;
        ai->config_desc.virtual_host_addr = vpackoff;
-       ai->config_desc.rid_desc.host_addr = (dma_addr_t) busaddroff;
-       ai->ridbus = (dma_addr_t)busaddroff;
+       ai->config_desc.rid_desc.host_addr = busaddroff;
+       ai->ridbus = busaddroff;
        ai->config_desc.rid_desc.rid = 0;
        ai->config_desc.rid_desc.len = RIDSIZE;
        ai->config_desc.rid_desc.valid = 1;
@@ -2647,9 +2642,7 @@ static void wifi_setup(struct net_device *dev)
        dev->get_stats = &airo_get_stats;
        dev->set_mac_address = &airo_set_mac_address;
        dev->do_ioctl = &airo_ioctl;
-#ifdef WIRELESS_EXT
        dev->wireless_handlers = &airo_handler_def;
-#endif /* WIRELESS_EXT */
        dev->change_mtu = &airo_change_mtu;
        dev->open = &airo_open;
        dev->stop = &airo_close;
@@ -2675,9 +2668,7 @@ static struct net_device *init_wifidev(struct airo_info *ai,
        dev->priv = ethdev->priv;
        dev->irq = ethdev->irq;
        dev->base_addr = ethdev->base_addr;
-#ifdef WIRELESS_EXT
        dev->wireless_data = ethdev->wireless_data;
-#endif /* WIRELESS_EXT */
        memcpy(dev->dev_addr, ethdev->dev_addr, dev->addr_len);
        err = register_netdev(dev);
        if (err<0) {
@@ -2755,11 +2746,9 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
        dev->set_multicast_list = &airo_set_multicast_list;
        dev->set_mac_address = &airo_set_mac_address;
        dev->do_ioctl = &airo_ioctl;
-#ifdef WIRELESS_EXT
        dev->wireless_handlers = &airo_handler_def;
        ai->wireless_data.spy_data = &ai->spy_data;
        dev->wireless_data = &ai->wireless_data;
-#endif /* WIRELESS_EXT */
        dev->change_mtu = &airo_change_mtu;
        dev->open = &airo_open;
        dev->stop = &airo_close;
@@ -5598,7 +5587,6 @@ static void __exit airo_cleanup_module( void )
        remove_proc_entry("aironet", proc_root_driver);
 }
 
-#ifdef WIRELESS_EXT
 /*
  * Initial Wireless Extension code for Aironet driver by :
  *     Jean Tourrilhes <jt@hpl.hp.com> - HPL - 17 November 00
@@ -7107,8 +7095,6 @@ static const struct iw_handler_def        airo_handler_def =
        .get_wireless_stats = airo_get_wireless_stats,
 };
 
-#endif /* WIRELESS_EXT */
-
 /*
  * This defines the configuration part of the Wireless Extensions
  * Note : irq and spinlock protection will occur in the subroutines
@@ -7187,7 +7173,6 @@ static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
        return rc;
 }
 
-#ifdef WIRELESS_EXT
 /*
  * Get the Wireless stats out of the driver
  * Note : irq and spinlock protection will occur in the subroutines
@@ -7260,7 +7245,6 @@ static struct iw_statistics *airo_get_wireless_stats(struct net_device *dev)
 
        return &local->wstats;
 }
-#endif /* WIRELESS_EXT */
 
 #ifdef CISCO_EXT
 /*
index 9d49670..7b321f7 100644 (file)
 #define PFX DRIVER_NAME ": "
 
 #include <linux/config.h>
-
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/ioport.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/etherdevice.h>
-#include <linux/wireless.h>
-
-#include <asm/io.h>
-#include <asm/system.h>
-#include <asm/current.h>
-#include <asm/prom.h>
-#include <asm/machdep.h>
+#include <linux/delay.h>
 #include <asm/pmac_feature.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
 
 #include "orinoco.h"
 
index 587869d..d570110 100644 (file)
@@ -618,12 +618,12 @@ static int atmel_lock_mac(struct atmel_private *priv);
 static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data);
 static void atmel_command_irq(struct atmel_private *priv);
 static int atmel_validate_channel(struct atmel_private *priv, int channel);
-static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_hdr *header, 
+static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_hdr_4addr *header, 
                                   u16 frame_len, u8 rssi);
 static void atmel_management_timer(u_long a);
 static void atmel_send_command(struct atmel_private *priv, int command, void *cmd, int cmd_size);
 static int atmel_send_command_wait(struct atmel_private *priv, int command, void *cmd, int cmd_size);
-static void atmel_transmit_management_frame(struct atmel_private *priv, struct ieee80211_hdr *header,
+static void atmel_transmit_management_frame(struct atmel_private *priv, struct ieee80211_hdr_4addr *header,
                                            u8 *body, int body_len);
 
 static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index);
@@ -827,7 +827,7 @@ static void tx_update_descriptor(struct atmel_private *priv, int is_bcast, u16 l
 static int start_tx (struct sk_buff *skb, struct net_device *dev)
 {
        struct atmel_private *priv = netdev_priv(dev);
-       struct ieee80211_hdr header;
+       struct ieee80211_hdr_4addr header;
        unsigned long flags;
        u16 buff, frame_ctl, len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
        u8 SNAP_RFC1024[6] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
@@ -902,7 +902,7 @@ static int start_tx (struct sk_buff *skb, struct net_device *dev)
 }
 
 static void atmel_transmit_management_frame(struct atmel_private *priv, 
-                                           struct ieee80211_hdr *header,
+                                           struct ieee80211_hdr_4addr *header,
                                            u8 *body, int body_len)
 {
        u16 buff;
@@ -917,7 +917,7 @@ static void atmel_transmit_management_frame(struct atmel_private *priv,
        tx_update_descriptor(priv, header->addr1[0] & 0x01, len, buff, TX_PACKET_TYPE_MGMT);
 }
        
-static void fast_rx_path(struct atmel_private *priv, struct ieee80211_hdr *header, 
+static void fast_rx_path(struct atmel_private *priv, struct ieee80211_hdr_4addr *header, 
                         u16 msdu_size, u16 rx_packet_loc, u32 crc)
 {
        /* fast path: unfragmented packet copy directly into skbuf */
@@ -990,7 +990,7 @@ static int probe_crc(struct atmel_private *priv, u16 packet_loc, u16 msdu_size)
        return (crc ^ 0xffffffff) == netcrc;
 }
 
-static void frag_rx_path(struct atmel_private *priv, struct ieee80211_hdr *header, 
+static void frag_rx_path(struct atmel_private *priv, struct ieee80211_hdr_4addr *header, 
                         u16 msdu_size, u16 rx_packet_loc, u32 crc, u16 seq_no, u8 frag_no, int more_frags)
 {
        u8 mac4[6]; 
@@ -1082,7 +1082,7 @@ static void frag_rx_path(struct atmel_private *priv, struct ieee80211_hdr *heade
 static void rx_done_irq(struct atmel_private *priv)
 {
        int i;
-       struct ieee80211_hdr header;
+       struct ieee80211_hdr_4addr header;
        
        for (i = 0; 
             atmel_rmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head)) == RX_DESC_FLAG_VALID &&
@@ -2650,7 +2650,7 @@ static void handle_beacon_probe(struct atmel_private *priv, u16 capability, u8 c
  
 static void send_authentication_request(struct atmel_private *priv, u8 *challenge, int challenge_len)
 {
-       struct ieee80211_hdr header;
+       struct ieee80211_hdr_4addr header;
        struct auth_body auth;
        
        header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH); 
@@ -2688,7 +2688,7 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc)
 {
        u8 *ssid_el_p;
        int bodysize;
-       struct ieee80211_hdr header;
+       struct ieee80211_hdr_4addr header;
        struct ass_req_format {
                u16 capability;
                u16 listen_interval; 
@@ -2738,7 +2738,7 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc)
        atmel_transmit_management_frame(priv, &header, (void *)&body, bodysize);
 }
 
-static int is_frame_from_current_bss(struct atmel_private *priv, struct ieee80211_hdr *header)
+static int is_frame_from_current_bss(struct atmel_private *priv, struct ieee80211_hdr_4addr *header)
 {
        if (le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_FROMDS)
                return memcmp(header->addr3, priv->CurrentBSSID, 6) == 0;
@@ -2788,7 +2788,7 @@ static int retrieve_bss(struct atmel_private *priv)
 }
 
 
-static void store_bss_info(struct atmel_private *priv, struct ieee80211_hdr *header,
+static void store_bss_info(struct atmel_private *priv, struct ieee80211_hdr_4addr *header,
                           u16 capability, u16 beacon_period, u8 channel, u8 rssi, 
                           u8 ssid_len, u8 *ssid, int is_beacon)
 {
@@ -3072,7 +3072,7 @@ static void atmel_smooth_qual(struct atmel_private *priv)
 }
 
 /* deals with incoming managment frames. */
-static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_hdr *header, 
+static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_hdr_4addr *header, 
                      u16 frame_len, u8 rssi)
 {
        u16 subtype;
index 21c3d0d..eba0d9d 100644 (file)
  */
 
 #include <linux/config.h>
-
 #include <linux/module.h>
-#include <linux/types.h>
-#include <linux/threads.h>
-#include <linux/smp.h>
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/init.h>
 #include <linux/kernel.h>
-#include <linux/net.h>
-#include <asm/errno.h>
+#include <linux/init.h>
+#include <linux/delay.h>
 
 #include "hermes.h"
 
index 8c9e874..ad28e32 100644 (file)
@@ -30,9 +30,8 @@
  * access to the hermes_t structure, and to the hardware
 */
 
-#include <linux/delay.h>
 #include <linux/if_ether.h>
-#include <asm/byteorder.h>
+#include <asm/io.h>
 
 /*
  * Limits and constants
 #define        HERMES_RXSTAT_WMP               (0x6000)        /* Wavelan-II Management Protocol frame */
 
 struct hermes_tx_descriptor {
-       u16 status;
-       u16 reserved1;
-       u16 reserved2;
-       u32 sw_support;
+       __le16 status;
+       __le16 reserved1;
+       __le16 reserved2;
+       __le32 sw_support;
        u8 retry_count;
        u8 tx_rate;
-       u16 tx_control; 
+       __le16 tx_control;      
 } __attribute__ ((packed));
 
 #define HERMES_TXSTAT_RETRYERR         (0x0001)
@@ -222,60 +221,60 @@ struct hermes_tx_descriptor {
 #define HERMES_INQ_SEC_STAT_AGERE      (0xF202)
 
 struct hermes_tallies_frame {
-       u16 TxUnicastFrames;
-       u16 TxMulticastFrames;
-       u16 TxFragments;
-       u16 TxUnicastOctets;
-       u16 TxMulticastOctets;
-       u16 TxDeferredTransmissions;
-       u16 TxSingleRetryFrames;
-       u16 TxMultipleRetryFrames;
-       u16 TxRetryLimitExceeded;
-       u16 TxDiscards;
-       u16 RxUnicastFrames;
-       u16 RxMulticastFrames;
-       u16 RxFragments;
-       u16 RxUnicastOctets;
-       u16 RxMulticastOctets;
-       u16 RxFCSErrors;
-       u16 RxDiscards_NoBuffer;
-       u16 TxDiscardsWrongSA;
-       u16 RxWEPUndecryptable;
-       u16 RxMsgInMsgFragments;
-       u16 RxMsgInBadMsgFragments;
+       __le16 TxUnicastFrames;
+       __le16 TxMulticastFrames;
+       __le16 TxFragments;
+       __le16 TxUnicastOctets;
+       __le16 TxMulticastOctets;
+       __le16 TxDeferredTransmissions;
+       __le16 TxSingleRetryFrames;
+       __le16 TxMultipleRetryFrames;
+       __le16 TxRetryLimitExceeded;
+       __le16 TxDiscards;
+       __le16 RxUnicastFrames;
+       __le16 RxMulticastFrames;
+       __le16 RxFragments;
+       __le16 RxUnicastOctets;
+       __le16 RxMulticastOctets;
+       __le16 RxFCSErrors;
+       __le16 RxDiscards_NoBuffer;
+       __le16 TxDiscardsWrongSA;
+       __le16 RxWEPUndecryptable;
+       __le16 RxMsgInMsgFragments;
+       __le16 RxMsgInBadMsgFragments;
        /* Those last are probably not available in very old firmwares */
-       u16 RxDiscards_WEPICVError;
-       u16 RxDiscards_WEPExcluded;
+       __le16 RxDiscards_WEPICVError;
+       __le16 RxDiscards_WEPExcluded;
 } __attribute__ ((packed));
 
 /* Grabbed from wlan-ng - Thanks Mark... - Jean II
  * This is the result of a scan inquiry command */
 /* Structure describing info about an Access Point */
 struct prism2_scan_apinfo {
-       u16 channel;            /* Channel where the AP sits */
-       u16 noise;              /* Noise level */
-       u16 level;              /* Signal level */
+       __le16 channel;         /* Channel where the AP sits */
+       __le16 noise;           /* Noise level */
+       __le16 level;           /* Signal level */
        u8 bssid[ETH_ALEN];     /* MAC address of the Access Point */
-       u16 beacon_interv;      /* Beacon interval */
-       u16 capabilities;       /* Capabilities */
-       u16 essid_len;          /* ESSID length */
+       __le16 beacon_interv;   /* Beacon interval */
+       __le16 capabilities;    /* Capabilities */
+       __le16 essid_len;       /* ESSID length */
        u8 essid[32];           /* ESSID of the network */
        u8 rates[10];           /* Bit rate supported */
-       u16 proberesp_rate;     /* Data rate of the response frame */
-       u16 atim;               /* ATIM window time, Kus (hostscan only) */
+       __le16 proberesp_rate;  /* Data rate of the response frame */
+       __le16 atim;            /* ATIM window time, Kus (hostscan only) */
 } __attribute__ ((packed));
 
 /* Same stuff for the Lucent/Agere card.
  * Thanks to h1kari <h1kari AT dachb0den.com> - Jean II */
 struct agere_scan_apinfo {
-       u16 channel;            /* Channel where the AP sits */
-       u16 noise;              /* Noise level */
-       u16 level;              /* Signal level */
+       __le16 channel;         /* Channel where the AP sits */
+       __le16 noise;           /* Noise level */
+       __le16 level;           /* Signal level */
        u8 bssid[ETH_ALEN];     /* MAC address of the Access Point */
-       u16 beacon_interv;      /* Beacon interval */
-       u16 capabilities;       /* Capabilities */
+       __le16 beacon_interv;   /* Beacon interval */
+       __le16 capabilities;    /* Capabilities */
        /* bits: 0-ess, 1-ibss, 4-privacy [wep] */
-       u16 essid_len;          /* ESSID length */
+       __le16 essid_len;       /* ESSID length */
        u8 essid[32];           /* ESSID of the network */
 } __attribute__ ((packed));
 
@@ -283,16 +282,16 @@ struct agere_scan_apinfo {
 struct symbol_scan_apinfo {
        u8 channel;             /* Channel where the AP sits */
        u8 unknown1;            /* 8 in 2.9x and 3.9x f/w, 0 otherwise */
-       u16 noise;              /* Noise level */
-       u16 level;              /* Signal level */
+       __le16 noise;           /* Noise level */
+       __le16 level;           /* Signal level */
        u8 bssid[ETH_ALEN];     /* MAC address of the Access Point */
-       u16 beacon_interv;      /* Beacon interval */
-       u16 capabilities;       /* Capabilities */
+       __le16 beacon_interv;   /* Beacon interval */
+       __le16 capabilities;    /* Capabilities */
        /* bits: 0-ess, 1-ibss, 4-privacy [wep] */
-       u16 essid_len;          /* ESSID length */
+       __le16 essid_len;       /* ESSID length */
        u8 essid[32];           /* ESSID of the network */
-       u16 rates[5];           /* Bit rate supported */
-       u16 basic_rates;        /* Basic rates bitmask */
+       __le16 rates[5];        /* Bit rate supported */
+       __le16 basic_rates;     /* Basic rates bitmask */
        u8 unknown2[6];         /* Always FF:FF:FF:FF:00:00 */
        u8 unknown3[8];         /* Always 0, appeared in f/w 3.91-68 */
 } __attribute__ ((packed));
@@ -312,7 +311,7 @@ union hermes_scan_info {
 #define HERMES_LINKSTATUS_ASSOC_FAILED    (0x0006)
   
 struct hermes_linkstatus {
-       u16 linkstatus;         /* Link status */
+       __le16 linkstatus;         /* Link status */
 } __attribute__ ((packed));
 
 struct hermes_response {
@@ -321,8 +320,8 @@ struct hermes_response {
 
 /* "ID" structure - used for ESSID and station nickname */
 struct hermes_idstring {
-       u16 len;
-       u16 val[16];
+       __le16 len;
+       __le16 val[16];
 } __attribute__ ((packed));
 
 struct hermes_multicast {
@@ -447,7 +446,7 @@ static inline void hermes_clear_words(struct hermes *hw, int off, unsigned count
 
 static inline int hermes_read_wordrec(hermes_t *hw, int bap, u16 rid, u16 *word)
 {
-       u16 rec;
+       __le16 rec;
        int err;
 
        err = HERMES_READ_RECORD(hw, bap, rid, &rec);
@@ -457,7 +456,7 @@ static inline int hermes_read_wordrec(hermes_t *hw, int bap, u16 rid, u16 *word)
 
 static inline int hermes_write_wordrec(hermes_t *hw, int bap, u16 rid, u16 word)
 {
-       u16 rec = cpu_to_le16(word);
+       __le16 rec = cpu_to_le16(word);
        return HERMES_WRITE_RECORD(hw, bap, rid, &rec);
 }
 
index e7f5821..6a96cd9 100644 (file)
@@ -716,9 +716,6 @@ static int prism2_close(struct net_device *dev)
                hostap_deauth_all_stas(dev, local->ap, 1);
 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
 
-       if (local->func->dev_close && local->func->dev_close(local))
-               return 0;
-
        if (dev == local->dev) {
                local->func->hw_shutdown(dev, HOSTAP_HW_ENABLE_CMDCOMPL);
        }
@@ -766,9 +763,6 @@ static int prism2_open(struct net_device *dev)
            local->hw_downloading)
                return -ENODEV;
 
-       if (local->func->dev_open && local->func->dev_open(local))
-               return 1;
-
        if (!try_module_get(local->hw_module))
                return -ENODEV;
        local->num_dev_open++;
index b050124..ffac508 100644 (file)
@@ -6,10 +6,10 @@
 void hostap_dump_rx_80211(const char *name, struct sk_buff *skb,
                          struct hostap_80211_rx_status *rx_stats)
 {
-       struct ieee80211_hdr *hdr;
+       struct ieee80211_hdr_4addr *hdr;
        u16 fc;
 
-       hdr = (struct ieee80211_hdr *) skb->data;
+       hdr = (struct ieee80211_hdr_4addr *) skb->data;
 
        printk(KERN_DEBUG "%s: RX signal=%d noise=%d rate=%d len=%d "
               "jiffies=%ld\n",
@@ -51,7 +51,7 @@ int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb,
        int hdrlen, phdrlen, head_need, tail_need;
        u16 fc;
        int prism_header, ret;
-       struct ieee80211_hdr *hdr;
+       struct ieee80211_hdr_4addr *hdr;
 
        iface = netdev_priv(dev);
        local = iface->local;
@@ -70,7 +70,7 @@ int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb,
                phdrlen = 0;
        }
 
-       hdr = (struct ieee80211_hdr *) skb->data;
+       hdr = (struct ieee80211_hdr_4addr *) skb->data;
        fc = le16_to_cpu(hdr->frame_ctl);
 
        if (type == PRISM2_RX_MGMT && (fc & IEEE80211_FCTL_VERS)) {
@@ -215,7 +215,7 @@ prism2_frag_cache_find(local_info_t *local, unsigned int seq,
 
 /* Called only as a tasklet (software IRQ) */
 static struct sk_buff *
-prism2_frag_cache_get(local_info_t *local, struct ieee80211_hdr *hdr)
+prism2_frag_cache_get(local_info_t *local, struct ieee80211_hdr_4addr *hdr)
 {
        struct sk_buff *skb = NULL;
        u16 sc;
@@ -229,7 +229,7 @@ prism2_frag_cache_get(local_info_t *local, struct ieee80211_hdr *hdr)
        if (frag == 0) {
                /* Reserve enough space to fit maximum frame length */
                skb = dev_alloc_skb(local->dev->mtu +
-                                   sizeof(struct ieee80211_hdr) +
+                                   sizeof(struct ieee80211_hdr_4addr) +
                                    8 /* LLC */ +
                                    2 /* alignment */ +
                                    8 /* WEP */ + ETH_ALEN /* WDS */);
@@ -267,7 +267,7 @@ prism2_frag_cache_get(local_info_t *local, struct ieee80211_hdr *hdr)
 
 /* Called only as a tasklet (software IRQ) */
 static int prism2_frag_cache_invalidate(local_info_t *local,
-                                       struct ieee80211_hdr *hdr)
+                                       struct ieee80211_hdr_4addr *hdr)
 {
        u16 sc;
        unsigned int seq;
@@ -441,7 +441,7 @@ hostap_rx_frame_mgmt(local_info_t *local, struct sk_buff *skb,
                     u16 stype)
 {
        if (local->iw_mode == IW_MODE_MASTER) {
-               hostap_update_sta_ps(local, (struct ieee80211_hdr *)
+               hostap_update_sta_ps(local, (struct ieee80211_hdr_4addr *)
                                     skb->data);
        }
 
@@ -520,7 +520,7 @@ static inline struct net_device *prism2_rx_get_wds(local_info_t *local,
 
 
 static inline int
-hostap_rx_frame_wds(local_info_t *local, struct ieee80211_hdr *hdr,
+hostap_rx_frame_wds(local_info_t *local, struct ieee80211_hdr_4addr *hdr,
                    u16 fc, struct net_device **wds)
 {
        /* FIX: is this really supposed to accept WDS frames only in Master
@@ -579,13 +579,13 @@ static int hostap_is_eapol_frame(local_info_t *local, struct sk_buff *skb)
 {
        struct net_device *dev = local->dev;
        u16 fc, ethertype;
-       struct ieee80211_hdr *hdr;
+       struct ieee80211_hdr_4addr *hdr;
        u8 *pos;
 
        if (skb->len < 24)
                return 0;
 
-       hdr = (struct ieee80211_hdr *) skb->data;
+       hdr = (struct ieee80211_hdr_4addr *) skb->data;
        fc = le16_to_cpu(hdr->frame_ctl);
 
        /* check that the frame is unicast frame to us */
@@ -619,13 +619,13 @@ static inline int
 hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb,
                        struct ieee80211_crypt_data *crypt)
 {
-       struct ieee80211_hdr *hdr;
+       struct ieee80211_hdr_4addr *hdr;
        int res, hdrlen;
 
        if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
                return 0;
 
-       hdr = (struct ieee80211_hdr *) skb->data;
+       hdr = (struct ieee80211_hdr_4addr *) skb->data;
        hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
 
        if (local->tkip_countermeasures &&
@@ -658,13 +658,13 @@ static inline int
 hostap_rx_frame_decrypt_msdu(local_info_t *local, struct sk_buff *skb,
                             int keyidx, struct ieee80211_crypt_data *crypt)
 {
-       struct ieee80211_hdr *hdr;
+       struct ieee80211_hdr_4addr *hdr;
        int res, hdrlen;
 
        if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
                return 0;
 
-       hdr = (struct ieee80211_hdr *) skb->data;
+       hdr = (struct ieee80211_hdr_4addr *) skb->data;
        hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
 
        atomic_inc(&crypt->refcnt);
@@ -689,7 +689,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
 {
        struct hostap_interface *iface;
        local_info_t *local;
-       struct ieee80211_hdr *hdr;
+       struct ieee80211_hdr_4addr *hdr;
        size_t hdrlen;
        u16 fc, type, stype, sc;
        struct net_device *wds = NULL;
@@ -716,7 +716,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
        dev = local->ddev;
        iface = netdev_priv(dev);
 
-       hdr = (struct ieee80211_hdr *) skb->data;
+       hdr = (struct ieee80211_hdr_4addr *) skb->data;
        stats = hostap_get_stats(dev);
 
        if (skb->len < 10)
@@ -737,7 +737,8 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
                struct iw_quality wstats;
                wstats.level = rx_stats->signal;
                wstats.noise = rx_stats->noise;
-               wstats.updated = 6;     /* No qual value */
+               wstats.updated = IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_UPDATED
+                       | IW_QUAL_QUAL_INVALID | IW_QUAL_DBM;
                /* Update spy records */
                wireless_spy_update(dev, hdr->addr2, &wstats);
        }
@@ -889,7 +890,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
        if (local->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) &&
            (keyidx = hostap_rx_frame_decrypt(local, skb, crypt)) < 0)
                goto rx_dropped;
-       hdr = (struct ieee80211_hdr *) skb->data;
+       hdr = (struct ieee80211_hdr_4addr *) skb->data;
 
        /* skb: hdr + (possibly fragmented) plaintext payload */
 
@@ -941,7 +942,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
                /* this was the last fragment and the frame will be
                 * delivered, so remove skb from fragment cache */
                skb = frag_skb;
-               hdr = (struct ieee80211_hdr *) skb->data;
+               hdr = (struct ieee80211_hdr_4addr *) skb->data;
                prism2_frag_cache_invalidate(local, hdr);
        }
 
@@ -952,7 +953,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
            hostap_rx_frame_decrypt_msdu(local, skb, keyidx, crypt))
                goto rx_dropped;
 
-       hdr = (struct ieee80211_hdr *) skb->data;
+       hdr = (struct ieee80211_hdr_4addr *) skb->data;
        if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !local->open_wep) {
                if (local->ieee_802_1x &&
                    hostap_is_eapol_frame(local, skb)) {
index 6358015..9d24f8a 100644 (file)
@@ -1,9 +1,9 @@
 void hostap_dump_tx_80211(const char *name, struct sk_buff *skb)
 {
-       struct ieee80211_hdr *hdr;
+       struct ieee80211_hdr_4addr *hdr;
        u16 fc;
 
-       hdr = (struct ieee80211_hdr *) skb->data;
+       hdr = (struct ieee80211_hdr_4addr *) skb->data;
 
        printk(KERN_DEBUG "%s: TX len=%d jiffies=%ld\n",
               name, skb->len, jiffies);
@@ -41,7 +41,7 @@ int hostap_data_start_xmit(struct sk_buff *skb, struct net_device *dev)
        struct hostap_interface *iface;
        local_info_t *local;
        int need_headroom, need_tailroom = 0;
-       struct ieee80211_hdr hdr;
+       struct ieee80211_hdr_4addr hdr;
        u16 fc, ethertype = 0;
        enum {
                WDS_NO = 0, WDS_OWN_FRAME, WDS_COMPLIANT_FRAME
@@ -244,7 +244,7 @@ int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev)
        struct hostap_interface *iface;
        local_info_t *local;
        struct hostap_skb_tx_data *meta;
-       struct ieee80211_hdr *hdr;
+       struct ieee80211_hdr_4addr *hdr;
        u16 fc;
 
        iface = netdev_priv(dev);
@@ -266,7 +266,7 @@ int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev)
        meta->iface = iface;
 
        if (skb->len >= IEEE80211_DATA_HDR3_LEN + sizeof(rfc1042_header) + 2) {
-               hdr = (struct ieee80211_hdr *) skb->data;
+               hdr = (struct ieee80211_hdr_4addr *) skb->data;
                fc = le16_to_cpu(hdr->frame_ctl);
                if (WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA &&
                    WLAN_FC_GET_STYPE(fc) == IEEE80211_STYPE_DATA) {
@@ -289,7 +289,7 @@ struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
 {
        struct hostap_interface *iface;
        local_info_t *local;
-       struct ieee80211_hdr *hdr;
+       struct ieee80211_hdr_4addr *hdr;
        u16 fc;
        int hdr_len, res;
 
@@ -303,7 +303,7 @@ struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
 
        if (local->tkip_countermeasures &&
            crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
-               hdr = (struct ieee80211_hdr *) skb->data;
+               hdr = (struct ieee80211_hdr_4addr *) skb->data;
                if (net_ratelimit()) {
                        printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
                               "TX packet to " MACSTR "\n",
@@ -317,15 +317,15 @@ struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
        if (skb == NULL)
                return NULL;
 
-       if ((skb_headroom(skb) < crypt->ops->extra_prefix_len ||
-            skb_tailroom(skb) < crypt->ops->extra_postfix_len) &&
-           pskb_expand_head(skb, crypt->ops->extra_prefix_len,
-                            crypt->ops->extra_postfix_len, GFP_ATOMIC)) {
+       if ((skb_headroom(skb) < crypt->ops->extra_mpdu_prefix_len ||
+            skb_tailroom(skb) < crypt->ops->extra_mpdu_postfix_len) &&
+           pskb_expand_head(skb, crypt->ops->extra_mpdu_prefix_len,
+                            crypt->ops->extra_mpdu_postfix_len, GFP_ATOMIC)) {
                kfree_skb(skb);
                return NULL;
        }
 
-       hdr = (struct ieee80211_hdr *) skb->data;
+       hdr = (struct ieee80211_hdr_4addr *) skb->data;
        fc = le16_to_cpu(hdr->frame_ctl);
        hdr_len = hostap_80211_get_hdrlen(fc);
 
@@ -360,7 +360,7 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
        ap_tx_ret tx_ret;
        struct hostap_skb_tx_data *meta;
        int no_encrypt = 0;
-       struct ieee80211_hdr *hdr;
+       struct ieee80211_hdr_4addr *hdr;
 
        iface = netdev_priv(dev);
        local = iface->local;
@@ -403,7 +403,7 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
        tx_ret = hostap_handle_sta_tx(local, &tx);
        skb = tx.skb;
        meta = (struct hostap_skb_tx_data *) skb->cb;
-       hdr = (struct ieee80211_hdr *) skb->data;
+       hdr = (struct ieee80211_hdr_4addr *) skb->data;
        fc = le16_to_cpu(hdr->frame_ctl);
        switch (tx_ret) {
        case AP_TX_CONTINUE:
index 930cef8..9da94ab 100644 (file)
@@ -591,14 +591,14 @@ static void hostap_ap_tx_cb(struct sk_buff *skb, int ok, void *data)
 {
        struct ap_data *ap = data;
        u16 fc;
-       struct ieee80211_hdr *hdr;
+       struct ieee80211_hdr_4addr *hdr;
 
        if (!ap->local->hostapd || !ap->local->apdev) {
                dev_kfree_skb(skb);
                return;
        }
 
-       hdr = (struct ieee80211_hdr *) skb->data;
+       hdr = (struct ieee80211_hdr_4addr *) skb->data;
        fc = le16_to_cpu(hdr->frame_ctl);
 
        /* Pass the TX callback frame to the hostapd; use 802.11 header version
@@ -623,7 +623,7 @@ static void hostap_ap_tx_cb_auth(struct sk_buff *skb, int ok, void *data)
 {
        struct ap_data *ap = data;
        struct net_device *dev = ap->local->dev;
-       struct ieee80211_hdr *hdr;
+       struct ieee80211_hdr_4addr *hdr;
        u16 fc, *pos, auth_alg, auth_transaction, status;
        struct sta_info *sta = NULL;
        char *txt = NULL;
@@ -633,7 +633,7 @@ static void hostap_ap_tx_cb_auth(struct sk_buff *skb, int ok, void *data)
                return;
        }
 
-       hdr = (struct ieee80211_hdr *) skb->data;
+       hdr = (struct ieee80211_hdr_4addr *) skb->data;
        fc = le16_to_cpu(hdr->frame_ctl);
        if (WLAN_FC_GET_TYPE(fc) != IEEE80211_FTYPE_MGMT ||
            WLAN_FC_GET_STYPE(fc) != IEEE80211_STYPE_AUTH ||
@@ -692,7 +692,7 @@ static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data)
 {
        struct ap_data *ap = data;
        struct net_device *dev = ap->local->dev;
-       struct ieee80211_hdr *hdr;
+       struct ieee80211_hdr_4addr *hdr;
        u16 fc, *pos, status;
        struct sta_info *sta = NULL;
        char *txt = NULL;
@@ -702,7 +702,7 @@ static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data)
                return;
        }
 
-       hdr = (struct ieee80211_hdr *) skb->data;
+       hdr = (struct ieee80211_hdr_4addr *) skb->data;
        fc = le16_to_cpu(hdr->frame_ctl);
        if (WLAN_FC_GET_TYPE(fc) != IEEE80211_FTYPE_MGMT ||
            (WLAN_FC_GET_STYPE(fc) != IEEE80211_STYPE_ASSOC_RESP &&
@@ -757,12 +757,12 @@ static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data)
 static void hostap_ap_tx_cb_poll(struct sk_buff *skb, int ok, void *data)
 {
        struct ap_data *ap = data;
-       struct ieee80211_hdr *hdr;
+       struct ieee80211_hdr_4addr *hdr;
        struct sta_info *sta;
 
        if (skb->len < 24)
                goto fail;
-       hdr = (struct ieee80211_hdr *) skb->data;
+       hdr = (struct ieee80211_hdr_4addr *) skb->data;
        if (ok) {
                spin_lock(&ap->sta_table_lock);
                sta = ap_get_sta(ap, hdr->addr1);
@@ -918,7 +918,7 @@ static void prism2_send_mgmt(struct net_device *dev,
 {
        struct hostap_interface *iface;
        local_info_t *local;
-       struct ieee80211_hdr *hdr;
+       struct ieee80211_hdr_4addr *hdr;
        u16 fc;
        struct sk_buff *skb;
        struct hostap_skb_tx_data *meta;
@@ -944,7 +944,7 @@ static void prism2_send_mgmt(struct net_device *dev,
 
        fc = type_subtype;
        hdrlen = hostap_80211_get_hdrlen(fc);
-       hdr = (struct ieee80211_hdr *) skb_put(skb, hdrlen);
+       hdr = (struct ieee80211_hdr_4addr *) skb_put(skb, hdrlen);
        if (body)
                memcpy(skb_put(skb, body_len), body, body_len);
 
@@ -1256,14 +1256,14 @@ static char * ap_auth_make_challenge(struct ap_data *ap)
        }
 
        skb = dev_alloc_skb(WLAN_AUTH_CHALLENGE_LEN +
-                           ap->crypt->extra_prefix_len +
-                           ap->crypt->extra_postfix_len);
+                           ap->crypt->extra_mpdu_prefix_len +
+                           ap->crypt->extra_mpdu_postfix_len);
        if (skb == NULL) {
                kfree(tmpbuf);
                return NULL;
        }
 
-       skb_reserve(skb, ap->crypt->extra_prefix_len);
+       skb_reserve(skb, ap->crypt->extra_mpdu_prefix_len);
        memset(skb_put(skb, WLAN_AUTH_CHALLENGE_LEN), 0,
               WLAN_AUTH_CHALLENGE_LEN);
        if (ap->crypt->encrypt_mpdu(skb, 0, ap->crypt_priv)) {
@@ -1272,7 +1272,7 @@ static char * ap_auth_make_challenge(struct ap_data *ap)
                return NULL;
        }
 
-       memcpy(tmpbuf, skb->data + ap->crypt->extra_prefix_len,
+       memcpy(tmpbuf, skb->data + ap->crypt->extra_mpdu_prefix_len,
               WLAN_AUTH_CHALLENGE_LEN);
        dev_kfree_skb(skb);
 
@@ -1285,7 +1285,7 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb,
                          struct hostap_80211_rx_status *rx_stats)
 {
        struct net_device *dev = local->dev;
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+       struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
        size_t hdrlen;
        struct ap_data *ap = local->ap;
        char body[8 + WLAN_AUTH_CHALLENGE_LEN], *challenge = NULL;
@@ -1498,7 +1498,7 @@ static void handle_assoc(local_info_t *local, struct sk_buff *skb,
                         struct hostap_80211_rx_status *rx_stats, int reassoc)
 {
        struct net_device *dev = local->dev;
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+       struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
        char body[12], *p, *lpos;
        int len, left;
        u16 *pos;
@@ -1705,7 +1705,7 @@ static void handle_deauth(local_info_t *local, struct sk_buff *skb,
                          struct hostap_80211_rx_status *rx_stats)
 {
        struct net_device *dev = local->dev;
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+       struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
        char *body = (char *) (skb->data + IEEE80211_MGMT_HDR_LEN);
        int len;
        u16 reason_code, *pos;
@@ -1746,7 +1746,7 @@ static void handle_disassoc(local_info_t *local, struct sk_buff *skb,
                            struct hostap_80211_rx_status *rx_stats)
 {
        struct net_device *dev = local->dev;
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+       struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
        char *body = skb->data + IEEE80211_MGMT_HDR_LEN;
        int len;
        u16 reason_code, *pos;
@@ -1784,7 +1784,7 @@ static void handle_disassoc(local_info_t *local, struct sk_buff *skb,
 
 /* Called only as a scheduled task for pending AP frames. */
 static void ap_handle_data_nullfunc(local_info_t *local,
-                                   struct ieee80211_hdr *hdr)
+                                   struct ieee80211_hdr_4addr *hdr)
 {
        struct net_device *dev = local->dev;
 
@@ -1801,7 +1801,7 @@ static void ap_handle_data_nullfunc(local_info_t *local,
 
 /* Called only as a scheduled task for pending AP frames. */
 static void ap_handle_dropped_data(local_info_t *local,
-                                  struct ieee80211_hdr *hdr)
+                                  struct ieee80211_hdr_4addr *hdr)
 {
        struct net_device *dev = local->dev;
        struct sta_info *sta;
@@ -1860,7 +1860,7 @@ static void pspoll_send_buffered(local_info_t *local, struct sta_info *sta,
 
 /* Called only as a scheduled task for pending AP frames. */
 static void handle_pspoll(local_info_t *local,
-                         struct ieee80211_hdr *hdr,
+                         struct ieee80211_hdr_4addr *hdr,
                          struct hostap_80211_rx_status *rx_stats)
 {
        struct net_device *dev = local->dev;
@@ -1979,7 +1979,7 @@ static void handle_wds_oper_queue(void *data)
 static void handle_beacon(local_info_t *local, struct sk_buff *skb,
                          struct hostap_80211_rx_status *rx_stats)
 {
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+       struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
        char *body = skb->data + IEEE80211_MGMT_HDR_LEN;
        int len, left;
        u16 *pos, beacon_int, capability;
@@ -2137,11 +2137,11 @@ static void handle_ap_item(local_info_t *local, struct sk_buff *skb,
        struct net_device *dev = local->dev;
 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
        u16 fc, type, stype;
-       struct ieee80211_hdr *hdr;
+       struct ieee80211_hdr_4addr *hdr;
 
        /* FIX: should give skb->len to handler functions and check that the
         * buffer is long enough */
-       hdr = (struct ieee80211_hdr *) skb->data;
+       hdr = (struct ieee80211_hdr_4addr *) skb->data;
        fc = le16_to_cpu(hdr->frame_ctl);
        type = WLAN_FC_GET_TYPE(fc);
        stype = WLAN_FC_GET_STYPE(fc);
@@ -2258,7 +2258,7 @@ void hostap_rx(struct net_device *dev, struct sk_buff *skb,
        struct hostap_interface *iface;
        local_info_t *local;
        u16 fc;
-       struct ieee80211_hdr *hdr;
+       struct ieee80211_hdr_4addr *hdr;
 
        iface = netdev_priv(dev);
        local = iface->local;
@@ -2268,7 +2268,7 @@ void hostap_rx(struct net_device *dev, struct sk_buff *skb,
 
        local->stats.rx_packets++;
 
-       hdr = (struct ieee80211_hdr *) skb->data;
+       hdr = (struct ieee80211_hdr_4addr *) skb->data;
        fc = le16_to_cpu(hdr->frame_ctl);
 
        if (local->ap->ap_policy == AP_OTHER_AP_SKIP_ALL &&
@@ -2289,7 +2289,7 @@ void hostap_rx(struct net_device *dev, struct sk_buff *skb,
 static void schedule_packet_send(local_info_t *local, struct sta_info *sta)
 {
        struct sk_buff *skb;
-       struct ieee80211_hdr *hdr;
+       struct ieee80211_hdr_4addr *hdr;
        struct hostap_80211_rx_status rx_stats;
 
        if (skb_queue_empty(&sta->tx_buf))
@@ -2302,7 +2302,7 @@ static void schedule_packet_send(local_info_t *local, struct sta_info *sta)
                return;
        }
 
-       hdr = (struct ieee80211_hdr *) skb_put(skb, 16);
+       hdr = (struct ieee80211_hdr_4addr *) skb_put(skb, 16);
 
        /* Generate a fake pspoll frame to start packet delivery */
        hdr->frame_ctl = __constant_cpu_to_le16(
@@ -2349,7 +2349,7 @@ static int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
                qual[count].noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence);
                qual[count].updated = sta->last_rx_updated;
 
-               sta->last_rx_updated = 0;
+               sta->last_rx_updated = IW_QUAL_DBM;
 
                count++;
                if (count >= buf_size)
@@ -2467,7 +2467,7 @@ static int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
                }
 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
 
-               sta->last_rx_updated = 0;
+               sta->last_rx_updated = IW_QUAL_DBM;
 
                /* To be continued, we should make good use of IWEVCUSTOM */
        }
@@ -2685,7 +2685,7 @@ ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx)
        struct sta_info *sta = NULL;
        struct sk_buff *skb = tx->skb;
        int set_tim, ret;
-       struct ieee80211_hdr *hdr;
+       struct ieee80211_hdr_4addr *hdr;
        struct hostap_skb_tx_data *meta;
 
        meta = (struct hostap_skb_tx_data *) skb->cb;
@@ -2694,7 +2694,7 @@ ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx)
            meta->iface->type == HOSTAP_INTERFACE_STA)
                goto out;
 
-       hdr = (struct ieee80211_hdr *) skb->data;
+       hdr = (struct ieee80211_hdr_4addr *) skb->data;
 
        if (hdr->addr1[0] & 0x01) {
                /* broadcast/multicast frame - no AP related processing */
@@ -2821,10 +2821,10 @@ void hostap_handle_sta_release(void *ptr)
 void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb)
 {
        struct sta_info *sta;
-       struct ieee80211_hdr *hdr;
+       struct ieee80211_hdr_4addr *hdr;
        struct hostap_skb_tx_data *meta;
 
-       hdr = (struct ieee80211_hdr *) skb->data;
+       hdr = (struct ieee80211_hdr_4addr *) skb->data;
        meta = (struct hostap_skb_tx_data *) skb->cb;
 
        spin_lock(&local->ap->sta_table_lock);
@@ -2892,7 +2892,7 @@ static void hostap_update_sta_ps2(local_info_t *local, struct sta_info *sta,
 
 /* Called only as a tasklet (software IRQ). Called for each RX frame to update
  * STA power saving state. pwrmgt is a flag from 802.11 frame_ctl field. */
-int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr *hdr)
+int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr_4addr *hdr)
 {
        struct sta_info *sta;
        u16 fc;
@@ -2925,12 +2925,12 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
        int ret;
        struct sta_info *sta;
        u16 fc, type, stype;
-       struct ieee80211_hdr *hdr;
+       struct ieee80211_hdr_4addr *hdr;
 
        if (local->ap == NULL)
                return AP_RX_CONTINUE;
 
-       hdr = (struct ieee80211_hdr *) skb->data;
+       hdr = (struct ieee80211_hdr_4addr *) skb->data;
 
        fc = le16_to_cpu(hdr->frame_ctl);
        type = WLAN_FC_GET_TYPE(fc);
@@ -3058,7 +3058,7 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
 
 /* Called only as a tasklet (software IRQ) */
 int hostap_handle_sta_crypto(local_info_t *local,
-                            struct ieee80211_hdr *hdr,
+                            struct ieee80211_hdr_4addr *hdr,
                             struct ieee80211_crypt_data **crypt,
                             void **sta_ptr)
 {
@@ -3160,7 +3160,7 @@ int hostap_add_sta(struct ap_data *ap, u8 *sta_addr)
 
 /* Called only as a tasklet (software IRQ) */
 int hostap_update_rx_stats(struct ap_data *ap,
-                          struct ieee80211_hdr *hdr,
+                          struct ieee80211_hdr_4addr *hdr,
                           struct hostap_80211_rx_status *rx_stats)
 {
        struct sta_info *sta;
@@ -3174,7 +3174,7 @@ int hostap_update_rx_stats(struct ap_data *ap,
                sta->last_rx_silence = rx_stats->noise;
                sta->last_rx_signal = rx_stats->signal;
                sta->last_rx_rate = rx_stats->rate;
-               sta->last_rx_updated = 7;
+               sta->last_rx_updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
                if (rx_stats->rate == 10)
                        sta->rx_count[0]++;
                else if (rx_stats->rate == 20)
index 816a52b..6d00df6 100644 (file)
@@ -233,7 +233,7 @@ struct hostap_tx_data {
 ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx);
 void hostap_handle_sta_release(void *ptr);
 void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb);
-int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr *hdr);
+int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr_4addr *hdr);
 typedef enum {
        AP_RX_CONTINUE, AP_RX_DROP, AP_RX_EXIT, AP_RX_CONTINUE_NOT_AUTHORIZED
 } ap_rx_ret;
@@ -241,13 +241,13 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
                               struct sk_buff *skb,
                               struct hostap_80211_rx_status *rx_stats,
                               int wds);
-int hostap_handle_sta_crypto(local_info_t *local, struct ieee80211_hdr *hdr,
+int hostap_handle_sta_crypto(local_info_t *local, struct ieee80211_hdr_4addr *hdr,
                             struct ieee80211_crypt_data **crypt,
                             void **sta_ptr);
 int hostap_is_sta_assoc(struct ap_data *ap, u8 *sta_addr);
 int hostap_is_sta_authorized(struct ap_data *ap, u8 *sta_addr);
 int hostap_add_sta(struct ap_data *ap, u8 *sta_addr);
-int hostap_update_rx_stats(struct ap_data *ap, struct ieee80211_hdr *hdr,
+int hostap_update_rx_stats(struct ap_data *ap, struct ieee80211_hdr_4addr *hdr,
                           struct hostap_80211_rx_status *rx_stats);
 void hostap_update_rates(local_info_t *local);
 void hostap_add_wds_links(local_info_t *local);
index faa83ba..2643976 100644 (file)
@@ -492,42 +492,10 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr)
 }
 
 
-static int prism2_pccard_dev_open(local_info_t *local)
-{
-       struct hostap_cs_priv *hw_priv = local->hw_priv;
-       hw_priv->link->open++;
-       return 0;
-}
-
-
-static int prism2_pccard_dev_close(local_info_t *local)
-{
-       struct hostap_cs_priv *hw_priv;
-
-       if (local == NULL || local->hw_priv == NULL)
-               return 1;
-       hw_priv = local->hw_priv;
-       if (hw_priv->link == NULL)
-               return 1;
-
-       if (!hw_priv->link->open) {
-               printk(KERN_WARNING "%s: prism2_pccard_dev_close(): "
-                      "link not open?!\n", local->dev->name);
-               return 1;
-       }
-
-       hw_priv->link->open--;
-
-       return 0;
-}
-
-
 static struct prism2_helper_functions prism2_pccard_funcs =
 {
        .card_present   = prism2_pccard_card_present,
        .cor_sreset     = prism2_pccard_cor_sreset,
-       .dev_open       = prism2_pccard_dev_open,
-       .dev_close      = prism2_pccard_dev_close,
        .genesis_reset  = prism2_pccard_genesis_reset,
        .hw_type        = HOSTAP_HW_PCCARD,
 };
@@ -597,13 +565,14 @@ static void prism2_detach(dev_link_t *link)
        *linkp = link->next;
        /* release net devices */
        if (link->priv) {
+               struct hostap_cs_priv *hw_priv;
                struct net_device *dev;
                struct hostap_interface *iface;
                dev = link->priv;
                iface = netdev_priv(dev);
-               kfree(iface->local->hw_priv);
-               iface->local->hw_priv = NULL;
+               hw_priv = iface->local->hw_priv;
                prism2_free_local_data(dev);
+               kfree(hw_priv);
        }
        kfree(link);
 }
@@ -883,6 +852,13 @@ static int prism2_event(event_t event, int priority,
 {
        dev_link_t *link = args->client_data;
        struct net_device *dev = (struct net_device *) link->priv;
+       int dev_open = 0;
+
+       if (link->state & DEV_CONFIG) {
+               struct hostap_interface *iface = netdev_priv(dev);
+               if (iface && iface->local)
+                       dev_open = iface->local->num_dev_open > 0;
+       }
 
        switch (event) {
        case CS_EVENT_CARD_INSERTION:
@@ -911,7 +887,7 @@ static int prism2_event(event_t event, int priority,
        case CS_EVENT_RESET_PHYSICAL:
                PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_RESET_PHYSICAL\n", dev_info);
                if (link->state & DEV_CONFIG) {
-                       if (link->open) {
+                       if (dev_open) {
                                netif_stop_queue(dev);
                                netif_device_detach(dev);
                        }
@@ -931,8 +907,8 @@ static int prism2_event(event_t event, int priority,
                        pcmcia_request_configuration(link->handle,
                                                     &link->conf);
                        prism2_hw_shutdown(dev, 1);
-                       prism2_hw_config(dev, link->open ? 0 : 1);
-                       if (link->open) {
+                       prism2_hw_config(dev, dev_open ? 0 : 1);
+                       if (dev_open) {
                                netif_device_attach(dev);
                                netif_start_queue(dev);
                        }
index e533a66..59fc155 100644 (file)
@@ -3322,6 +3322,18 @@ static void prism2_free_local_data(struct net_device *dev)
        iface = netdev_priv(dev);
        local = iface->local;
 
+       /* Unregister all netdevs before freeing local data. */
+       list_for_each_safe(ptr, n, &local->hostap_interfaces) {
+               iface = list_entry(ptr, struct hostap_interface, list);
+               if (iface->type == HOSTAP_INTERFACE_MASTER) {
+                       /* special handling for this interface below */
+                       continue;
+               }
+               hostap_remove_interface(iface->dev, 0, 1);
+       }
+
+       unregister_netdev(local->dev);
+
        flush_scheduled_work();
 
        if (timer_pending(&local->crypt_deinit_timer))
@@ -3382,15 +3394,6 @@ static void prism2_free_local_data(struct net_device *dev)
        prism2_download_free_data(local->dl_sec);
 #endif /* PRISM2_DOWNLOAD_SUPPORT */
 
-       list_for_each_safe(ptr, n, &local->hostap_interfaces) {
-               iface = list_entry(ptr, struct hostap_interface, list);
-               if (iface->type == HOSTAP_INTERFACE_MASTER) {
-                       /* special handling for this interface below */
-                       continue;
-               }
-               hostap_remove_interface(iface->dev, 0, 1);
-       }
-
        prism2_clear_set_tim_queue(local);
 
        list_for_each_safe(ptr, n, &local->bss_list) {
@@ -3403,7 +3406,6 @@ static void prism2_free_local_data(struct net_device *dev)
        kfree(local->last_scan_results);
        kfree(local->generic_elem);
 
-       unregister_netdev(local->dev);
        free_netdev(local->dev);
 }
 
index e720369..53f5246 100644 (file)
@@ -50,7 +50,8 @@ static struct iw_statistics *hostap_get_wireless_stats(struct net_device *dev)
 #endif /* in_atomic */
 
                if (update && prism2_update_comms_qual(dev) == 0)
-                       wstats->qual.updated = 7;
+                       wstats->qual.updated = IW_QUAL_ALL_UPDATED |
+                               IW_QUAL_DBM;
 
                wstats->qual.qual = local->comms_qual;
                wstats->qual.level = local->avg_signal;
@@ -59,7 +60,7 @@ static struct iw_statistics *hostap_get_wireless_stats(struct net_device *dev)
                wstats->qual.qual = 0;
                wstats->qual.level = 0;
                wstats->qual.noise = 0;
-               wstats->qual.updated = 0;
+               wstats->qual.updated = IW_QUAL_ALL_INVALID;
        }
 
        return wstats;
@@ -1827,13 +1828,6 @@ static char * __prism2_translate_scan(local_info_t *local,
        iwe.cmd = SIOCGIWAP;
        iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
        memcpy(iwe.u.ap_addr.sa_data, bssid, ETH_ALEN);
-       /* FIX:
-        * I do not know how this is possible, but iwe_stream_add_event
-        * seems to re-order memcpy execution so that len is set only
-        * after copying.. Pre-setting len here "fixes" this, but real
-        * problems should be solved (after which these iwe.len
-        * settings could be removed from this function). */
-       iwe.len = IW_EV_ADDR_LEN;
        current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
                                          IW_EV_ADDR_LEN);
 
@@ -1843,7 +1837,6 @@ static char * __prism2_translate_scan(local_info_t *local,
        iwe.cmd = SIOCGIWESSID;
        iwe.u.data.length = ssid_len;
        iwe.u.data.flags = 1;
-       iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
        current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, ssid);
 
        memset(&iwe, 0, sizeof(iwe));
@@ -1859,7 +1852,6 @@ static char * __prism2_translate_scan(local_info_t *local,
                        iwe.u.mode = IW_MODE_MASTER;
                else
                        iwe.u.mode = IW_MODE_ADHOC;
-               iwe.len = IW_EV_UINT_LEN;
                current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
                                                  IW_EV_UINT_LEN);
        }
@@ -1877,7 +1869,6 @@ static char * __prism2_translate_scan(local_info_t *local,
        if (chan > 0) {
                iwe.u.freq.m = freq_list[le16_to_cpu(chan - 1)] * 100000;
                iwe.u.freq.e = 1;
-               iwe.len = IW_EV_FREQ_LEN;
                current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
                                                  IW_EV_FREQ_LEN);
        }