]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge branch 'upstream-fixes'
authorJeff Garzik <jgarzik@pobox.com>
Tue, 4 Oct 2005 02:06:19 +0000 (22:06 -0400)
committerJeff Garzik <jgarzik@pobox.com>
Tue, 4 Oct 2005 02:06:19 +0000 (22:06 -0400)
115 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
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 bc537440ca025931124c278d81f66a3d742cabf6..f822cd3025ff07b154e48e7cd2d226e21f4f6898 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 4c2cf7bbd252927c40a018bb8d69b0e3c26b900e..76ef6efd59507fb619c386b0d38c9457435b2750 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 2a908c4690a7cd41eae1793dec2d9c6daa2e9b41..018b11a7a4ce04c41c7ed14e3d24d179c4822243 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 8aeec9f2495b5e712879b7735e95bf141ce49e05..4c9477cb212778bb021e821e52736547955b6e3e 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 94939f570f78988e7c54c9dbcab685ca59385253..d27e870e59abb2da1a5a9e2fcd69ef7a81fc36fb 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 fbf1c06ec5c12aac8c83defb67221339325337e3..c15406d46418d4f76a3f13185b902557392d86a8 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 f133ff0b0b947c6ad6a76635ff5f159f6cad83bd..8f3a13420278278c0aa7d1f3bddd432056cbe879 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 ee687c902a20be52d0bdf95ef4fc58b03f5317a3..c062b0ad8262202b1b4fb2fbbf1cb9dab1c85852 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 d6eefdb71c174889b6491635121fe33f9b789594..e5f480203675f31c00d0087f7af0ff4321dc6043 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 6518334b92801a41745718b09a74805e3e7b8004..ae5a2ed3b2640336a656087596206d2e462ee73e 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 28af087d9fbba24d0005fd66c34f765005565610..c77ca6c0d04a6d651c0e3d37ca749146b5e9bc5c 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 a451de629197b13e1204f59b2707fef1d425e91d..68e3578e76133b8783b5dcfa1db03367c5e0d9ac 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 cf0ac6fda1a1741390486e2168271cf3fc4ba554..b71fab6e34f4268e0dc53ad9d675cac3f998309a 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 15f207323d97043b124dd6282835447804abf5aa..3961a754e920e37e8a1b310670edcdb48549a46c 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 9d026ed77ddd4250660ad117d76c2e319e6d3eda..04e47189d830105a848d6b6db71c8dd26f625de9 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 89d6d69be382a3d625892823d8859cbae8237908..176680cb153e8b114797f4e6a8bad2f1837c678c 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 27f0d8ac4c40d99a869e2cd297007dbeeb487d0e..309d254842cf2f85ab2d0ea7653b98d4132b7248 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 c33cb3dc942b713f993f7ae75f5bede82c5cacc9..e42aa797f08b88ca9f9b71a065e1dab90d4047cd 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 f1c01ac2910239206fc892516057ef4bf85bb0c3..e531a4eedfeee3fd046beb4c7df5e3cb03be0da8 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 1d123d2b53fdfb34923a8e8d20c253c5834c95e3..bc354a80c09963c703626512943e2382e64922ce 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 113b68099216b4aeac8af443d690e21cd1c15cb4..70fe81a89df958ab72b540924383a164a0a56c00 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 14f4de1a8180289db3f05ca5395c3a93d6df0296..c782a6329805713493f930681176d3e8a32d8c47 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 d9e11f93bf3a34c54560dc724d56ce71b85d8141..9209da9dde0da9738d662e7a8167ae2136f2d831 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 33f7bdb5857c8d97cef75cde5fdb69de33830771..6da1aa0706a1441ba227829ec529bd98089cf0a9 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 afb3f186b8843b96b4ad0214c18e40515a11b091..159b56a56ef49112fc5e58083c76a3066eb76958 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 c2e6484ef138f6e0c8d7548fd340a61028c85c81..572f121b1f4edaf29533eba3d3c0bd7c7a4e959b 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 d500a5771dbc5c05f5f03428b71f58e21b96530f..e148a7212073195976de970e2c60f6b3ce5ffe68 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 e7b001017b9a18dd5184f95604f14b6cfb7b6773..8154bbbb779247cbe1a92b7b6537b59bf4acdac9 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 9e7923192a49f0f01e6f7ffef375da1351938203..05477d24fd49c5359d9989062ad2bd4688d228c1 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 2e39bf1f74620f88cf5d03fce1a71ac0f1e107fb..c1925590a0e110e431a0434901349f47d27f1384 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 ecfa6f8805ce0ef050448e777e68364b7d50a32e..4c76cb794bfbb48ad0a5c4954cd85ee8324156ee 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 fc7738ffbfffeb1ffd17c7724426169b65531372..e7b4bc3820e337282fb08adc90ff005e368868ca 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 7ff814fd65d0826596261f76448911b4579efe2e..ae9e897c255ec04576d1c58b28fde673bdc4be55 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 9e56fc346ba4f72b53e0031167803165bf0dde1d..e6d005726aadea2875fca2e747cee73aaa9225db 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 7b48064364dc7896440ab70b6d61d498789a57ce..430b1f630fb4a71147992411b3ad0eb71e997ad6 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 02d57c0b4243ac8ab61e4db9a3eb3e6e90d66d82..a631d1c2fa148a7191ac775baab2f2c4a82fe12b 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 520a77a798e25482ee52852fa97d17edfc7e2191..2f61a47b4716947d331dca4a5e2ee2d311c05d15 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 2c83cca34b8698cc269a0feda4def2b5a5d00c9d..7981a2c7906e0522aa3a34c4cd9ba7f6c84637fc 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 a5d6891c9d4c3959fcb895d8dc1a2500a8eb6200..e1601d35dceddf133379a57155ca9472294b2eac 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 9dccd9546a17b829b0816866d627d9d25c7bd0c5..3b94352b0d03178b31cdf5d364beaffd062c0390 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 f55ce76b00edd4545fe826f6844b338acd1cc46d..af8b55fdd9d98008bfe040b895ae734bfafb088b 100644 (file)
   * of the GNU General Public License version 2, incorporated herein by reference.
   */
 
-/*
- * 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.
  */
index 73401b0f01517ca8bb533acdfae0b05d6a175a70..2024b26b99e6e2728945af0c553455cb1bdaef9a 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 3e7753b1071759f147851c69ed38e0317d13f994..a3e65d1bc19bbcddda71bd74f2ec707a6a0bf5f1 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 8454bf6caaa70136f6106869a30a8f61899c0002..52f26b9c69d245e9aa090e374964f04d5895f7b0 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 3ac9a45b20fae7da4de35a3a4ae8055f90ee2501..036adc4f8ba7e85dab072fb7595cbe8f57e1e8d5 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 0497dbdb8631fe379c7f952dc2c50ee7c21bd814..7f1ce9d4333e8fc440b957b532f96ca0318ed4d8 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 8a95d61a2f8ff0fa3b980990c13f2f32be00dd25..63f846d6f3a6dd87592db1ac4fd09e0a67a22f83 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 c8bc6da57a418b2b62fb18c9ccfa3c06dcea362c..7c2cf2e76300c4f7fce69777653da0742bfdb8d7 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 a6d3b55013a5106b379bd5bddf47b4e89f1ad3f4..2d1bba06a08512d5d0a5af5bb8283ee9f9493922 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 06998c2240d9f167096426a582ec588bebbce7fc..746456c34df8f8f79333ace24f67e4921131b2c3 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 9d496703c4650dec63a23689bfc44e814436ec50..7b321f7cf358d05b3656dfce2e918daa373ce39b 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 587869d86eeea1ea195137619db5ec316bd4f774..d57011028b7279ef576191c006fd392027c16802 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 21c3d0d227e62e9572cdcf56ae3c6527688974fa..eba0d9d2b7c53015bc96c4f909e6e728faf2e52e 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 8c9e874c9118c494a74a42979e45c1c8f68030c0..ad28e32943608af5351fc805fb10e5aa3254ed27 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 e7f5821b49429c3e05470a0c377d0aca788a87de..6a96cd9f2685c7d8d962ba7f9ef5de47c4896d23 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 b0501243b175f99090f2b7321cb15ba77be4b8bd..ffac50899454353b324d52a2593fbb281ab05d23 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 6358015f65260d8fc9921ab185d42e9e5aa82f2b..9d24f8a38ac525843772b41143db514a9f686ecc 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 930cef8367f2a2ffa983bf9c10fa28a56ec6377d..9da94ab7f05f87e24eec2816ca5094e894906d01 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 816a52bcea8f7adc71078a1a0bca50a18b40f29d..6d00df69c2e3e9f57f28af33a8af725aebb8bae9 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 faa83badf0a1b5e5897566b2be057583ca4d26a9..2643976a66775f559936b4fd0ce84672d96342d2 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 e533a663deda5ebc3fd00df476237d9dda5311ce..59fc15572395cc50a4e8f56b2643afd6800f43d1 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 e720369a3515595b1a35129b92be19f0a578325c..53f5246c40aa3bb7bc00eaf80e015a54a7718ec4 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);
        }
@@ -1894,7 +1885,10 @@ static char * __prism2_translate_scan(local_info_t *local,
                        iwe.u.qual.noise =
                                HFA384X_LEVEL_TO_dBm(le16_to_cpu(scan->anl));
                }
-               iwe.len = IW_EV_QUAL_LEN;
+               iwe.u.qual.updated = IW_QUAL_LEVEL_UPDATED
+                       | IW_QUAL_NOISE_UPDATED
+                       | IW_QUAL_QUAL_INVALID
+                       | IW_QUAL_DBM;
                current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
                                                  IW_EV_QUAL_LEN);
        }
@@ -1906,7 +1900,6 @@ static char * __prism2_translate_scan(local_info_t *local,
        else
                iwe.u.data.flags = IW_ENCODE_DISABLED;
        iwe.u.data.length = 0;
-       iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
        current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, "");
 
        /* TODO: add SuppRates into BSS table */
@@ -1930,7 +1923,7 @@ static char * __prism2_translate_scan(local_info_t *local,
        }
 
        /* TODO: add BeaconInt,resp_rate,atim into BSS table */
-       buf = kmalloc(MAX_WPA_IE_LEN * 2 + 30, GFP_KERNEL);
+       buf = kmalloc(MAX_WPA_IE_LEN * 2 + 30, GFP_ATOMIC);
        if (buf && scan) {
                memset(&iwe, 0, sizeof(iwe));
                iwe.cmd = IWEVCUSTOM;
index 025f8cdb55663758d5329163084965c0403ed0db..da0c80fb941cab99dac9d2c93cf0105010f90abd 100644 (file)
@@ -59,11 +59,13 @@ static struct pci_device_id prism2_pci_id_table[] __devinitdata = {
 static inline void hfa384x_outb_debug(struct net_device *dev, int a, u8 v)
 {
        struct hostap_interface *iface;
+       struct hostap_pci_priv *hw_priv;
        local_info_t *local;
        unsigned long flags;
 
        iface = netdev_priv(dev);
        local = iface->local;
+       hw_priv = local->hw_priv;
 
        spin_lock_irqsave(&local->lock, flags);
        prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTB, a, v);
@@ -74,12 +76,14 @@ static inline void hfa384x_outb_debug(struct net_device *dev, int a, u8 v)
 static inline u8 hfa384x_inb_debug(struct net_device *dev, int a)
 {
        struct hostap_interface *iface;
+       struct hostap_pci_priv *hw_priv;
        local_info_t *local;
        unsigned long flags;
        u8 v;
 
        iface = netdev_priv(dev);
        local = iface->local;
+       hw_priv = local->hw_priv;
 
        spin_lock_irqsave(&local->lock, flags);
        v = readb(hw_priv->mem_start + a);
@@ -91,11 +95,13 @@ static inline u8 hfa384x_inb_debug(struct net_device *dev, int a)
 static inline void hfa384x_outw_debug(struct net_device *dev, int a, u16 v)
 {
        struct hostap_interface *iface;
+       struct hostap_pci_priv *hw_priv;
        local_info_t *local;
        unsigned long flags;
 
        iface = netdev_priv(dev);
        local = iface->local;
+       hw_priv = local->hw_priv;
 
        spin_lock_irqsave(&local->lock, flags);
        prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTW, a, v);
@@ -106,12 +112,14 @@ static inline void hfa384x_outw_debug(struct net_device *dev, int a, u16 v)
 static inline u16 hfa384x_inw_debug(struct net_device *dev, int a)
 {
        struct hostap_interface *iface;
+       struct hostap_pci_priv *hw_priv;
        local_info_t *local;
        unsigned long flags;
        u16 v;
 
        iface = netdev_priv(dev);
        local = iface->local;
+       hw_priv = local->hw_priv;
 
        spin_lock_irqsave(&local->lock, flags);
        v = readw(hw_priv->mem_start + a);
@@ -277,8 +285,6 @@ static struct prism2_helper_functions prism2_pci_funcs =
 {
        .card_present   = NULL,
        .cor_sreset     = prism2_pci_cor_sreset,
-       .dev_open       = NULL,
-       .dev_close      = NULL,
        .genesis_reset  = prism2_pci_genesis_reset,
        .hw_type        = HOSTAP_HW_PCI,
 };
@@ -352,8 +358,6 @@ static int prism2_pci_probe(struct pci_dev *pdev,
        return hostap_hw_ready(dev);
 
  fail:
-       kfree(hw_priv);
-
        if (irq_registered && dev)
                free_irq(dev->irq, dev);
 
@@ -364,10 +368,8 @@ static int prism2_pci_probe(struct pci_dev *pdev,
 
  err_out_disable:
        pci_disable_device(pdev);
-       kfree(hw_priv);
-       if (local)
-               local->hw_priv = NULL;
        prism2_free_local_data(dev);
+       kfree(hw_priv);
 
        return -ENODEV;
 }
@@ -392,9 +394,8 @@ static void prism2_pci_remove(struct pci_dev *pdev)
                free_irq(dev->irq, dev);
 
        mem_start = hw_priv->mem_start;
-       kfree(hw_priv);
-       iface->local->hw_priv = NULL;
        prism2_free_local_data(dev);
+       kfree(hw_priv);
 
        iounmap(mem_start);
 
@@ -441,7 +442,7 @@ static int prism2_pci_resume(struct pci_dev *pdev)
 MODULE_DEVICE_TABLE(pci, prism2_pci_id_table);
 
 static struct pci_driver prism2_pci_drv_id = {
-       .name           = "prism2_pci",
+       .name           = "hostap_pci",
        .id_table       = prism2_pci_id_table,
        .probe          = prism2_pci_probe,
        .remove         = prism2_pci_remove,
index 474ef83d813e876cbe1fa026ac9d851f828475e7..78d67b408b2f9423080bd276ba4bfc78644164a7 100644 (file)
@@ -328,8 +328,6 @@ static struct prism2_helper_functions prism2_plx_funcs =
 {
        .card_present   = NULL,
        .cor_sreset     = prism2_plx_cor_sreset,
-       .dev_open       = NULL,
-       .dev_close      = NULL,
        .genesis_reset  = prism2_plx_genesis_reset,
        .hw_type        = HOSTAP_HW_PLX,
 };
@@ -570,10 +568,8 @@ static int prism2_plx_probe(struct pci_dev *pdev,
        return hostap_hw_ready(dev);
 
  fail:
-       kfree(hw_priv);
-       if (local)
-               local->hw_priv = NULL;
        prism2_free_local_data(dev);
+       kfree(hw_priv);
 
        if (irq_registered && dev)
                free_irq(dev->irq, dev);
@@ -606,9 +602,8 @@ static void prism2_plx_remove(struct pci_dev *pdev)
        if (dev->irq)
                free_irq(dev->irq, dev);
 
-       kfree(iface->local->hw_priv);
-       iface->local->hw_priv = NULL;
        prism2_free_local_data(dev);
+       kfree(hw_priv);
        pci_disable_device(pdev);
 }
 
@@ -616,7 +611,7 @@ static void prism2_plx_remove(struct pci_dev *pdev)
 MODULE_DEVICE_TABLE(pci, prism2_plx_id_table);
 
 static struct pci_driver prism2_plx_drv_id = {
-       .name           = "prism2_plx",
+       .name           = "hostap_plx",
        .id_table       = prism2_plx_id_table,
        .probe          = prism2_plx_probe,
        .remove         = prism2_plx_remove,
index cc061e1560d39c7150f4770f063f89207f752f14..cfd8015594921a849dd00215d4190ca381b8cd91 100644 (file)
@@ -552,8 +552,6 @@ struct prism2_helper_functions {
         * (hostap_{cs,plx,pci}.c */
        int (*card_present)(local_info_t *local);
        void (*cor_sreset)(local_info_t *local);
-       int (*dev_open)(local_info_t *local);
-       int (*dev_close)(local_info_t *local);
        void (*genesis_reset)(local_info_t *local, int hcr);
 
        /* the following functions are from hostap_hw.c, but they may have some
index 2414e6493aa5639ad88aaa829395976c404fa972..ad7f8cd76db9041376b19a024a74dc38ac5854b4 100644 (file)
@@ -800,8 +800,7 @@ static int ipw2100_hw_send_command(struct ipw2100_priv *priv,
         * doesn't seem to have as many firmware restart cycles...
         *
         * As a test, we're sticking in a 1/100s delay here */
-       set_current_state(TASK_UNINTERRUPTIBLE);
-       schedule_timeout(HZ / 100);
+       schedule_timeout_uninterruptible(msecs_to_jiffies(10));
 
        return 0;
 
@@ -1256,8 +1255,7 @@ static int ipw2100_start_adapter(struct ipw2100_priv *priv)
        IPW_DEBUG_FW("Waiting for f/w initialization to complete...\n");
        i = 5000;
        do {
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(40 * HZ / 1000);
+               schedule_timeout_uninterruptible(msecs_to_jiffies(40));
                /* Todo... wait for sync command ... */
 
                read_register(priv->net_dev, IPW_REG_INTA, &inta);
@@ -1411,8 +1409,7 @@ static int ipw2100_hw_phy_off(struct ipw2100_priv *priv)
                    (val2 & IPW2100_COMMAND_PHY_OFF))
                        return 0;
 
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(HW_PHY_OFF_LOOP_DELAY);
+               schedule_timeout_uninterruptible(HW_PHY_OFF_LOOP_DELAY);
        }
 
        return -EIO;
@@ -1466,7 +1463,7 @@ fail_up:
 
 static int ipw2100_hw_stop_adapter(struct ipw2100_priv *priv)
 {
-#define HW_POWER_DOWN_DELAY (HZ / 10)
+#define HW_POWER_DOWN_DELAY (msecs_to_jiffies(100))
 
        struct host_command cmd = {
                .host_command = HOST_PRE_POWER_DOWN,
@@ -1520,10 +1517,8 @@ static int ipw2100_hw_stop_adapter(struct ipw2100_priv *priv)
                        printk(KERN_WARNING DRV_NAME ": "
                               "%s: Power down command failed: Error %d\n",
                               priv->net_dev->name, err);
-               else {
-                       set_current_state(TASK_UNINTERRUPTIBLE);
-                       schedule_timeout(HW_POWER_DOWN_DELAY);
-               }
+               else
+                       schedule_timeout_uninterruptible(HW_POWER_DOWN_DELAY);
        }
 
        priv->status &= ~STATUS_ENABLED;
@@ -2953,7 +2948,7 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
        int next = txq->next;
         int i = 0;
        struct ipw2100_data_header *ipw_hdr;
-       struct ieee80211_hdr *hdr;
+       struct ieee80211_hdr_3addr *hdr;
 
        while (!list_empty(&priv->tx_pend_list)) {
                /* if there isn't enough space in TBD queue, then
@@ -2989,7 +2984,7 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
                packet->index = txq->next;
 
                ipw_hdr = packet->info.d_struct.data;
-               hdr = (struct ieee80211_hdr *)packet->info.d_struct.txb->
+               hdr = (struct ieee80211_hdr_3addr *)packet->info.d_struct.txb->
                        fragments[0]->data;
 
                if (priv->ieee->iw_mode == IW_MODE_INFRA) {
@@ -3274,7 +3269,8 @@ static irqreturn_t ipw2100_interrupt(int irq, void *data,
        return IRQ_NONE;
 }
 
-static int ipw2100_tx(struct ieee80211_txb *txb, struct net_device *dev)
+static int ipw2100_tx(struct ieee80211_txb *txb, struct net_device *dev,
+                     int pri)
 {
        struct ipw2100_priv *priv = ieee80211_priv(dev);
        struct list_head *element;
index 2a3cdbd50168aada6c620aac39eb6eb65b4992f0..c9e99ce15d66f45b107845baae368292f3b4f86d 100644 (file)
@@ -808,7 +808,7 @@ struct ipw2100_priv {
 struct ipw2100_rx {
        union {
                unsigned char payload[IPW_RX_NIC_BUFFER_LENGTH];
-               struct ieee80211_hdr header;
+               struct ieee80211_hdr_4addr header;
                u32 status;
                struct ipw2100_notification notification;
                struct ipw2100_cmd_header command;
index b7f275c00de3cecc592368e90183bb96a3067563..7ea9bd58f65f8711e184daccf5382de827dadb42 100644 (file)
@@ -4904,7 +4904,7 @@ static void ipw_rx(struct ipw_priv *priv)
 {
        struct ipw_rx_mem_buffer *rxb;
        struct ipw_rx_packet *pkt;
-       struct ieee80211_hdr *header;
+       struct ieee80211_hdr_4addr *header;
        u32 r, w, i;
        u8 network_packet;
 
@@ -4967,8 +4967,9 @@ static void ipw_rx(struct ipw_priv *priv)
 #endif
 
                                header =
-                                   (struct ieee80211_hdr *)(rxb->skb->data +
-                                                            IPW_RX_FRAME_SIZE);
+                                   (struct ieee80211_hdr_4addr *)(rxb->skb->
+                                                                  data +
+                                                                  IPW_RX_FRAME_SIZE);
                                /* TODO: Check Ad-Hoc dest/source and make sure
                                 * that we are actually parsing these packets
                                 * correctly -- we should probably use the
@@ -6010,12 +6011,12 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev,
        }
 
        if (priv->adapter == IPW_2915ABG) {
-               priv->ieee->abg_ture = 1;
+               priv->ieee->abg_true = 1;
                if (mode & IEEE_A) {
                        band |= IEEE80211_52GHZ_BAND;
                        modulation |= IEEE80211_OFDM_MODULATION;
                } else
-                       priv->ieee->abg_ture = 0;
+                       priv->ieee->abg_true = 0;
        } else {
                if (mode & IEEE_A) {
                        IPW_WARNING("Attempt to set 2200BG into "
@@ -6023,20 +6024,20 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev,
                        return -EINVAL;
                }
 
-               priv->ieee->abg_ture = 0;
+               priv->ieee->abg_true = 0;
        }
 
        if (mode & IEEE_B) {
                band |= IEEE80211_24GHZ_BAND;
                modulation |= IEEE80211_CCK_MODULATION;
        } else
-               priv->ieee->abg_ture = 0;
+               priv->ieee->abg_true = 0;
 
        if (mode & IEEE_G) {
                band |= IEEE80211_24GHZ_BAND;
                modulation |= IEEE80211_OFDM_MODULATION;
        } else
-               priv->ieee->abg_ture = 0;
+               priv->ieee->abg_true = 0;
 
        priv->ieee->mode = mode;
        priv->ieee->freq_band = band;
@@ -6325,7 +6326,7 @@ we need to heavily modify the ieee80211_skb_to_txb.
 
 static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
 {
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)
+       struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *)
            txb->fragments[0]->data;
        int i = 0;
        struct tfd_frame *tfd;
@@ -6448,7 +6449,7 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
 }
 
 static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb,
-                                  struct net_device *dev)
+                                  struct net_device *dev, int pri)
 {
        struct ipw_priv *priv = ieee80211_priv(dev);
        unsigned long flags;
@@ -7108,7 +7109,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                printk(KERN_INFO DRV_NAME
                       ": Detected Intel PRO/Wireless 2915ABG Network "
                       "Connection\n");
-               priv->ieee->abg_ture = 1;
+               priv->ieee->abg_true = 1;
                band = IEEE80211_52GHZ_BAND | IEEE80211_24GHZ_BAND;
                modulation = IEEE80211_OFDM_MODULATION |
                    IEEE80211_CCK_MODULATION;
@@ -7124,7 +7125,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                               ": Detected Intel PRO/Wireless 2200BG Network "
                               "Connection\n");
 
-               priv->ieee->abg_ture = 0;
+               priv->ieee->abg_true = 0;
                band = IEEE80211_24GHZ_BAND;
                modulation = IEEE80211_OFDM_MODULATION |
                    IEEE80211_CCK_MODULATION;
index 5b00882133f919740cbe7e098a500e270ff8a5ff..e9cf32bf3e31741936882932b24ce289bf28f982 100644 (file)
@@ -1654,12 +1654,12 @@ static const long ipw_frequencies[] = {
 
 #define IPW_MAX_CONFIG_RETRIES 10
 
-static inline u32 frame_hdr_len(struct ieee80211_hdr *hdr)
+static inline u32 frame_hdr_len(struct ieee80211_hdr_4addr *hdr)
 {
        u32 retval;
        u16 fc;
 
-       retval = sizeof(struct ieee80211_hdr);
+       retval = sizeof(struct ieee80211_hdr_3addr);
        fc = le16_to_cpu(hdr->frame_ctl);
 
        /*
index ca6c03c89926ca89605c5b881a2ccabc0cb81411..92793b958e327d0777ea76291e614460bbe5bb40 100644 (file)
@@ -57,9 +57,7 @@
 #include <linux/bitops.h>
 #ifdef CONFIG_NET_RADIO
 #include <linux/wireless.h>
-#if WIRELESS_EXT > 12
 #include <net/iw_handler.h>
-#endif /* WIRELESS_EXT > 12 */
 #endif
 
 #include <pcmcia/cs_types.h>
@@ -225,10 +223,7 @@ static void update_stats(struct net_device *dev);
 static struct net_device_stats *netwave_get_stats(struct net_device *dev);
 
 /* Wireless extensions */
-#ifdef WIRELESS_EXT
 static struct iw_statistics* netwave_get_wireless_stats(struct net_device *dev);
-#endif
-static int netwave_ioctl(struct net_device *, struct ifreq *, int);
 
 static void set_multicast_list(struct net_device *dev);
 
@@ -260,26 +255,7 @@ static dev_link_t *dev_list;
    because they generally can't be allocated dynamically.
 */
 
-#if WIRELESS_EXT <= 12
-/* Wireless extensions backward compatibility */
-
-/* Part of iw_handler prototype we need */
-struct iw_request_info
-{
-       __u16           cmd;            /* Wireless Extension command */
-       __u16           flags;          /* More to come ;-) */
-};
-
-/* Wireless Extension Backward compatibility - Jean II
- * If the new wireless device private ioctl range is not defined,
- * default to standard device private ioctl range */
-#ifndef SIOCIWFIRSTPRIV
-#define SIOCIWFIRSTPRIV        SIOCDEVPRIVATE
-#endif /* SIOCIWFIRSTPRIV */
-
-#else  /* WIRELESS_EXT <= 12 */
 static const struct iw_handler_def     netwave_handler_def;
-#endif /* WIRELESS_EXT <= 12 */
 
 #define SIOCGIPSNAP    SIOCIWFIRSTPRIV + 1     /* Site Survey Snapshot */
 
@@ -319,9 +295,7 @@ typedef struct netwave_private {
     struct timer_list      watchdog;   /* To avoid blocking state */
     struct site_survey     nss;
     struct net_device_stats stats;
-#ifdef WIRELESS_EXT
     struct iw_statistics   iw_stats;    /* Wireless stats */
-#endif
 } netwave_private;
 
 #ifdef NETWAVE_STATS
@@ -353,7 +327,6 @@ static inline void wait_WOC(unsigned int iobase)
     while ((inb(iobase + NETWAVE_REG_ASR) & 0x8) != 0x8) ; 
 }
 
-#ifdef WIRELESS_EXT
 static void netwave_snapshot(netwave_private *priv, u_char __iomem *ramBase, 
                             kio_addr_t iobase) {
     u_short resultBuffer;
@@ -376,9 +349,7 @@ static void netwave_snapshot(netwave_private *priv, u_char __iomem *ramBase,
                      sizeof(struct site_survey)); 
     } 
 }
-#endif
 
-#ifdef WIRELESS_EXT
 /*
  * Function netwave_get_wireless_stats (dev)
  *
@@ -411,7 +382,6 @@ static struct iw_statistics *netwave_get_wireless_stats(struct net_device *dev)
     
     return &priv->iw_stats;
 }
-#endif
 
 /*
  * Function netwave_attach (void)
@@ -471,13 +441,7 @@ static dev_link_t *netwave_attach(void)
     dev->get_stats  = &netwave_get_stats;
     dev->set_multicast_list = &set_multicast_list;
     /* wireless extensions */
-#if WIRELESS_EXT <= 16
-    dev->get_wireless_stats = &netwave_get_wireless_stats;
-#endif /* WIRELESS_EXT <= 16 */
-#if WIRELESS_EXT > 12
     dev->wireless_handlers = (struct iw_handler_def *)&netwave_handler_def;
-#endif /* WIRELESS_EXT > 12 */
-    dev->do_ioctl = &netwave_ioctl;
 
     dev->tx_timeout = &netwave_watchdog;
     dev->watchdog_timeo = TX_TIMEOUT;
@@ -576,13 +540,8 @@ static int netwave_set_nwid(struct net_device *dev,
        /* Disable interrupts & save flags */
        spin_lock_irqsave(&priv->spinlock, flags);
 
-#if WIRELESS_EXT > 8
        if(!wrqu->nwid.disabled) {
            domain = wrqu->nwid.value;
-#else  /* WIRELESS_EXT > 8 */
-       if(wrqu->nwid.on) {
-           domain = wrqu->nwid.nwid;
-#endif /* WIRELESS_EXT > 8 */
            printk( KERN_DEBUG "Setting domain to 0x%x%02x\n", 
                    (domain >> 8) & 0x01, domain & 0xff);
            wait_WOC(iobase);
@@ -606,15 +565,9 @@ static int netwave_get_nwid(struct net_device *dev,
                            union iwreq_data *wrqu,
                            char *extra)
 {
-#if WIRELESS_EXT > 8
        wrqu->nwid.value = domain;
        wrqu->nwid.disabled = 0;
        wrqu->nwid.fixed = 1;
-#else  /* WIRELESS_EXT > 8 */
-       wrqu->nwid.nwid = domain;
-       wrqu->nwid.on = 1;
-#endif /* WIRELESS_EXT > 8 */
-
        return 0;
 }
 
@@ -657,17 +610,11 @@ static int netwave_get_scramble(struct net_device *dev,
 {
        key[1] = scramble_key & 0xff;
        key[0] = (scramble_key>>8) & 0xff;
-#if WIRELESS_EXT > 8
        wrqu->encoding.flags = IW_ENCODE_ENABLED;
        wrqu->encoding.length = 2;
-#else /* WIRELESS_EXT > 8 */
-       wrqu->encoding.method = 1;
-#endif /* WIRELESS_EXT > 8 */
-
        return 0;
 }
 
-#if WIRELESS_EXT > 8
 /*
  * Wireless Handler : get mode
  */
@@ -683,7 +630,6 @@ static int netwave_get_mode(struct net_device *dev,
 
        return 0;
 }
-#endif /* WIRELESS_EXT > 8 */
 
 /*
  * Wireless Handler : get range info
@@ -702,11 +648,9 @@ static int netwave_get_range(struct net_device *dev,
        /* Set all the info we don't care or don't know about to zero */
        memset(range, 0, sizeof(struct iw_range));
 
-#if WIRELESS_EXT > 10
        /* Set the Wireless Extension versions */
        range->we_version_compiled = WIRELESS_EXT;
        range->we_version_source = 9;   /* Nothing for us in v10 and v11 */
-#endif /* WIRELESS_EXT > 10 */
                   
        /* Set information in the range struct */
        range->throughput = 450 * 1000; /* don't argue on this ! */
@@ -720,16 +664,12 @@ static int netwave_get_range(struct net_device *dev,
        range->max_qual.level = 255;
        range->max_qual.noise = 0;
                   
-#if WIRELESS_EXT > 7
        range->num_bitrates = 1;
        range->bitrate[0] = 1000000;    /* 1 Mb/s */
-#endif /* WIRELESS_EXT > 7 */
 
-#if WIRELESS_EXT > 8
        range->encoding_size[0] = 2;            /* 16 bits scrambling */
        range->num_encoding_sizes = 1;
        range->max_encoding_tokens = 1; /* Only one key possible */
-#endif /* WIRELESS_EXT > 8 */
 
        return ret;
 }
@@ -775,8 +715,6 @@ static const struct iw_priv_args netwave_private_args[] = {
     "getsitesurvey" },
 };
 
-#if WIRELESS_EXT > 12
-
 static const iw_handler                netwave_handler[] =
 {
        NULL,                           /* SIOCSIWNAME */
@@ -839,131 +777,8 @@ static const struct iw_handler_def        netwave_handler_def =
        .standard       = (iw_handler *) netwave_handler,
        .private        = (iw_handler *) netwave_private_handler,
        .private_args   = (struct iw_priv_args *) netwave_private_args,
-#if WIRELESS_EXT > 16
        .get_wireless_stats = netwave_get_wireless_stats,
-#endif /* WIRELESS_EXT > 16 */
 };
-#endif /* WIRELESS_EXT > 12 */
-
-/*
- * Function netwave_ioctl (dev, rq, cmd)
- *
- *     Perform ioctl : config & info stuff
- *     This is the stuff that are treated the wireless extensions (iwconfig)
- *
- */
-static int netwave_ioctl(struct net_device *dev, /* ioctl device */
-                        struct ifreq *rq,       /* Data passed */
-                        int    cmd)         /* Ioctl number */
-{
-    int                        ret = 0;
-#ifdef WIRELESS_EXT
-#if WIRELESS_EXT <= 12
-    struct iwreq *wrq = (struct iwreq *) rq;
-#endif
-#endif
-       
-    DEBUG(0, "%s: ->netwave_ioctl(cmd=0x%X)\n", dev->name, cmd);
-       
-    /* Look what is the request */
-    switch(cmd) {
-       /* --------------- WIRELESS EXTENSIONS --------------- */
-#ifdef WIRELESS_EXT
-#if WIRELESS_EXT <= 12
-    case SIOCGIWNAME:
-       netwave_get_name(dev, NULL, &(wrq->u), NULL);
-       break;
-    case SIOCSIWNWID:
-       ret = netwave_set_nwid(dev, NULL, &(wrq->u), NULL);
-       break;
-    case SIOCGIWNWID:
-       ret = netwave_get_nwid(dev, NULL, &(wrq->u), NULL);
-       break;
-#if WIRELESS_EXT > 8   /* Note : The API did change... */
-    case SIOCGIWENCODE:
-       /* Get scramble key */
-       if(wrq->u.encoding.pointer != (caddr_t) 0)
-         {
-           char        key[2];
-           ret = netwave_get_scramble(dev, NULL, &(wrq->u), key);
-           if(copy_to_user(wrq->u.encoding.pointer, key, 2))
-             ret = -EFAULT;
-         }
-       break;
-    case SIOCSIWENCODE:
-       /* Set  scramble key */
-       if(wrq->u.encoding.pointer != (caddr_t) 0)
-         {
-           char        key[2];
-           if(copy_from_user(key, wrq->u.encoding.pointer, 2))
-             {
-               ret = -EFAULT;
-               break;
-             }
-           ret = netwave_set_scramble(dev, NULL, &(wrq->u), key);
-         }
-       break;
-    case SIOCGIWMODE:
-       /* Mode of operation */
-       ret = netwave_get_mode(dev, NULL, &(wrq->u), NULL);
-       break;
-#else /* WIRELESS_EXT > 8 */
-    case SIOCGIWENCODE:
-       /* Get scramble key */
-       ret = netwave_get_scramble(dev, NULL, &(wrq->u),
-                                  (char *) &wrq->u.encoding.code);
-       break;
-    case SIOCSIWENCODE:
-       /* Set  scramble key */
-       ret = netwave_set_scramble(dev, NULL, &(wrq->u),
-                                  (char *) &wrq->u.encoding.code);
-       break;
-#endif /* WIRELESS_EXT > 8 */
-   case SIOCGIWRANGE:
-       /* Basic checking... */
-       if(wrq->u.data.pointer != (caddr_t) 0) {
-           struct iw_range range;
-          ret = netwave_get_range(dev, NULL, &(wrq->u), (char *) &range);
-          if (copy_to_user(wrq->u.data.pointer, &range,
-                           sizeof(struct iw_range)))
-              ret = -EFAULT;
-       }
-       break;
-    case SIOCGIWPRIV:
-       /* Basic checking... */
-       if(wrq->u.data.pointer != (caddr_t) 0) {
-           /* Set the number of ioctl available */
-           wrq->u.data.length = sizeof(netwave_private_args) / sizeof(netwave_private_args[0]);
-                       
-           /* Copy structure to the user buffer */
-           if(copy_to_user(wrq->u.data.pointer,
-                           (u_char *) netwave_private_args,
-                           sizeof(netwave_private_args)))
-             ret = -EFAULT;
-       } 
-       break;
-    case SIOCGIPSNAP:
-       if(wrq->u.data.pointer != (caddr_t) 0) {
-           char buffer[sizeof( struct site_survey)];
-           ret = netwave_get_snap(dev, NULL, &(wrq->u), buffer);
-           /* Copy structure to the user buffer */
-           if(copy_to_user(wrq->u.data.pointer, 
-                           buffer,
-                           sizeof( struct site_survey)))
-             {
-               printk(KERN_DEBUG "Bad buffer!\n");
-               break;
-             }
-       }
-       break;
-#endif /* WIRELESS_EXT <= 12 */
-#endif /* WIRELESS_EXT */
-    default:
-       ret = -EOPNOTSUPP;
-    }
-       
-    return ret;
-}
 
 /*
  * Function netwave_pcmcia_config (link)
index 6deb7cc810cca9574356a0f84172e2057dce3869..78afbc7f08be76d0cb7ca6ca8754c9fa41e5a869 100644 (file)
 #define DRIVER_NAME "orinoco"
 
 #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/ethtool.h>
 #include <linux/wireless.h>
 #include <net/iw_handler.h>
 #include <net/ieee80211.h>
 
-#include <net/ieee80211.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/system.h>
-
-#include "hermes.h"
 #include "hermes_rid.h"
 #include "orinoco.h"
 
@@ -137,7 +123,7 @@ MODULE_PARM_DESC(force_monitor, "Allow monitor mode for all firmware versions");
 
 /* We do this this way to avoid ifdefs in the actual code */
 #ifdef WIRELESS_SPY
-#define SPY_NUMBER(priv)       (priv->spy_number)
+#define SPY_NUMBER(priv)       (priv->spy_data.spy_number)
 #else
 #define SPY_NUMBER(priv)       0
 #endif /* WIRELESS_SPY */
@@ -216,31 +202,32 @@ static struct {
 /********************************************************************/
 
 /* Used in Event handling.
- * We avoid nested structres as they break on ARM -- Moustafa */
+ * We avoid nested structures as they break on ARM -- Moustafa */
 struct hermes_tx_descriptor_802_11 {
        /* 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;
 
-       /* ieee802_11_hdr */
-       u16 frame_ctl;
-       u16 duration_id;
+       /* ieee80211_hdr */
+       __le16 frame_ctl;
+       __le16 duration_id;
        u8 addr1[ETH_ALEN];
        u8 addr2[ETH_ALEN];
        u8 addr3[ETH_ALEN];
-       u16 seq_ctl;
+       __le16 seq_ctl;
        u8 addr4[ETH_ALEN];
-       u16 data_len;
+
+       __le16 data_len;
 
        /* ethhdr */
-       unsigned char   h_dest[ETH_ALEN];       /* destination eth addr */
-       unsigned char   h_source[ETH_ALEN];     /* source ether addr    */
-       unsigned short  h_proto;                /* packet type ID field */
+       u8 h_dest[ETH_ALEN];    /* destination eth addr */
+       u8 h_source[ETH_ALEN];  /* source ether addr    */
+       __be16 h_proto;         /* packet type ID field */
 
        /* p8022_hdr */
        u8 dsap;
@@ -248,31 +235,31 @@ struct hermes_tx_descriptor_802_11 {
        u8 ctrl;
        u8 oui[3];
 
-       u16 ethertype;
+       __be16 ethertype;
 } __attribute__ ((packed));
 
 /* Rx frame header except compatibility 802.3 header */
 struct hermes_rx_descriptor {
        /* Control */
-       u16 status;
-       u32 time;
+       __le16 status;
+       __le32 time;
        u8 silence;
        u8 signal;
        u8 rate;
        u8 rxflow;
-       u32 reserved;
+       __le32 reserved;
 
        /* 802.11 header */
-       u16 frame_ctl;
-       u16 duration_id;
+       __le16 frame_ctl;
+       __le16 duration_id;
        u8 addr1[ETH_ALEN];
        u8 addr2[ETH_ALEN];
        u8 addr3[ETH_ALEN];
-       u16 seq_ctl;
+       __le16 seq_ctl;
        u8 addr4[ETH_ALEN];
 
        /* Data length */
-       u16 data_len;
+       __le16 data_len;
 } __attribute__ ((packed));
 
 /********************************************************************/
@@ -396,14 +383,14 @@ static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
                /* If a spy address is defined, we report stats of the
                 * first spy address - Jean II */
                if (SPY_NUMBER(priv)) {
-                       wstats->qual.qual = priv->spy_stat[0].qual;
-                       wstats->qual.level = priv->spy_stat[0].level;
-                       wstats->qual.noise = priv->spy_stat[0].noise;
-                       wstats->qual.updated = priv->spy_stat[0].updated;
+                       wstats->qual.qual = priv->spy_data.spy_stat[0].qual;
+                       wstats->qual.level = priv->spy_data.spy_stat[0].level;
+                       wstats->qual.noise = priv->spy_data.spy_stat[0].noise;
+                       wstats->qual.updated = priv->spy_data.spy_stat[0].updated;
                }
        } else {
                struct {
-                       u16 qual, signal, noise;
+                       __le16 qual, signal, noise;
                } __attribute__ ((packed)) cq;
 
                err = HERMES_READ_RECORD(hw, USER_BAP,
@@ -629,16 +616,17 @@ static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
        struct orinoco_private *priv = netdev_priv(dev);
        struct net_device_stats *stats = &priv->stats;
        u16 fid = hermes_read_regn(hw, TXCOMPLFID);
+       u16 status;
        struct hermes_tx_descriptor_802_11 hdr;
        int err = 0;
 
        if (fid == DUMMY_FID)
                return; /* Nothing's really happened */
 
-       /* Read the frame header */
+       /* Read part of the frame header - we need status and addr1 */
        err = hermes_bap_pread(hw, IRQ_BAP, &hdr,
-                              sizeof(struct hermes_tx_descriptor) +
-                              sizeof(struct ieee80211_hdr),
+                              offsetof(struct hermes_tx_descriptor_802_11,
+                                       addr2),
                               fid, 0);
 
        hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
@@ -658,8 +646,8 @@ static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
         * exceeded, because that's the only status that really mean
         * that this particular node went away.
         * Other errors means that *we* screwed up. - Jean II */
-       hdr.status = le16_to_cpu(hdr.status);
-       if (hdr.status & (HERMES_TXSTAT_RETRYERR | HERMES_TXSTAT_AGEDERR)) {
+       status = le16_to_cpu(hdr.status);
+       if (status & (HERMES_TXSTAT_RETRYERR | HERMES_TXSTAT_AGEDERR)) {
                union iwreq_data        wrqu;
 
                /* Copy 802.11 dest address.
@@ -718,18 +706,13 @@ static inline int is_ethersnap(void *_hdr)
 static inline void orinoco_spy_gather(struct net_device *dev, u_char *mac,
                                      int level, int noise)
 {
-       struct orinoco_private *priv = netdev_priv(dev);
-       int i;
-
-       /* Gather wireless spy statistics: for each packet, compare the
-        * source address with out list, and if match, get the stats... */
-       for (i = 0; i < priv->spy_number; i++)
-               if (!memcmp(mac, priv->spy_address[i], ETH_ALEN)) {
-                       priv->spy_stat[i].level = level - 0x95;
-                       priv->spy_stat[i].noise = noise - 0x95;
-                       priv->spy_stat[i].qual = (level > noise) ? (level - noise) : 0;
-                       priv->spy_stat[i].updated = 7;
-               }
+       struct iw_quality wstats;
+       wstats.level = level - 0x95;
+       wstats.noise = noise - 0x95;
+       wstats.qual = (level > noise) ? (level - noise) : 0;
+       wstats.updated = 7;
+       /* Update spy records */
+       wireless_spy_update(dev, mac, &wstats);
 }
 
 static void orinoco_stat_gather(struct net_device *dev,
@@ -1050,7 +1033,7 @@ static void orinoco_join_ap(struct net_device *dev)
        unsigned long flags;
        struct join_req {
                u8 bssid[ETH_ALEN];
-               u16 channel;
+               __le16 channel;
        } __attribute__ ((packed)) req;
        const int atom_len = offsetof(struct prism2_scan_apinfo, atim);
        struct prism2_scan_apinfo *atom = NULL;
@@ -1065,7 +1048,7 @@ static void orinoco_join_ap(struct net_device *dev)
                return;
 
        if (orinoco_lock(priv, &flags) != 0)
-               goto out;
+               goto fail_lock;
 
        /* Sanity checks in case user changed something in the meantime */
        if (! priv->bssid_fixed)
@@ -1110,8 +1093,10 @@ static void orinoco_join_ap(struct net_device *dev)
                printk(KERN_ERR "%s: Error issuing join request\n", dev->name);
 
  out:
-       kfree(buf);
        orinoco_unlock(priv, &flags);
+
+ fail_lock:
+       kfree(buf);
 }
 
 /* Send new BSSID to userspace */
@@ -1129,12 +1114,14 @@ static void orinoco_send_wevents(struct net_device *dev)
        err = hermes_read_ltv(hw, IRQ_BAP, HERMES_RID_CURRENTBSSID,
                              ETH_ALEN, NULL, wrqu.ap_addr.sa_data);
        if (err != 0)
-               return;
+               goto out;
 
        wrqu.ap_addr.sa_family = ARPHRD_ETHER;
 
        /* Send event to user space */
        wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
+
+ out:
        orinoco_unlock(priv, &flags);
 }
 
@@ -1143,8 +1130,8 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
        struct orinoco_private *priv = netdev_priv(dev);
        u16 infofid;
        struct {
-               u16 len;
-               u16 type;
+               __le16 len;
+               __le16 type;
        } __attribute__ ((packed)) info;
        int len, type;
        int err;
@@ -2459,6 +2446,10 @@ struct net_device *alloc_orinocodev(int sizeof_card,
        dev->get_stats = orinoco_get_stats;
        dev->ethtool_ops = &orinoco_ethtool_ops;
        dev->wireless_handlers = (struct iw_handler_def *)&orinoco_handler_def;
+#ifdef WIRELESS_SPY
+       priv->wireless_data.spy_data = &priv->spy_data;
+       dev->wireless_data = &priv->wireless_data;
+#endif
        dev->change_mtu = orinoco_change_mtu;
        dev->set_multicast_list = orinoco_set_multicast_list;
        /* we use the default eth_mac_addr for setting the MAC addr */
@@ -2830,7 +2821,7 @@ static int orinoco_ioctl_getiwrange(struct net_device *dev,
                }
        }
 
-       if ((priv->iw_mode == IW_MODE_ADHOC) && (priv->spy_number == 0)){
+       if ((priv->iw_mode == IW_MODE_ADHOC) && (!SPY_NUMBER(priv))){
                /* Quality stats meaningless in ad-hoc mode */
        } else {
                range->max_qual.qual = 0x8b - 0x2f;
@@ -2877,6 +2868,14 @@ static int orinoco_ioctl_getiwrange(struct net_device *dev,
        range->min_r_time = 0;
        range->max_r_time = 65535 * 1000;       /* ??? */
 
+       /* Event capability (kernel) */
+       IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
+       /* Event capability (driver) */
+       IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWTHRSPY);
+       IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
+       IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
+       IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP);
+
        TRACE_EXIT(dev->name);
 
        return 0;
@@ -3836,92 +3835,6 @@ static int orinoco_ioctl_getrid(struct net_device *dev,
        return err;
 }
 
-/* Spy is used for link quality/strength measurements in Ad-Hoc mode
- * Jean II */
-static int orinoco_ioctl_setspy(struct net_device *dev,
-                               struct iw_request_info *info,
-                               struct iw_point *srq,
-                               char *extra)
-
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       struct sockaddr *address = (struct sockaddr *) extra;
-       int number = srq->length;
-       int i;
-       unsigned long flags;
-
-       /* Make sure nobody mess with the structure while we do */
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-
-       /* orinoco_lock() doesn't disable interrupts, so make sure the
-        * interrupt rx path don't get confused while we copy */
-       priv->spy_number = 0;
-
-       if (number > 0) {
-               /* Extract the addresses */
-               for (i = 0; i < number; i++)
-                       memcpy(priv->spy_address[i], address[i].sa_data,
-                              ETH_ALEN);
-               /* Reset stats */
-               memset(priv->spy_stat, 0,
-                      sizeof(struct iw_quality) * IW_MAX_SPY);
-               /* Set number of addresses */
-               priv->spy_number = number;
-       }
-
-       /* Now, let the others play */
-       orinoco_unlock(priv, &flags);
-
-       /* Do NOT call commit handler */
-       return 0;
-}
-
-static int orinoco_ioctl_getspy(struct net_device *dev,
-                               struct iw_request_info *info,
-                               struct iw_point *srq,
-                               char *extra)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       struct sockaddr *address = (struct sockaddr *) extra;
-       int number;
-       int i;
-       unsigned long flags;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-
-       number = priv->spy_number;
-       /* Create address struct */
-       for (i = 0; i < number; i++) {
-               memcpy(address[i].sa_data, priv->spy_address[i], ETH_ALEN);
-               address[i].sa_family = AF_UNIX;
-       }
-       if (number > 0) {
-               /* Create address struct */
-               for (i = 0; i < number; i++) {
-                       memcpy(address[i].sa_data, priv->spy_address[i],
-                              ETH_ALEN);
-                       address[i].sa_family = AF_UNIX;
-               }
-               /* Copy stats */
-               /* In theory, we should disable irqs while copying the stats
-                * because the rx path might update it in the middle...
-                * Bah, who care ? - Jean II */
-               memcpy(extra  + (sizeof(struct sockaddr) * number),
-                      priv->spy_stat, sizeof(struct iw_quality) * number);
-       }
-       /* Reset updated flags. */
-       for (i = 0; i < number; i++)
-               priv->spy_stat[i].updated = 0;
-
-       orinoco_unlock(priv, &flags);
-
-       srq->length = number;
-
-       return 0;
-}
-
 /* Trigger a scan (look for other cells in the vicinity */
 static int orinoco_ioctl_setscan(struct net_device *dev,
                                 struct iw_request_info *info,
@@ -3994,7 +3907,7 @@ static int orinoco_ioctl_setscan(struct net_device *dev,
                                                   HERMES_HOSTSCAN_SYMBOL_BCAST);
                        break;
                case FIRMWARE_TYPE_INTERSIL: {
-                       u16 req[3];
+                       __le16 req[3];
 
                        req[0] = cpu_to_le16(0x3fff);   /* All channels */
                        req[1] = cpu_to_le16(0x0001);   /* rate 1 Mbps */
@@ -4068,7 +3981,7 @@ static inline int orinoco_translate_scan(struct net_device *dev,
        case FIRMWARE_TYPE_INTERSIL:
                offset = 4;
                if (priv->has_hostscan) {
-                       atom_len = le16_to_cpup((u16 *)scan);
+                       atom_len = le16_to_cpup((__le16 *)scan);
                        /* Sanity check for atom_len */
                        if (atom_len < sizeof(struct prism2_scan_apinfo)) {
                                printk(KERN_ERR "%s: Invalid atom_len in scan data: %d\n",
@@ -4352,8 +4265,10 @@ static const iw_handler  orinoco_handler[] = {
        [SIOCSIWSENS  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setsens,
        [SIOCGIWSENS  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getsens,
        [SIOCGIWRANGE -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getiwrange,
-       [SIOCSIWSPY   -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setspy,
-       [SIOCGIWSPY   -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getspy,
+       [SIOCSIWSPY   -SIOCIWFIRST] = (iw_handler) iw_handler_set_spy,
+       [SIOCGIWSPY   -SIOCIWFIRST] = (iw_handler) iw_handler_get_spy,
+       [SIOCSIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_set_thrspy,
+       [SIOCGIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_get_thrspy,
        [SIOCSIWAP    -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setwap,
        [SIOCGIWAP    -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getwap,
        [SIOCSIWSCAN  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setscan,
index 2f213a7103fe70cee7ca41ca66f0994928471f85..7a17bb31fc896da55e1943c021aaa2ad7c125c51 100644 (file)
@@ -7,12 +7,11 @@
 #ifndef _ORINOCO_H
 #define _ORINOCO_H
 
-#define DRIVER_VERSION "0.15rc2"
+#define DRIVER_VERSION "0.15rc3"
 
-#include <linux/types.h>
-#include <linux/spinlock.h>
 #include <linux/netdevice.h>
 #include <linux/wireless.h>
+#include <net/iw_handler.h>
 #include <linux/version.h>
 
 #include "hermes.h"
@@ -28,7 +27,7 @@
 #define ORINOCO_MAX_KEYS       4
 
 struct orinoco_key {
-       u16 len;        /* always stored as little-endian */
+       __le16 len;     /* always stored as little-endian */
        char data[ORINOCO_MAX_KEY_SIZE];
 } __attribute__ ((packed));
 
@@ -36,14 +35,14 @@ struct header_struct {
        /* 802.3 */
        u8 dest[ETH_ALEN];
        u8 src[ETH_ALEN];
-       u16 len;
+       __be16 len;
        /* 802.2 */
        u8 dsap;
        u8 ssap;
        u8 ctrl;
        /* SNAP */
        u8 oui[3];
-       u16 ethertype;
+       unsigned short ethertype;
 } __attribute__ ((packed));
 
 typedef enum {
@@ -112,9 +111,8 @@ struct orinoco_private {
        u16 pm_on, pm_mcast, pm_period, pm_timeout;
        u16 preamble;
 #ifdef WIRELESS_SPY
-       int                     spy_number;
-       u_char                  spy_address[IW_MAX_SPY][ETH_ALEN];
-       struct iw_quality       spy_stat[IW_MAX_SPY];
+       struct iw_spy_data spy_data; /* iwspy support */
+       struct iw_public_data   wireless_data;
 #endif
 
        /* Configuration dependent variables */
index bedd7f9f23e48cd37201e79f6a3b4c3b35697bc6..dc1128a009719811c39a426ef132a8dd88c94ca7 100644 (file)
 #define PFX DRIVER_NAME ": "
 
 #include <linux/config.h>
-#ifdef  __IN_PCMCIA_PACKAGE__
-#include <pcmcia/k_compat.h>
-#endif /* __IN_PCMCIA_PACKAGE__ */
-
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/etherdevice.h>
-#include <linux/wireless.h>
-
+#include <linux/delay.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
 #include <pcmcia/ds.h>
 
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/system.h>
-
 #include "orinoco.h"
 
 /********************************************************************/
@@ -97,17 +80,8 @@ static dev_link_t *dev_list; /* = NULL */
 /* Function prototypes                                             */
 /********************************************************************/
 
-/* device methods */
-static int orinoco_cs_hard_reset(struct orinoco_private *priv);
-
-/* PCMCIA gumpf */
-static void orinoco_cs_config(dev_link_t * link);
-static void orinoco_cs_release(dev_link_t * link);
-static int orinoco_cs_event(event_t event, int priority,
-                           event_callback_args_t * args);
-
-static dev_link_t *orinoco_cs_attach(void);
-static void orinoco_cs_detach(dev_link_t *);
+static void orinoco_cs_release(dev_link_t *link);
+static void orinoco_cs_detach(dev_link_t *link);
 
 /********************************************************************/
 /* Device methods                                                  */
@@ -603,49 +577,85 @@ static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
        "Pavel Roskin <proski@gnu.org>, et al)";
 
 static struct pcmcia_device_id orinoco_cs_ids[] = {
-       PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300),
-       PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002),
-       PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002),
-       PCMCIA_DEVICE_MANF_CARD(0x01eb, 0x080a),
-       PCMCIA_DEVICE_MANF_CARD(0x0261, 0x0002),
-       PCMCIA_DEVICE_MANF_CARD(0x0268, 0x0001),
-       PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0305),
-       PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1613),
-       PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0002),
-       PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0673),
-       PCMCIA_DEVICE_MANF_CARD(0x02aa, 0x0002),
-       PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x0002),
-       PCMCIA_DEVICE_MANF_CARD(0x14ea, 0xb001),
-       PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300),
-       PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021),
-       PCMCIA_DEVICE_MANF_CARD(0xc250, 0x0002),
-       PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002),
-       PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005),
+       PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7100), /* SonicWALL Long Range Wireless Card */
+       PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300), /* Sohoware NCP110, Philips 802.11b */
+       PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0002), /* AnyPoint(TM) Wireless II PC Card */
+       PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0777), /* 3Com AirConnect PCI 777A */
+       PCMCIA_DEVICE_MANF_CARD(0x0126, 0x8000), /* PROXIM RangeLAN-DS/LAN PC CARD */
+       PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002), /* Compaq WL100 11 Mbps Wireless Adapter */
+       PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002), /* Lucent Orinoco and old Intersil */
+       PCMCIA_DEVICE_MANF_CARD(0x016b, 0x0001), /* Ericsson WLAN Card C11 */
+       PCMCIA_DEVICE_MANF_CARD(0x01eb, 0x080a), /* Nortel Networks eMobility 802.11 Wireless Adapter */
+       PCMCIA_DEVICE_MANF_CARD(0x01ff, 0x0008), /* Intermec MobileLAN 11Mbps 802.11b WLAN Card */
+       PCMCIA_DEVICE_MANF_CARD(0x0250, 0x0002), /* Samsung SWL2000-N 11Mb/s WLAN Card */
+       PCMCIA_DEVICE_MANF_CARD(0x0261, 0x0002), /* AirWay 802.11 Adapter (PCMCIA) */
+       PCMCIA_DEVICE_MANF_CARD(0x0268, 0x0001), /* ARtem Onair */
+       PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0305), /* Buffalo WLI-PCM-S11 */
+       PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1612), /* Linksys WPC11 Version 2.5 */
+       PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1613), /* Linksys WPC11 Version 3 */
+       PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0002), /* Compaq HNW-100 11 Mbps Wireless Adapter */
+       PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0673), /* Linksys WCF12 Wireless CompactFlash Card */
+       PCMCIA_DEVICE_MANF_CARD(0x02aa, 0x0002), /* ASUS SpaceLink WL-100 */
+       PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x0002), /* SpeedStream SS1021 Wireless Adapter */
+       PCMCIA_DEVICE_MANF_CARD(0x14ea, 0xb001), /* PLANEX RoadLannerWave GW-NS11H */
+       PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300), /* Airvast WN-100 */
+       PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021), /* Adaptec Ultra Wireless ANW-8030 */
+       PCMCIA_DEVICE_MANF_CARD(0xc001, 0x0008), /* CONTEC FLEXSCAN/FX-DDS110-PCC */
+       PCMCIA_DEVICE_MANF_CARD(0xc250, 0x0002), /* Conceptronic CON11Cpro, EMTAC A2424i */
+       PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), /* Safeway 802.11b, ZCOMAX AirRunner/XI-300 */
+       PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), /* D-Link DCF660, Sandisk Connect SDWCFB-000 */
+       PCMCIA_DEVICE_PROD_ID12(" ", "IEEE 802.11 Wireless LAN/PC Card", 0x3b6e20c8, 0xefccafe9),
        PCMCIA_DEVICE_PROD_ID12("3Com", "3CRWE737A AirConnect Wireless LAN PC Card", 0x41240e5b, 0x56010af3),
-       PCMCIA_DEVICE_PROD_ID123("Instant Wireless ", " Network PC CARD", "Version 01.02", 0x11d901af, 0x6e9bd926, 0x4b74baa0),
        PCMCIA_DEVICE_PROD_ID12("ACTIONTEC", "PRISM Wireless LAN PC Card", 0x393089da, 0xa71e69d5),
+       PCMCIA_DEVICE_PROD_ID12("Addtron", "AWP-100 Wireless PCMCIA", 0xe6ec52ce, 0x08649af2),
+       PCMCIA_DEVICE_PROD_ID123("AIRVAST", "IEEE 802.11b Wireless PCMCIA Card", "HFA3863", 0xea569531, 0x4bcb9645, 0x355cb092),
+       PCMCIA_DEVICE_PROD_ID12("Allied Telesyn", "AT-WCL452 Wireless PCMCIA Radio", 0x5cd01705, 0x4271660f),
+       PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11b_PC_CARD_25", 0x78fc06ee, 0xdb9aa842),
+       PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11B_CF_CARD_25", 0x78fc06ee, 0x45a50c1e),
        PCMCIA_DEVICE_PROD_ID12("Avaya Communication", "Avaya Wireless PC Card", 0xd8a43b78, 0x0d341169),
+       PCMCIA_DEVICE_PROD_ID12("BENQ", "AWL100 PCMCIA ADAPTER", 0x35dadc74, 0x01f7fedb),
        PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-PCM-L11G", 0x2decece3, 0xf57ca4b3),
+       PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-CF-S11G", 0x2decece3, 0x82067c18),
        PCMCIA_DEVICE_PROD_ID12("Cabletron", "RoamAbout 802.11 DS", 0x32d445f5, 0xedeffd90),
+       PCMCIA_DEVICE_PROD_ID12("Compaq", "WL200_11Mbps_Wireless_PCI_Card", 0x54f7c49c, 0x15a75e5b),
+       PCMCIA_DEVICE_PROD_ID123("corega", "WL PCCL-11", "ISL37300P", 0x0a21501a, 0x59868926, 0xc9049a39),
        PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCC-11", 0x5261440f, 0xa6405584),
        PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCCA-11", 0x5261440f, 0xdf6115f9),
        PCMCIA_DEVICE_PROD_ID12("corega_K.K.", "Wireless_LAN_PCCB-11", 0x29e33311, 0xee7a27ae),
        PCMCIA_DEVICE_PROD_ID12("D", "Link DRC-650 11Mbps WLAN Card", 0x71b18589, 0xf144e3ac),
        PCMCIA_DEVICE_PROD_ID12("D", "Link DWL-650 11Mbps WLAN Card", 0x71b18589, 0xb6f1b0ab),
+       PCMCIA_DEVICE_PROD_ID12("D-Link Corporation", "D-Link DWL-650H 11Mbps WLAN Adapter", 0xef544d24, 0xcd8ea916),
+       PCMCIA_DEVICE_PROD_ID12("Digital Data Communications", "WPC-0100", 0xfdd73470, 0xe0b6f146),
        PCMCIA_DEVICE_PROD_ID12("ELSA", "AirLancer MC-11", 0x4507a33a, 0xef54f0e3),
        PCMCIA_DEVICE_PROD_ID12("HyperLink", "Wireless PC Card 11Mbps", 0x56cc3f1a, 0x0bcf220c),
+       PCMCIA_DEVICE_PROD_ID123("Instant Wireless ", " Network PC CARD", "Version 01.02", 0x11d901af, 0x6e9bd926, 0x4b74baa0),
+       PCMCIA_DEVICE_PROD_ID12("Intel", "PRO/Wireless 2011 LAN PC Card", 0x816cc815, 0x07f58077),
        PCMCIA_DEVICE_PROD_ID12("INTERSIL", "HFA384x/IEEE", 0x74c5e40d, 0xdb472a18),
+       PCMCIA_DEVICE_PROD_ID12("INTERSIL", "I-GATE 11M PC Card / PC Card plus", 0x74c5e40d, 0x8304ff77),
+       PCMCIA_DEVICE_PROD_ID12("Intersil", "PRISM 2_5 PCMCIA ADAPTER", 0x4b801a17, 0x6345a0bf),
+       PCMCIA_DEVICE_PROD_ID123("Intersil", "PRISM Freedom PCMCIA Adapter", "ISL37100P", 0x4b801a17, 0xf222ec2d, 0x630d52b2),
+       PCMCIA_DEVICE_PROD_ID12("LeArtery", "SYNCBYAIR 11Mbps Wireless LAN PC Card", 0x7e3b326a, 0x49893e92),
+       PCMCIA_DEVICE_PROD_ID12("Linksys", "Wireless CompactFlash Card", 0x0733cc81, 0x0c52f395),
        PCMCIA_DEVICE_PROD_ID12("Lucent Technologies", "WaveLAN/IEEE", 0x23eb9949, 0xc562e72a),
        PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11", 0x481e0094, 0x7360e410),
        PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11G", 0x481e0094, 0xf57ca4b3),
        PCMCIA_DEVICE_PROD_ID12("Microsoft", "Wireless Notebook Adapter MN-520", 0x5961bf85, 0x6eec8c01),
        PCMCIA_DEVICE_PROD_ID12("NCR", "WaveLAN/IEEE", 0x24358cd4, 0xc562e72a),
+       PCMCIA_DEVICE_PROD_ID12("NETGEAR MA401 Wireless PC", "Card", 0xa37434e9, 0x9762e8f1),
        PCMCIA_DEVICE_PROD_ID12("NETGEAR MA401RA Wireless PC", "Card", 0x0306467f, 0x9762e8f1),
+       PCMCIA_DEVICE_PROD_ID12("Nortel Networks", "emobility 802.11 Wireless LAN PC Card", 0x2d617ea0, 0x88cd5767),
+       PCMCIA_DEVICE_PROD_ID12("OEM", "PRISM2 IEEE 802.11 PC-Card", 0xfea54c90, 0x48f2bdd6),
+       PCMCIA_DEVICE_PROD_ID12("OTC", "Wireless AirEZY 2411-PCC WLAN Card", 0x4ac44287, 0x235a6bed),
+       PCMCIA_DEVICE_PROD_ID123("PCMCIA", "11M WLAN Card v2.5", "ISL37300P", 0x281f1c5d, 0x6e440487, 0xc9049a39),
        PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-CF110", 0x209f40ab, 0xd9715264),
+       PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-NS110", 0x209f40ab, 0x46263178),
        PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PC CARD HARMONY 80211B", 0xc6536a5e, 0x090c3cd9),
        PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PCI CARD HARMONY 80211B", 0xc6536a5e, 0x9f494e26),
        PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "11Mbps WLAN Card", 0x43d74cb4, 0x579bd91b),
-       PCMCIA_DEVICE_PROD_ID1("Symbol Technologies", 0x3f02b4d6),
+       PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2632W", 0xc4f8b18b, 0x474a1f2a),
+       PCMCIA_DEVICE_PROD_ID12("Symbol Technologies", "LA4111 Spectrum24 Wireless LAN PC Card", 0x3f02b4d6, 0x3663cb0e),
+       PCMCIA_DEVICE_PROD_ID123("The Linksys Group, Inc.", "Instant Wireless Network PC Card", "ISL37300P", 0xa5f472c2, 0x590eb502, 0xc9049a39),
+       PCMCIA_DEVICE_PROD_ID12("ZoomAir 11Mbps High", "Rate wireless Networking", 0x273fe3db, 0x32a1eaee),
        PCMCIA_DEVICE_NULL,
 };
 MODULE_DEVICE_TABLE(pcmcia, orinoco_cs_ids);
@@ -656,8 +666,8 @@ static struct pcmcia_driver orinoco_driver = {
                .name   = DRIVER_NAME,
        },
        .attach         = orinoco_cs_attach,
-       .event          = orinoco_cs_event,
        .detach         = orinoco_cs_detach,
+       .event          = orinoco_cs_event,
        .id_table       = orinoco_cs_ids,
 };
 
index 86fa58e5cfac87279c28f729c8c840c6f446a9d7..d8afd51ff8a59010dd89f26dddcc38ff2e20496c 100644 (file)
 #define PFX DRIVER_NAME ": "
 
 #include <linux/config.h>
-
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/ioport.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/etherdevice.h>
-#include <linux/list.h>
+#include <linux/delay.h>
 #include <linux/pci.h>
-#include <linux/fcntl.h>
-
 #include <pcmcia/cisreg.h>
 
-#include "hermes.h"
 #include "orinoco.h"
 
 #define COR_OFFSET    (0xe0)   /* COR attribute offset of Prism2 PC card */
@@ -108,7 +92,7 @@ static int nortel_pci_cor_reset(struct orinoco_private *priv)
        return 0;
 }
 
-int nortel_pci_hw_init(struct nortel_pci_card *card)
+static int nortel_pci_hw_init(struct nortel_pci_card *card)
 {
        int i;
        u32 reg;
index 42e03438291b8e3ad7967ea93198c996211434ed..5362c214fc8e299da8bd0003f5d2bd76ab9fea6f 100644 (file)
 #define PFX DRIVER_NAME ": "
 
 #include <linux/config.h>
-
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/sched.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/list.h>
+#include <linux/delay.h>
 #include <linux/pci.h>
-#include <linux/fcntl.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/system.h>
 
-#include "hermes.h"
 #include "orinoco.h"
 
 /* All the magic there is from wlan-ng */
index 7ab05b89fb3f6176405cf1244c78061afe633980..210e73776545d6750e0e99289ff7f023acf2b69a 100644 (file)
 #define PFX DRIVER_NAME ": "
 
 #include <linux/config.h>
-
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/ioport.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/etherdevice.h>
-#include <linux/list.h>
+#include <linux/delay.h>
 #include <linux/pci.h>
-#include <linux/fcntl.h>
-
 #include <pcmcia/cisreg.h>
 
-#include "hermes.h"
 #include "orinoco.h"
 
 #define COR_OFFSET     (0x3e0) /* COR attribute offset of Prism2 PC card */
index 85893f42445be7e227c7fd3627747d66e984b656..5e68b7026186bc9f497c1abbf9d14259e4a96bca 100644 (file)
 #define PFX DRIVER_NAME ": "
 
 #include <linux/config.h>
-
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/ioport.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/etherdevice.h>
-#include <linux/list.h>
+#include <linux/delay.h>
 #include <linux/pci.h>
-#include <linux/fcntl.h>
-
 #include <pcmcia/cisreg.h>
 
-#include "hermes.h"
 #include "orinoco.h"
 
 #define COR_VALUE      (COR_LEVEL_REQ | COR_FUNC_ENA) /* Enable PC card with interrupt in level trigger */
index 9a8790e3580c648d33f948717c38bc0d94a29728..5c1a1adf1ff8b2421d93549f765c071c2bc9e0fb 100644 (file)
@@ -462,14 +462,12 @@ prism54_get_range(struct net_device *ndev, struct iw_request_info *info,
        /* txpower is supported in dBm's */
        range->txpower_capa = IW_TXPOW_DBM;
 
-#if WIRELESS_EXT > 16
        /* Event capability (kernel + driver) */
        range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
        IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |
        IW_EVENT_CAPA_MASK(SIOCGIWAP));
        range->event_capa[1] = IW_EVENT_CAPA_K_1;
        range->event_capa[4] = IW_EVENT_CAPA_MASK(IWEVCUSTOM);
-#endif /* WIRELESS_EXT > 16 */
 
        if (islpci_get_state(priv) < PRV_STATE_INIT)
                return 0;
@@ -693,14 +691,13 @@ prism54_get_scan(struct net_device *ndev, struct iw_request_info *info,
                                                   extra + dwrq->length,
                                                   &(bsslist->bsslist[i]),
                                                   noise);
-#if WIRELESS_EXT > 16
+
                /* Check if there is space for one more entry */
                if((extra + dwrq->length - current_ev) <= IW_EV_ADDR_LEN) {
                        /* Ask user space to try again with a bigger buffer */
                        rvalue = -E2BIG;
                        break;
                }
-#endif /* WIRELESS_EXT > 16 */
        }
 
        kfree(bsslist);
@@ -2727,12 +2724,7 @@ const struct iw_handler_def prism54_handler_def = {
        .standard = (iw_handler *) prism54_handler,
        .private = (iw_handler *) prism54_private_handler,
        .private_args = (struct iw_priv_args *) prism54_private_args,
-#if WIRELESS_EXT > 16
        .get_wireless_stats = prism54_get_wireless_stats,
-#endif /* WIRELESS_EXT > 16 */
-#if WIRELESS_EXT == 16
-       .spy_offset = offsetof(islpci_private, spy_data),
-#endif /* WIRELESS_EXT == 16 */
 };
 
 /* For wpa_supplicant */
index 6f13d4a8e2d33805b93952d1663459afb7cd8995..6c9584a9f284dc1b357af18804d6856b47260156 100644 (file)
@@ -439,8 +439,7 @@ prism54_bring_down(islpci_private *priv)
        wmb();
 
        /* wait a while for the device to reset */
-       set_current_state(TASK_UNINTERRUPTIBLE);
-       schedule_timeout(50*HZ/1000);
+       schedule_timeout_uninterruptible(msecs_to_jiffies(50));
 
        return 0;
 }
@@ -491,8 +490,7 @@ islpci_reset_if(islpci_private *priv)
                /* The software reset acknowledge needs about 220 msec here.
                 * Be conservative and wait for up to one second. */
        
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               remaining = schedule_timeout(HZ);
+               remaining = schedule_timeout_uninterruptible(HZ);
 
                if(remaining > 0) {
                        result = 0;
@@ -839,13 +837,9 @@ islpci_setup(struct pci_dev *pdev)
        priv->ndev->type = (priv->iw_mode == IW_MODE_MONITOR) ?
                priv->monitor_type : ARPHRD_ETHER;
 
-#if WIRELESS_EXT > 16
        /* Add pointers to enable iwspy support. */
        priv->wireless_data.spy_data = &priv->spy_data;
        ndev->wireless_data = &priv->wireless_data;
-#else  /* WIRELESS_EXT > 16 */
-       ndev->get_wireless_stats = &prism54_get_wireless_stats;
-#endif /* WIRELESS_EXT > 16 */
 
        /* save the start and end address of the PCI memory area */
        ndev->mem_start = (unsigned long) priv->device_base;
index 32a1019f1b363ef9c8486eba3138c159f5dee784..efbed439795111ac4e9021f56b60c4fc00ac2dad 100644 (file)
@@ -100,9 +100,7 @@ typedef struct {
 
        struct iw_spy_data spy_data; /* iwspy support */
 
-#if WIRELESS_EXT > 16
        struct iw_public_data wireless_data;
-#endif /* WIRELESS_EXT > 16 */
 
        int monitor_type; /* ARPHRD_IEEE80211 or ARPHRD_IEEE80211_PRISM */
 
index b6f2e5a223be623e56f4f5a156cf96a3ea8d5abf..4937a5ad4b2cee319d63eabf5ee423b2e8aa955c 100644 (file)
@@ -455,7 +455,7 @@ islpci_mgt_transaction(struct net_device *ndev,
                       struct islpci_mgmtframe **recvframe)
 {
        islpci_private *priv = netdev_priv(ndev);
-       const long wait_cycle_jiffies = (ISL38XX_WAIT_CYCLE * 10 * HZ) / 1000;
+       const long wait_cycle_jiffies = msecs_to_jiffies(ISL38XX_WAIT_CYCLE * 10);
        long timeout_left = ISL38XX_MAX_WAIT_CYCLES * wait_cycle_jiffies;
        int err;
        DEFINE_WAIT(wait);
@@ -475,8 +475,7 @@ islpci_mgt_transaction(struct net_device *ndev,
                int timeleft;
                struct islpci_mgmtframe *frame;
 
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               timeleft = schedule_timeout(wait_cycle_jiffies);
+               timeleft = schedule_timeout_uninterruptible(wait_cycle_jiffies);
                frame = xchg(&priv->mgmt_received, NULL);
                if (frame) {
                        if (frame->header->oid == oid) {
index e9c5ea0f5535dada4e4416fdad26d81caa6de948..70fd6fd8feb9bd5fb856043e8e195ddfccea84e6 100644 (file)
@@ -1649,28 +1649,28 @@ static iw_stats * ray_get_wireless_stats(struct net_device *    dev)
  */
 
 static const iw_handler        ray_handler[] = {
-       [SIOCSIWCOMMIT-SIOCIWFIRST] (iw_handler) ray_commit,
-       [SIOCGIWNAME  -SIOCIWFIRST] (iw_handler) ray_get_name,
-       [SIOCSIWFREQ  -SIOCIWFIRST] (iw_handler) ray_set_freq,
-       [SIOCGIWFREQ  -SIOCIWFIRST] (iw_handler) ray_get_freq,
-       [SIOCSIWMODE  -SIOCIWFIRST] (iw_handler) ray_set_mode,
-       [SIOCGIWMODE  -SIOCIWFIRST] (iw_handler) ray_get_mode,
-       [SIOCGIWRANGE -SIOCIWFIRST] (iw_handler) ray_get_range,
+       [SIOCSIWCOMMIT-SIOCIWFIRST] (iw_handler) ray_commit,
+       [SIOCGIWNAME  -SIOCIWFIRST] (iw_handler) ray_get_name,
+       [SIOCSIWFREQ  -SIOCIWFIRST] (iw_handler) ray_set_freq,
+       [SIOCGIWFREQ  -SIOCIWFIRST] (iw_handler) ray_get_freq,
+       [SIOCSIWMODE  -SIOCIWFIRST] (iw_handler) ray_set_mode,
+       [SIOCGIWMODE  -SIOCIWFIRST] (iw_handler) ray_get_mode,
+       [SIOCGIWRANGE -SIOCIWFIRST] (iw_handler) ray_get_range,
 #ifdef WIRELESS_SPY
-       [SIOCSIWSPY   -SIOCIWFIRST] (iw_handler) iw_handler_set_spy,
-       [SIOCGIWSPY   -SIOCIWFIRST] (iw_handler) iw_handler_get_spy,
-       [SIOCSIWTHRSPY-SIOCIWFIRST] (iw_handler) iw_handler_set_thrspy,
-       [SIOCGIWTHRSPY-SIOCIWFIRST] (iw_handler) iw_handler_get_thrspy,
+       [SIOCSIWSPY   -SIOCIWFIRST] (iw_handler) iw_handler_set_spy,
+       [SIOCGIWSPY   -SIOCIWFIRST] (iw_handler) iw_handler_get_spy,
+       [SIOCSIWTHRSPY-SIOCIWFIRST] (iw_handler) iw_handler_set_thrspy,
+       [SIOCGIWTHRSPY-SIOCIWFIRST] (iw_handler) iw_handler_get_thrspy,
 #endif /* WIRELESS_SPY */
-       [SIOCGIWAP    -SIOCIWFIRST] (iw_handler) ray_get_wap,
-       [SIOCSIWESSID -SIOCIWFIRST] (iw_handler) ray_set_essid,
-       [SIOCGIWESSID -SIOCIWFIRST] (iw_handler) ray_get_essid,
-       [SIOCSIWRATE  -SIOCIWFIRST] (iw_handler) ray_set_rate,
-       [SIOCGIWRATE  -SIOCIWFIRST] (iw_handler) ray_get_rate,
-       [SIOCSIWRTS   -SIOCIWFIRST] (iw_handler) ray_set_rts,
-       [SIOCGIWRTS   -SIOCIWFIRST] (iw_handler) ray_get_rts,
-       [SIOCSIWFRAG  -SIOCIWFIRST] (iw_handler) ray_set_frag,
-       [SIOCGIWFRAG  -SIOCIWFIRST] (iw_handler) ray_get_frag,
+       [SIOCGIWAP    -SIOCIWFIRST] (iw_handler) ray_get_wap,
+       [SIOCSIWESSID -SIOCIWFIRST] (iw_handler) ray_set_essid,
+       [SIOCGIWESSID -SIOCIWFIRST] (iw_handler) ray_get_essid,
+       [SIOCSIWRATE  -SIOCIWFIRST] (iw_handler) ray_set_rate,
+       [SIOCGIWRATE  -SIOCIWFIRST] (iw_handler) ray_get_rate,
+       [SIOCSIWRTS   -SIOCIWFIRST] (iw_handler) ray_set_rts,
+       [SIOCGIWRTS   -SIOCIWFIRST] (iw_handler) ray_get_rts,
+       [SIOCSIWFRAG  -SIOCIWFIRST] (iw_handler) ray_set_frag,
+       [SIOCGIWFRAG  -SIOCIWFIRST] (iw_handler) ray_get_frag,
 };
 
 #define SIOCSIPFRAMING SIOCIWFIRSTPRIV         /* Set framing mode */
@@ -1678,9 +1678,9 @@ static const iw_handler   ray_handler[] = {
 #define SIOCGIPCOUNTRY SIOCIWFIRSTPRIV + 3     /* Get country code */
 
 static const iw_handler        ray_private_handler[] = {
-       [0] (iw_handler) ray_set_framing,
-       [1] (iw_handler) ray_get_framing,
-       [3] (iw_handler) ray_get_country,
+       [0] (iw_handler) ray_set_framing,
+       [1] (iw_handler) ray_get_framing,
+       [3] (iw_handler) ray_get_country,
 };
 
 static const struct iw_priv_args       ray_private_args[] = {
index 39c6cdf7f3f736707c968008bdd11a0e7952fbed..b1bbc8e8e91f432e9e46cb44b969cbc70e550bc1 100644 (file)
 #define PFX DRIVER_NAME ": "
 
 #include <linux/config.h>
-#ifdef  __IN_PCMCIA_PACKAGE__
-#include <pcmcia/k_compat.h>
-#endif /* __IN_PCMCIA_PACKAGE__ */
-
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/etherdevice.h>
-#include <linux/wireless.h>
-
+#include <linux/delay.h>
+#include <linux/firmware.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
 #include <pcmcia/ds.h>
 
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/system.h>
-
 #include "orinoco.h"
 
-/*
- * If SPECTRUM_FW_INCLUDED is defined, the firmware is hardcoded into
- * the driver.  Use get_symbol_fw script to generate spectrum_fw.h and
- * copy it to the same directory as spectrum_cs.c.
- *
- * If SPECTRUM_FW_INCLUDED is not defined, the firmware is loaded at the
- * runtime using hotplug.  Use the same get_symbol_fw script to generate
- * files symbol_sp24t_prim_fw symbol_sp24t_sec_fw, copy them to the
- * hotplug firmware directory (typically /usr/lib/hotplug/firmware) and
- * make sure that you have hotplug installed and enabled in the kernel.
- */
-/* #define SPECTRUM_FW_INCLUDED 1 */
-
-#ifdef SPECTRUM_FW_INCLUDED
-/* Header with the firmware */
-#include "spectrum_fw.h"
-#else  /* !SPECTRUM_FW_INCLUDED */
-#include <linux/firmware.h>
 static unsigned char *primsym;
 static unsigned char *secsym;
 static const char primary_fw_name[] = "symbol_sp24t_prim_fw";
 static const char secondary_fw_name[] = "symbol_sp24t_sec_fw";
-#endif /* !SPECTRUM_FW_INCLUDED */
 
 /********************************************************************/
 /* Module stuff                                                            */
@@ -124,17 +89,8 @@ static dev_link_t *dev_list; /* = NULL */
 /* Function prototypes                                             */
 /********************************************************************/
 
-/* device methods */
-static int spectrum_cs_hard_reset(struct orinoco_private *priv);
-
-/* PCMCIA gumpf */
-static void spectrum_cs_config(dev_link_t * link);
-static void spectrum_cs_release(dev_link_t * link);
-static int spectrum_cs_event(event_t event, int priority,
-                           event_callback_args_t * args);
-
-static dev_link_t *spectrum_cs_attach(void);
-static void spectrum_cs_detach(dev_link_t *);
+static void spectrum_cs_release(dev_link_t *link);
+static void spectrum_cs_detach(dev_link_t *link);
 
 /********************************************************************/
 /* Firmware downloader                                             */
@@ -182,8 +138,8 @@ static void spectrum_cs_detach(dev_link_t *);
  * Each block has the following structure.
  */
 struct dblock {
-       u32 _addr;              /* adapter address where to write the block */
-       u16 _len;               /* length of the data only, in bytes */
+       __le32 _addr;           /* adapter address where to write the block */
+       __le16 _len;            /* length of the data only, in bytes */
        char data[0];           /* data to be written */
 } __attribute__ ((packed));
 
@@ -193,9 +149,9 @@ struct dblock {
  * items with matching ID should be written.
  */
 struct pdr {
-       u32 _id;                /* record ID */
-       u32 _addr;              /* adapter address where to write the data */
-       u32 _len;               /* expected length of the data, in bytes */
+       __le32 _id;             /* record ID */
+       __le32 _addr;           /* adapter address where to write the data */
+       __le32 _len;            /* expected length of the data, in bytes */
        char next[0];           /* next PDR starts here */
 } __attribute__ ((packed));
 
@@ -206,8 +162,8 @@ struct pdr {
  * be plugged into the secondary firmware.
  */
 struct pdi {
-       u16 _len;               /* length of ID and data, in words */
-       u16 _id;                /* record ID */
+       __le16 _len;            /* length of ID and data, in words */
+       __le16 _id;             /* record ID */
        char data[0];           /* plug data */
 } __attribute__ ((packed));;
 
@@ -414,7 +370,7 @@ spectrum_plug_pdi(hermes_t *hw, struct pdr *first_pdr, struct pdi *pdi)
 
 /* Read PDA from the adapter */
 static int
-spectrum_read_pda(hermes_t *hw, u16 *pda, int pda_len)
+spectrum_read_pda(hermes_t *hw, __le16 *pda, int pda_len)
 {
        int ret;
        int pda_size;
@@ -445,7 +401,7 @@ spectrum_read_pda(hermes_t *hw, u16 *pda, int pda_len)
 /* Parse PDA and write the records into the adapter */
 static int
 spectrum_apply_pda(hermes_t *hw, const struct dblock *first_block,
-                  u16 *pda)
+                  __le16 *pda)
 {
        int ret;
        struct pdi *pdi;
@@ -511,7 +467,7 @@ spectrum_dl_image(hermes_t *hw, dev_link_t *link,
        const struct dblock *first_block;
 
        /* Plug Data Area (PDA) */
-       u16 pda[PDA_WORDS];
+       __le16 pda[PDA_WORDS];
 
        /* Binary block begins after the 0x1A marker */
        ptr = image;
@@ -571,8 +527,6 @@ spectrum_dl_firmware(hermes_t *hw, dev_link_t *link)
 {
        int ret;
        client_handle_t handle = link->handle;
-
-#ifndef SPECTRUM_FW_INCLUDED
        const struct firmware *fw_entry;
 
        if (request_firmware(&fw_entry, primary_fw_name,
@@ -592,7 +546,6 @@ spectrum_dl_firmware(hermes_t *hw, dev_link_t *link)
                       secondary_fw_name);
                return -ENOENT;
        }
-#endif
 
        /* Load primary firmware */
        ret = spectrum_dl_image(hw, link, primsym);
@@ -1085,7 +1038,7 @@ static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
 static struct pcmcia_device_id spectrum_cs_ids[] = {
        PCMCIA_DEVICE_MANF_CARD(0x026c, 0x0001), /* Symbol Spectrum24 LA4100 */
        PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0001), /* Socket Communications CF */
-       PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0001), /* Intel PRO/Wireless 2011B */
+       PCMCIA_DEVICE_PROD_ID12("Intel", "PRO/Wireless LAN PC Card", 0x816cc815, 0x6fbf459a), /* 2011B, not 2011 */
        PCMCIA_DEVICE_NULL,
 };
 MODULE_DEVICE_TABLE(pcmcia, spectrum_cs_ids);
@@ -1096,8 +1049,8 @@ static struct pcmcia_driver orinoco_driver = {
                .name   = DRIVER_NAME,
        },
        .attach         = spectrum_cs_attach,
-       .event          = spectrum_cs_event,
        .detach         = spectrum_cs_detach,
+       .event          = spectrum_cs_event,
        .id_table       = spectrum_cs_ids,
 };
 
index 7a5e20a17890c81316c8bac8dcefd0963c29288e..b0d8b5b03152769974b382809418b47d1bd6fb08 100644 (file)
@@ -430,7 +430,6 @@ static void fee_read(unsigned long ioaddr,  /* I/O port of the card */
        }
 }
 
-#ifdef WIRELESS_EXT            /* if the wireless extension exists in the kernel */
 
 /*------------------------------------------------------------------*/
 /*
@@ -514,7 +513,6 @@ static void fee_write(unsigned long ioaddr, /* I/O port of the card */
        fee_wait(ioaddr, 10, 100);
 #endif                         /* EEPROM_IS_PROTECTED */
 }
-#endif                         /* WIRELESS_EXT */
 
 /************************ I82586 SUBROUTINES *************************/
 /*
@@ -973,11 +971,9 @@ static void wv_mmc_show(struct net_device * dev)
        mmc_read(ioaddr, 0, (u8 *) & m, sizeof(m));
        mmc_out(ioaddr, mmwoff(0, mmw_freeze), 0);
 
-#ifdef WIRELESS_EXT            /* if wireless extension exists in the kernel */
        /* Don't forget to update statistics */
        lp->wstats.discard.nwid +=
            (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l;
-#endif                         /* WIRELESS_EXT */
 
        printk(KERN_DEBUG "##### WaveLAN modem status registers: #####\n");
 #ifdef DEBUG_SHOW_UNUSED
@@ -1499,7 +1495,6 @@ static int wavelan_set_mac_address(struct net_device * dev, void *addr)
 }
 #endif                         /* SET_MAC_ADDRESS */
 
-#ifdef WIRELESS_EXT            /* if wireless extensions exist in the kernel */
 
 /*------------------------------------------------------------------*/
 /*
@@ -2473,7 +2468,6 @@ static iw_stats *wavelan_get_wireless_stats(struct net_device * dev)
 #endif
        return &lp->wstats;
 }
-#endif                         /* WIRELESS_EXT */
 
 /************************* PACKET RECEPTION *************************/
 /*
@@ -4194,11 +4188,9 @@ static int __init wavelan_config(struct net_device *dev, unsigned short ioaddr)
        dev->set_mac_address = &wavelan_set_mac_address;
 #endif                         /* SET_MAC_ADDRESS */
 
-#ifdef WIRELESS_EXT            /* if wireless extension exists in the kernel */
        dev->wireless_handlers = &wavelan_handler_def;
        lp->wireless_data.spy_data = &lp->spy_data;
        dev->wireless_data = &lp->wireless_data;
-#endif
 
        dev->mtu = WAVELAN_MTU;
 
index 509ff22a6caa674f5bc41fe41780611d45362146..166e28b9a4f7fca1464b5b500cd1759a0b2a6e34 100644 (file)
 #define MULTICAST_AVOID                /* Avoid extra multicast (I'm sceptical). */
 #undef SET_MAC_ADDRESS         /* Experimental */
 
-#ifdef WIRELESS_EXT    /* If wireless extensions exist in the kernel */
 /* Warning:  this stuff will slow down the driver. */
 #define WIRELESS_SPY           /* Enable spying addresses. */
 #undef HISTOGRAM               /* Enable histogram of signal level. */
-#endif
 
 /****************************** DEBUG ******************************/
 
@@ -506,12 +504,10 @@ struct net_local
   u_short      tx_first_free;
   u_short      tx_first_in_use;
 
-#ifdef WIRELESS_EXT
   iw_stats     wstats;         /* Wireless-specific statistics */
 
   struct iw_spy_data   spy_data;
   struct iw_public_data        wireless_data;
-#endif
 
 #ifdef HISTOGRAM
   int          his_number;             /* number of intervals */
index 183c4732ef65ca0eb24e99c79d1b43197a3f8930..4b3c98f5c564fba27800d496cd42695419924c65 100644 (file)
@@ -415,7 +415,6 @@ fee_read(u_long             base,   /* i/o port of the card */
     }
 }
 
-#ifdef WIRELESS_EXT    /* If wireless extension exist in the kernel */
 
 /*------------------------------------------------------------------*/
 /*
@@ -500,7 +499,6 @@ fee_write(u_long    base,   /* i/o port of the card */
   fee_wait(base, 10, 100);
 #endif /* EEPROM_IS_PROTECTED */
 }
-#endif /* WIRELESS_EXT */
 
 /******************* WaveLAN Roaming routines... ********************/
 
@@ -1161,10 +1159,8 @@ wv_mmc_show(struct net_device *  dev)
   mmc_read(base, 0, (u_char *)&m, sizeof(m));
   mmc_out(base, mmwoff(0, mmw_freeze), 0);
 
-#ifdef WIRELESS_EXT    /* If wireless extension exist in the kernel */
   /* Don't forget to update statistics */
   lp->wstats.discard.nwid += (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l;
-#endif /* WIRELESS_EXT */
 
   spin_unlock_irqrestore(&lp->spinlock, flags);
 
@@ -1550,7 +1546,6 @@ wavelan_set_mac_address(struct net_device *       dev,
 }
 #endif /* SET_MAC_ADDRESS */
 
-#ifdef WIRELESS_EXT    /* If wireless extension exist in the kernel */
 
 /*------------------------------------------------------------------*/
 /*
@@ -2793,7 +2788,6 @@ wavelan_get_wireless_stats(struct net_device *    dev)
 #endif
   return &lp->wstats;
 }
-#endif /* WIRELESS_EXT */
 
 /************************* PACKET RECEPTION *************************/
 /*
@@ -4679,11 +4673,9 @@ wavelan_attach(void)
   dev->watchdog_timeo  = WATCHDOG_JIFFIES;
   SET_ETHTOOL_OPS(dev, &ops);
 
-#ifdef WIRELESS_EXT    /* If wireless extension exist in the kernel */
   dev->wireless_handlers = &wavelan_handler_def;
   lp->wireless_data.spy_data = &lp->spy_data;
   dev->wireless_data = &lp->wireless_data;
-#endif
 
   /* Other specific data */
   dev->mtu = WAVELAN_MTU;
index 01d882be8790c1b9c8d2b81d71fcc64248210dad..724a715089c996f79b7e59e04ebf049bd3b0b182 100644 (file)
 #define MULTICAST_AVOID                /* Avoid extra multicast (I'm sceptical) */
 #undef SET_MAC_ADDRESS         /* Experimental */
 
-#ifdef WIRELESS_EXT    /* If wireless extension exist in the kernel */
 /* Warning : these stuff will slow down the driver... */
 #define WIRELESS_SPY           /* Enable spying addresses */
 #undef HISTOGRAM               /* Enable histogram of sig level... */
-#endif
 
 /****************************** DEBUG ******************************/
 
@@ -624,12 +622,10 @@ struct net_local
   int          rfp;            /* Last DMA machine receive pointer */
   int          overrunning;    /* Receiver overrun flag */
 
-#ifdef WIRELESS_EXT
   iw_stats     wstats;         /* Wireless specific stats */
 
   struct iw_spy_data   spy_data;
   struct iw_public_data        wireless_data;
-#endif
 
 #ifdef HISTOGRAM
   int          his_number;             /* Number of intervals */
index 7fcbe589c3f2bf4808284e1dfc595c8127fb6589..4303c50c2ab619eec386f2ec3f4b4bdc43b768f3 100644 (file)
@@ -548,7 +548,7 @@ struct wl3501_80211_tx_plcp_hdr {
 
 struct wl3501_80211_tx_hdr {
        struct wl3501_80211_tx_plcp_hdr pclp_hdr;
-       struct ieee80211_hdr            mac_hdr;
+       struct ieee80211_hdr_4addr              mac_hdr;
 } __attribute__ ((packed));
 
 /*
index 04fa7dff079c42225eb4caf97d4f29cfe65963e8..300d704bdb9a5416b781b955f0c7172a6451d269 100644 (file)
@@ -37,8 +37,6 @@
 #include <linux/cycx_x25.h>
 #endif
 
-#define        is_digit(ch) (((ch)>=(unsigned)'0'&&(ch)<=(unsigned)'9')?1:0)
-
 /* Adapter Data Space.
  * This structure is needed because we handle multiple cards, otherwise
  * static data would do it.
index 6621df86a7487745fca4b447900b59431f5d3b2e..12fe6b0bfcff8e45de8b52b2710543a4a7da7c20 100644 (file)
@@ -60,6 +60,5 @@ extern int cycx_peek(struct cycx_hw *hw, u32 addr, void *buf, u32 len);
 extern int cycx_poke(struct cycx_hw *hw, u32 addr, void *buf, u32 len);
 extern int cycx_exec(void __iomem *addr);
 
-extern void cycx_inten(struct cycx_hw *hw);
 extern void cycx_intr(struct cycx_hw *hw);
 #endif /* _CYCX_DRV_H */
index 2ef0b21517fbd20f56fe85c43aa5c7c14786c2c8..1c7a0dd5536aca7e8d2a1527ec60e48b0d26736c 100644 (file)
@@ -7,8 +7,8 @@
 /* ported to the Alpha architecture 02/20/96 (just used the HZ macro) */
 
 #define TR_RETRY_INTERVAL      (30*HZ) /* 500 on PC = 5 s */
-#define TR_RST_TIME            (HZ/20) /* 5 on PC = 50 ms */
-#define TR_BUSY_INTERVAL       (HZ/5)  /* 5 on PC = 200 ms */
+#define TR_RST_TIME            (msecs_to_jiffies(50))  /* 5 on PC = 50 ms */
+#define TR_BUSY_INTERVAL       (msecs_to_jiffies(200)) /* 5 on PC = 200 ms */
 #define TR_SPIN_INTERVAL       (3*HZ)  /* 3 seconds before init timeout */
 
 #define TR_ISA 1
index 0856548a2a08b2eadab1b6e9de56dfc667993673..a8b1a2071838f70794fc7605b0b44f5def7f44d4 100644 (file)
@@ -84,6 +84,7 @@
 #define ARPHRD_IEEE802_TR 800          /* Magic type ident for TR      */
 #define ARPHRD_IEEE80211 801           /* IEEE 802.11                  */
 #define ARPHRD_IEEE80211_PRISM 802     /* IEEE 802.11 + Prism2 header  */
+#define ARPHRD_IEEE80211_RADIOTAP 803  /* IEEE 802.11 + radiotap header */
 
 #define ARPHRD_VOID      0xFFFF        /* Void type, nothing is known */
 #define ARPHRD_NONE      0xFFFE        /* zero header length */
index 9b8d0476988ad3bb1aa9bfeeae74b9d8b1a6f57f..68f5a0f392dd969a9e063a2e835ecced5ba1c61f 100644 (file)
@@ -158,6 +158,7 @@ extern int mii_link_ok (struct mii_if_info *mii);
 extern int mii_nway_restart (struct mii_if_info *mii);
 extern int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd);
 extern int mii_ethtool_sset(struct mii_if_info *mii, struct ethtool_cmd *ecmd);
+extern int mii_check_gmii_support(struct mii_if_info *mii);
 extern void mii_check_link (struct mii_if_info *mii);
 extern unsigned int mii_check_media (struct mii_if_info *mii,
                                     unsigned int ok_to_print,
index 368e4c825ff1b5006adfe8a962083500a6776e0c..a9281b24c40b8bfa748899dad4c5e17574e4aaaf 100644 (file)
@@ -873,11 +873,9 @@ static inline void netif_rx_complete(struct net_device *dev)
 
 static inline void netif_poll_disable(struct net_device *dev)
 {
-       while (test_and_set_bit(__LINK_STATE_RX_SCHED, &dev->state)) {
+       while (test_and_set_bit(__LINK_STATE_RX_SCHED, &dev->state))
                /* No hurry. */
-               current->state = TASK_INTERRUPTIBLE;
-               schedule_timeout(1);
-       }
+               schedule_timeout_interruptible(1);
 }
 
 static inline void netif_poll_enable(struct net_device *dev)
index 78f634007fc6b88d09ddf1ffde90cea1e7c58f72..c85e103d5e7b664d9f0d3ad005175705f4ee3bce 100644 (file)
@@ -52,12 +52,8 @@ typedef struct sdlahw
 
 extern int sdla_setup  (sdlahw_t* hw, void* sfm, unsigned len);
 extern int sdla_down   (sdlahw_t* hw);
-extern int sdla_inten  (sdlahw_t* hw);
-extern int sdla_intde  (sdlahw_t* hw);
-extern int sdla_intack (sdlahw_t* hw);
 extern void S514_intack  (sdlahw_t* hw, u32 int_status);
 extern void read_S514_int_stat (sdlahw_t* hw, u32* int_status);
-extern int sdla_intr   (sdlahw_t* hw);
 extern int sdla_mapmem (sdlahw_t* hw, unsigned long addr);
 extern int sdla_peek   (sdlahw_t* hw, unsigned long addr, void* buf,
                         unsigned len);
index 167d956c492b12d484697dca5376b4855b37de86..dae9860091ddc8c99d472979b54b68577ac321ba 100644 (file)
@@ -265,15 +265,6 @@ typedef struct {
 #include <linux/tty_driver.h>
 #include <linux/tty_flip.h>
 
-
-#define        is_digit(ch) (((ch)>=(unsigned)'0'&&(ch)<=(unsigned)'9')?1:0)
-#define        is_alpha(ch) ((((ch)>=(unsigned)'a'&&(ch)<=(unsigned)'z')||\
-                 ((ch)>=(unsigned)'A'&&(ch)<=(unsigned)'Z'))?1:0)
-#define        is_hex_digit(ch) ((((ch)>=(unsigned)'0'&&(ch)<=(unsigned)'9')||\
-                 ((ch)>=(unsigned)'a'&&(ch)<=(unsigned)'f')||\
-                 ((ch)>=(unsigned)'A'&&(ch)<=(unsigned)'F'))?1:0)
-
-
 /****** Data Structures *****************************************************/
 
 /* Adapter Data Space.
index dc36b1be6745ac7c8b2e8e28810b9b99bc49de66..4851756202c5814ef66ea5089bd069f3f176c238 100644 (file)
  *
  * Adaption to a generic IEEE 802.11 stack by James Ketrenos
  * <jketreno@linux.intel.com>
- * Copyright (c) 2004, Intel Corporation
+ * Copyright (c) 2004-2005, Intel Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation. See README and COPYING for
  * more details.
+ *
+ * API Version History
+ * 1.0.x -- Initial version
+ * 1.1.x -- Added radiotap, QoS, TIM, ieee80211_geo APIs,
+ *          various structure changes, and crypto API init method
  */
 #ifndef IEEE80211_H
 #define IEEE80211_H
-#include <linux/if_ether.h> /* ETH_ALEN */
-#include <linux/kernel.h>   /* ARRAY_SIZE */
+#include <linux/if_ether.h>    /* ETH_ALEN */
+#include <linux/kernel.h>      /* ARRAY_SIZE */
 #include <linux/wireless.h>
 
+#define IEEE80211_VERSION "git-1.1.5"
+
 #define IEEE80211_DATA_LEN             2304
 /* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
    6.2.1.1.2.
    represents the 2304 bytes of real data, plus a possible 8 bytes of
    WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */
 
-
-#define IEEE80211_HLEN                 30
-#define IEEE80211_FRAME_LEN            (IEEE80211_DATA_LEN + IEEE80211_HLEN)
-
-struct ieee80211_hdr {
-       __le16 frame_ctl;
-       __le16 duration_id;
-       u8 addr1[ETH_ALEN];
-       u8 addr2[ETH_ALEN];
-       u8 addr3[ETH_ALEN];
-       __le16 seq_ctl;
-       u8 addr4[ETH_ALEN];
-} __attribute__ ((packed));
-
-struct ieee80211_hdr_3addr {
-       __le16 frame_ctl;
-       __le16 duration_id;
-       u8 addr1[ETH_ALEN];
-       u8 addr2[ETH_ALEN];
-       u8 addr3[ETH_ALEN];
-       __le16 seq_ctl;
-} __attribute__ ((packed));
-
 #define IEEE80211_1ADDR_LEN 10
 #define IEEE80211_2ADDR_LEN 16
 #define IEEE80211_3ADDR_LEN 24
 #define IEEE80211_4ADDR_LEN 30
 #define IEEE80211_FCS_LEN    4
+#define IEEE80211_HLEN                 (IEEE80211_4ADDR_LEN)
+#define IEEE80211_FRAME_LEN            (IEEE80211_DATA_LEN + IEEE80211_HLEN)
 
 #define MIN_FRAG_THRESHOLD     256U
 #define        MAX_FRAG_THRESHOLD     2346U
@@ -113,11 +99,11 @@ struct ieee80211_hdr_3addr {
 #define IEEE80211_STYPE_CFACK          0x0050
 #define IEEE80211_STYPE_CFPOLL         0x0060
 #define IEEE80211_STYPE_CFACKPOLL      0x0070
+#define IEEE80211_STYPE_QOS_DATA        0x0080
 
 #define IEEE80211_SCTL_FRAG            0x000F
 #define IEEE80211_SCTL_SEQ             0xFFF0
 
-
 /* debug macros */
 
 #ifdef CONFIG_IEEE80211_DEBUG
@@ -128,8 +114,7 @@ do { if (ieee80211_debug_level & (level)) \
          in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0)
 #else
 #define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
-#endif /* CONFIG_IEEE80211_DEBUG */
-
+#endif                         /* CONFIG_IEEE80211_DEBUG */
 
 /* debug macros not dependent on CONFIG_IEEE80211_DEBUG */
 
@@ -140,7 +125,6 @@ do { if (ieee80211_debug_level & (level)) \
  * messages. It should never be used for passing essid to user space. */
 const char *escape_essid(const char *essid, u8 essid_len);
 
-
 /*
  * To use the debug system:
  *
@@ -177,6 +161,7 @@ const char *escape_essid(const char *essid, u8 essid_len);
 
 #define IEEE80211_DL_TX            (1<<8)
 #define IEEE80211_DL_RX            (1<<9)
+#define IEEE80211_DL_QOS           (1<<31)
 
 #define IEEE80211_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a)
 #define IEEE80211_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a)
@@ -190,9 +175,10 @@ const char *escape_essid(const char *essid, u8 essid_len);
 #define IEEE80211_DEBUG_DROP(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_DROP, f, ## a)
 #define IEEE80211_DEBUG_TX(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_TX, f, ## a)
 #define IEEE80211_DEBUG_RX(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_RX, f, ## a)
+#define IEEE80211_DEBUG_QOS(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_QOS, f, ## a)
 #include <linux/netdevice.h>
 #include <linux/wireless.h>
-#include <linux/if_arp.h> /* ARPHRD_ETHER */
+#include <linux/if_arp.h>      /* ARPHRD_ETHER */
 
 #ifndef WIRELESS_SPY
 #define WIRELESS_SPY           /* enable iwspy support */
@@ -200,10 +186,10 @@ const char *escape_essid(const char *essid, u8 essid_len);
 #include <net/iw_handler.h>    /* new driver API */
 
 #ifndef ETH_P_PAE
-#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
-#endif /* ETH_P_PAE */
+#define ETH_P_PAE 0x888E       /* Port Access Entity (IEEE 802.1X) */
+#endif                         /* ETH_P_PAE */
 
-#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
+#define ETH_P_PREAUTH 0x88C7   /* IEEE 802.11i pre-authentication */
 
 #ifndef ETH_P_80211_RAW
 #define ETH_P_80211_RAW (ETH_P_ECONET + 1)
@@ -215,10 +201,10 @@ const char *escape_essid(const char *essid, u8 essid_len);
 
 struct ieee80211_snap_hdr {
 
-        u8    dsap;   /* always 0xAA */
-        u8    ssap;   /* always 0xAA */
-        u8    ctrl;   /* always 0x03 */
-        u8    oui[P80211_OUI_LEN];    /* organizational universal id */
+       u8 dsap;                /* always 0xAA */
+       u8 ssap;                /* always 0xAA */
+       u8 ctrl;                /* always 0x03 */
+       u8 oui[P80211_OUI_LEN]; /* organizational universal id */
 
 } __attribute__ ((packed));
 
@@ -246,8 +232,9 @@ struct ieee80211_snap_hdr {
 #define WLAN_CAPABILITY_PBCC (1<<6)
 #define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7)
 #define WLAN_CAPABILITY_SPECTRUM_MGMT (1<<8)
+#define WLAN_CAPABILITY_QOS (1<<9)
 #define WLAN_CAPABILITY_SHORT_SLOT_TIME (1<<10)
-#define WLAN_CAPABILITY_OSSS_OFDM (1<<13)
+#define WLAN_CAPABILITY_DSSS_OFDM (1<<13)
 
 /* Status codes */
 enum ieee80211_statuscode {
@@ -312,14 +299,12 @@ enum ieee80211_reasoncode {
        WLAN_REASON_CIPHER_SUITE_REJECTED = 24,
 };
 
-
 #define IEEE80211_STATMASK_SIGNAL (1<<0)
 #define IEEE80211_STATMASK_RSSI (1<<1)
 #define IEEE80211_STATMASK_NOISE (1<<2)
 #define IEEE80211_STATMASK_RATE (1<<3)
 #define IEEE80211_STATMASK_WEMASK 0x7
 
-
 #define IEEE80211_CCK_MODULATION    (1<<0)
 #define IEEE80211_OFDM_MODULATION   (1<<1)
 
@@ -377,9 +362,6 @@ enum ieee80211_reasoncode {
 #define IEEE80211_NUM_CCK_RATES                    4
 #define IEEE80211_OFDM_SHIFT_MASK_A         4
 
-
-
-
 /* NOTE: This data is for statistical purposes; not all hardware provides this
  *       information for frames received.  Not setting these will not cause
  *       any adverse affects. */
@@ -388,7 +370,7 @@ struct ieee80211_rx_stats {
        s8 rssi;
        u8 signal;
        u8 noise;
-       u16 rate; /* in 100 kbps */
+       u16 rate;               /* in 100 kbps */
        u8 received_channel;
        u8 control;
        u8 mask;
@@ -439,38 +421,44 @@ struct ieee80211_device;
 
 #include "ieee80211_crypt.h"
 
-#define SEC_KEY_1         (1<<0)
-#define SEC_KEY_2         (1<<1)
-#define SEC_KEY_3         (1<<2)
-#define SEC_KEY_4         (1<<3)
-#define SEC_ACTIVE_KEY    (1<<4)
-#define SEC_AUTH_MODE     (1<<5)
-#define SEC_UNICAST_GROUP (1<<6)
-#define SEC_LEVEL         (1<<7)
-#define SEC_ENABLED       (1<<8)
-
-#define SEC_LEVEL_0      0 /* None */
-#define SEC_LEVEL_1      1 /* WEP 40 and 104 bit */
-#define SEC_LEVEL_2      2 /* Level 1 + TKIP */
-#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */
-#define SEC_LEVEL_3      4 /* Level 2 + CCMP */
-
-#define WEP_KEYS 4
-#define WEP_KEY_LEN 13
+#define SEC_KEY_1              (1<<0)
+#define SEC_KEY_2              (1<<1)
+#define SEC_KEY_3              (1<<2)
+#define SEC_KEY_4              (1<<3)
+#define SEC_ACTIVE_KEY         (1<<4)
+#define SEC_AUTH_MODE          (1<<5)
+#define SEC_UNICAST_GROUP      (1<<6)
+#define SEC_LEVEL              (1<<7)
+#define SEC_ENABLED            (1<<8)
+#define SEC_ENCRYPT            (1<<9)
+
+#define SEC_LEVEL_0            0       /* None */
+#define SEC_LEVEL_1            1       /* WEP 40 and 104 bit */
+#define SEC_LEVEL_2            2       /* Level 1 + TKIP */
+#define SEC_LEVEL_2_CKIP       3       /* Level 1 + CKIP */
+#define SEC_LEVEL_3            4       /* Level 2 + CCMP */
+
+#define SEC_ALG_NONE           0
+#define SEC_ALG_WEP            1
+#define SEC_ALG_TKIP           2
+#define SEC_ALG_CCMP           3
+
+#define WEP_KEYS               4
+#define WEP_KEY_LEN            13
+#define SCM_KEY_LEN            32
+#define SCM_TEMPORAL_KEY_LENGTH        16
 
 struct ieee80211_security {
        u16 active_key:2,
-            enabled:1,
-           auth_mode:2,
-            auth_algo:4,
-            unicast_uses_group:1;
+           enabled:1,
+           auth_mode:2, auth_algo:4, unicast_uses_group:1, encrypt:1;
+       u8 encode_alg[WEP_KEYS];
        u8 key_sizes[WEP_KEYS];
-       u8 keys[WEP_KEYS][WEP_KEY_LEN];
+       u8 keys[WEP_KEYS][SCM_KEY_LEN];
        u8 level;
        u16 flags;
 } __attribute__ ((packed));
 
-
 /*
 
  802.11 data frame from AP
@@ -494,7 +482,7 @@ enum ieee80211_mfie {
        MFIE_TYPE_RATES = 1,
        MFIE_TYPE_FH_SET = 2,
        MFIE_TYPE_DS_SET = 3,
-       MFIE_TYPE_CF_SET =  4,
+       MFIE_TYPE_CF_SET = 4,
        MFIE_TYPE_TIM = 5,
        MFIE_TYPE_IBSS_SET = 6,
        MFIE_TYPE_COUNTRY = 7,
@@ -516,11 +504,75 @@ enum ieee80211_mfie {
        MFIE_TYPE_RSN = 48,
        MFIE_TYPE_RATES_EX = 50,
        MFIE_TYPE_GENERIC = 221,
+       MFIE_TYPE_QOS_PARAMETER = 222,
 };
 
-struct ieee80211_info_element_hdr {
-       u8 id;
-       u8 len;
+/* Minimal header; can be used for passing 802.11 frames with sufficient
+ * information to determine what type of underlying data type is actually
+ * stored in the data. */
+struct ieee80211_hdr {
+       __le16 frame_ctl;
+       __le16 duration_id;
+       u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_1addr {
+       __le16 frame_ctl;
+       __le16 duration_id;
+       u8 addr1[ETH_ALEN];
+       u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_2addr {
+       __le16 frame_ctl;
+       __le16 duration_id;
+       u8 addr1[ETH_ALEN];
+       u8 addr2[ETH_ALEN];
+       u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_3addr {
+       __le16 frame_ctl;
+       __le16 duration_id;
+       u8 addr1[ETH_ALEN];
+       u8 addr2[ETH_ALEN];
+       u8 addr3[ETH_ALEN];
+       __le16 seq_ctl;
+       u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_4addr {
+       __le16 frame_ctl;
+       __le16 duration_id;
+       u8 addr1[ETH_ALEN];
+       u8 addr2[ETH_ALEN];
+       u8 addr3[ETH_ALEN];
+       __le16 seq_ctl;
+       u8 addr4[ETH_ALEN];
+       u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_3addrqos {
+       __le16 frame_ctl;
+       __le16 duration_id;
+       u8 addr1[ETH_ALEN];
+       u8 addr2[ETH_ALEN];
+       u8 addr3[ETH_ALEN];
+       __le16 seq_ctl;
+       u8 payload[0];
+       __le16 qos_ctl;
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_4addrqos {
+       __le16 frame_ctl;
+       __le16 duration_id;
+       u8 addr1[ETH_ALEN];
+       u8 addr2[ETH_ALEN];
+       u8 addr3[ETH_ALEN];
+       __le16 seq_ctl;
+       u8 addr4[ETH_ALEN];
+       u8 payload[0];
+       __le16 qos_ctl;
 } __attribute__ ((packed));
 
 struct ieee80211_info_element {
@@ -546,49 +598,77 @@ struct ieee80211_info_element {
        u16 status;
 */
 
-struct ieee80211_authentication {
+struct ieee80211_auth {
        struct ieee80211_hdr_3addr header;
        __le16 algorithm;
        __le16 transaction;
        __le16 status;
-       struct ieee80211_info_element info_element;
+       /* challenge */
+       struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_disassoc {
+       struct ieee80211_hdr_3addr header;
+       __le16 reason;
 } __attribute__ ((packed));
 
+/* Alias deauth for disassoc */
+#define ieee82011_deauth ieee80211_disassoc
+
+struct ieee80211_probe_request {
+       struct ieee80211_hdr_3addr header;
+       /* SSID, supported rates */
+       struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
 
 struct ieee80211_probe_response {
        struct ieee80211_hdr_3addr header;
        u32 time_stamp[2];
        __le16 beacon_interval;
        __le16 capability;
-       struct ieee80211_info_element info_element;
+       /* SSID, supported rates, FH params, DS params,
+        * CF params, IBSS params, TIM (if beacon), RSN */
+       struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+/* Alias beacon for probe_response */
+#define ieee80211_beacon ieee80211_probe_response
+
+struct ieee80211_assoc_request {
+       struct ieee80211_hdr_3addr header;
+       __le16 capability;
+       __le16 listen_interval;
+       /* SSID, supported rates, RSN */
+       struct ieee80211_info_element info_element[0];
 } __attribute__ ((packed));
 
-struct ieee80211_assoc_request_frame {
+struct ieee80211_reassoc_request {
+       struct ieee80211_hdr_3addr header;
        __le16 capability;
        __le16 listen_interval;
        u8 current_ap[ETH_ALEN];
-       struct ieee80211_info_element info_element;
+       struct ieee80211_info_element info_element[0];
 } __attribute__ ((packed));
 
-struct ieee80211_assoc_response_frame {
+struct ieee80211_assoc_response {
        struct ieee80211_hdr_3addr header;
        __le16 capability;
        __le16 status;
        __le16 aid;
-       struct ieee80211_info_element info_element; /* supported rates */
+       /* supported rates */
+       struct ieee80211_info_element info_element[0];
 } __attribute__ ((packed));
 
-
 struct ieee80211_txb {
        u8 nr_frags;
        u8 encrypted;
-       u16 reserved;
-       u16 frag_size;
-       u16 payload_size;
+       u8 rts_included;
+       u8 reserved;
+       __le16 frag_size;
+       __le16 payload_size;
        struct sk_buff *fragments[0];
 };
 
-
 /* SWEEP TABLE ENTRIES NUMBER */
 #define MAX_SWEEP_TAB_ENTRIES            42
 #define MAX_SWEEP_TAB_ENTRIES_PER_PACKET  7
@@ -604,9 +684,68 @@ struct ieee80211_txb {
 
 #define MAX_WPA_IE_LEN 64
 
-#define NETWORK_EMPTY_ESSID (1<<0)
-#define NETWORK_HAS_OFDM    (1<<1)
-#define NETWORK_HAS_CCK     (1<<2)
+#define NETWORK_EMPTY_ESSID    (1<<0)
+#define NETWORK_HAS_OFDM       (1<<1)
+#define NETWORK_HAS_CCK        (1<<2)
+
+/* QoS structure */
+#define NETWORK_HAS_QOS_PARAMETERS      (1<<3)
+#define NETWORK_HAS_QOS_INFORMATION     (1<<4)
+#define NETWORK_HAS_QOS_MASK            (NETWORK_HAS_QOS_PARAMETERS | NETWORK_HAS_QOS_INFORMATION)
+
+#define QOS_QUEUE_NUM                   4
+#define QOS_OUI_LEN                     3
+#define QOS_OUI_TYPE                    2
+#define QOS_ELEMENT_ID                  221
+#define QOS_OUI_INFO_SUB_TYPE           0
+#define QOS_OUI_PARAM_SUB_TYPE          1
+#define QOS_VERSION_1                   1
+#define QOS_AIFSN_MIN_VALUE             2
+
+struct ieee80211_qos_information_element {
+       u8 elementID;
+       u8 length;
+       u8 qui[QOS_OUI_LEN];
+       u8 qui_type;
+       u8 qui_subtype;
+       u8 version;
+       u8 ac_info;
+} __attribute__ ((packed));
+
+struct ieee80211_qos_ac_parameter {
+       u8 aci_aifsn;
+       u8 ecw_min_max;
+       __le16 tx_op_limit;
+} __attribute__ ((packed));
+
+struct ieee80211_qos_parameter_info {
+       struct ieee80211_qos_information_element info_element;
+       u8 reserved;
+       struct ieee80211_qos_ac_parameter ac_params_record[QOS_QUEUE_NUM];
+} __attribute__ ((packed));
+
+struct ieee80211_qos_parameters {
+       __le16 cw_min[QOS_QUEUE_NUM];
+       __le16 cw_max[QOS_QUEUE_NUM];
+       u8 aifs[QOS_QUEUE_NUM];
+       u8 flag[QOS_QUEUE_NUM];
+       __le16 tx_op_limit[QOS_QUEUE_NUM];
+} __attribute__ ((packed));
+
+struct ieee80211_qos_data {
+       struct ieee80211_qos_parameters parameters;
+       int active;
+       int supported;
+       u8 param_count;
+       u8 old_param_count;
+};
+
+struct ieee80211_tim_parameters {
+       u8 tim_count;
+       u8 tim_period;
+} __attribute__ ((packed));
+
+/*******************************************************/
 
 struct ieee80211_network {
        /* These entries are used to identify a unique network */
@@ -616,6 +755,8 @@ struct ieee80211_network {
        u8 ssid[IW_ESSID_MAX_SIZE + 1];
        u8 ssid_len;
 
+       struct ieee80211_qos_data qos_data;
+
        /* These are network statistics */
        struct ieee80211_rx_stats stats;
        u16 capability;
@@ -631,10 +772,12 @@ struct ieee80211_network {
        u16 beacon_interval;
        u16 listen_interval;
        u16 atim_window;
+       u8 erp_value;
        u8 wpa_ie[MAX_WPA_IE_LEN];
        size_t wpa_ie_len;
        u8 rsn_ie[MAX_WPA_IE_LEN];
        size_t rsn_ie_len;
+       struct ieee80211_tim_parameters tim;
        struct list_head list;
 };
 
@@ -651,17 +794,52 @@ enum ieee80211_state {
 #define DEFAULT_MAX_SCAN_AGE (15 * HZ)
 #define DEFAULT_FTS 2346
 
-
 #define CFG_IEEE80211_RESERVE_FCS (1<<0)
 #define CFG_IEEE80211_COMPUTE_FCS (1<<1)
+#define CFG_IEEE80211_RTS (1<<2)
+
+#define IEEE80211_24GHZ_MIN_CHANNEL 1
+#define IEEE80211_24GHZ_MAX_CHANNEL 14
+#define IEEE80211_24GHZ_CHANNELS    14
+
+#define IEEE80211_52GHZ_MIN_CHANNEL 36
+#define IEEE80211_52GHZ_MAX_CHANNEL 165
+#define IEEE80211_52GHZ_CHANNELS    32
+
+enum {
+       IEEE80211_CH_PASSIVE_ONLY = (1 << 0),
+       IEEE80211_CH_B_ONLY = (1 << 2),
+       IEEE80211_CH_NO_IBSS = (1 << 3),
+       IEEE80211_CH_UNIFORM_SPREADING = (1 << 4),
+       IEEE80211_CH_RADAR_DETECT = (1 << 5),
+       IEEE80211_CH_INVALID = (1 << 6),
+};
+
+struct ieee80211_channel {
+       u32 freq;
+       u8 channel;
+       u8 flags;
+       u8 max_power;
+};
+
+struct ieee80211_geo {
+       u8 name[4];
+       u8 bg_channels;
+       u8 a_channels;
+       struct ieee80211_channel bg[IEEE80211_24GHZ_CHANNELS];
+       struct ieee80211_channel a[IEEE80211_52GHZ_CHANNELS];
+};
 
 struct ieee80211_device {
        struct net_device *dev;
+       struct ieee80211_security sec;
 
        /* Bookkeeping structures */
        struct net_device_stats stats;
        struct ieee80211_stats ieee_stats;
 
+       struct ieee80211_geo geo;
+
        /* Probe / Beacon management */
        struct list_head network_free_list;
        struct list_head network_list;
@@ -669,62 +847,102 @@ struct ieee80211_device {
        int scans;
        int scan_age;
 
-       int iw_mode; /* operating mode (IW_MODE_*) */
+       int iw_mode;            /* operating mode (IW_MODE_*) */
+       struct iw_spy_data spy_data;    /* iwspy support */
 
        spinlock_t lock;
 
-       int tx_headroom; /* Set to size of any additional room needed at front
-                         * of allocated Tx SKBs */
+       int tx_headroom;        /* Set to size of any additional room needed at front
+                                * of allocated Tx SKBs */
        u32 config;
 
        /* WEP and other encryption related settings at the device level */
-       int open_wep; /* Set to 1 to allow unencrypted frames */
+       int open_wep;           /* Set to 1 to allow unencrypted frames */
 
-       int reset_on_keychange; /* Set to 1 if the HW needs to be reset on
+       int reset_on_keychange; /* Set to 1 if the HW needs to be reset on
                                 * WEP key changes */
 
        /* If the host performs {en,de}cryption, then set to 1 */
        int host_encrypt;
+       int host_encrypt_msdu;
        int host_decrypt;
-       int ieee802_1x; /* is IEEE 802.1X used */
+       /* host performs multicast decryption */
+       int host_mc_decrypt;
+
+       int host_open_frag;
+       int host_build_iv;
+       int ieee802_1x;         /* is IEEE 802.1X used */
 
        /* WPA data */
        int wpa_enabled;
        int drop_unencrypted;
-       int tkip_countermeasures;
        int privacy_invoked;
        size_t wpa_ie_len;
        u8 *wpa_ie;
 
        struct list_head crypt_deinit_list;
        struct ieee80211_crypt_data *crypt[WEP_KEYS];
-       int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
+       int tx_keyidx;          /* default TX key index (crypt[tx_keyidx]) */
        struct timer_list crypt_deinit_timer;
+       int crypt_quiesced;
 
-       int bcrx_sta_key; /* use individual keys to override default keys even
-                          * with RX of broad/multicast frames */
+       int bcrx_sta_key;       /* use individual keys to override default keys even
+                                * with RX of broad/multicast frames */
 
        /* Fragmentation structures */
        struct ieee80211_frag_entry frag_cache[IEEE80211_FRAG_CACHE_LEN];
        unsigned int frag_next_idx;
-       u16 fts; /* Fragmentation Threshold */
+       u16 fts;                /* Fragmentation Threshold */
+       u16 rts;                /* RTS threshold */
 
        /* Association info */
        u8 bssid[ETH_ALEN];
 
        enum ieee80211_state state;
 
-       int mode;       /* A, B, G */
-       int modulation; /* CCK, OFDM */
-       int freq_band;  /* 2.4Ghz, 5.2Ghz, Mixed */
-       int abg_ture;   /* ABG flag              */
+       int mode;               /* A, B, G */
+       int modulation;         /* CCK, OFDM */
+       int freq_band;          /* 2.4Ghz, 5.2Ghz, Mixed */
+       int abg_true;           /* ABG flag              */
+
+       int perfect_rssi;
+       int worst_rssi;
 
        /* Callback functions */
-       void (*set_security)(struct net_device *dev,
-                            struct ieee80211_security *sec);
-       int (*hard_start_xmit)(struct ieee80211_txb *txb,
-                              struct net_device *dev);
-       int (*reset_port)(struct net_device *dev);
+       void (*set_security) (struct net_device * dev,
+                             struct ieee80211_security * sec);
+       int (*hard_start_xmit) (struct ieee80211_txb * txb,
+                               struct net_device * dev, int pri);
+       int (*reset_port) (struct net_device * dev);
+       int (*is_queue_full) (struct net_device * dev, int pri);
+
+       int (*handle_management) (struct net_device * dev,
+                                 struct ieee80211_network * network, u16 type);
+
+       /* Typical STA methods */
+       int (*handle_auth) (struct net_device * dev,
+                           struct ieee80211_auth * auth);
+       int (*handle_deauth) (struct net_device * dev,
+                             struct ieee80211_auth * auth);
+       int (*handle_disassoc) (struct net_device * dev,
+                               struct ieee80211_disassoc * assoc);
+       int (*handle_beacon) (struct net_device * dev,
+                             struct ieee80211_beacon * beacon,
+                             struct ieee80211_network * network);
+       int (*handle_probe_response) (struct net_device * dev,
+                                     struct ieee80211_probe_response * resp,
+                                     struct ieee80211_network * network);
+       int (*handle_probe_request) (struct net_device * dev,
+                                    struct ieee80211_probe_request * req,
+                                    struct ieee80211_rx_stats * stats);
+       int (*handle_assoc_response) (struct net_device * dev,
+                                     struct ieee80211_assoc_response * resp,
+                                     struct ieee80211_network * network);
+
+       /* Typical AP methods */
+       int (*handle_assoc_request) (struct net_device * dev);
+       int (*handle_reassoc_request) (struct net_device * dev,
+                                      struct ieee80211_reassoc_request * req);
 
        /* This must be the last item so that it points to the data
         * allocated beyond this structure by alloc_ieee80211 */
@@ -736,12 +954,12 @@ struct ieee80211_device {
 #define IEEE_G            (1<<2)
 #define IEEE_MODE_MASK    (IEEE_A|IEEE_B|IEEE_G)
 
-extern inline void *ieee80211_priv(struct net_device *dev)
+static inline void *ieee80211_priv(struct net_device *dev)
 {
        return ((struct ieee80211_device *)netdev_priv(dev))->priv;
 }
 
-extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
+static inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
 {
        /* Single white space is for Linksys APs */
        if (essid_len == 1 && essid[0] == ' ')
@@ -757,7 +975,8 @@ extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
        return 1;
 }
 
-extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode)
+static inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee,
+                                         int mode)
 {
        /*
         * It is possible for both access points and our device to support
@@ -783,14 +1002,17 @@ extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mod
        return 0;
 }
 
-extern inline int ieee80211_get_hdrlen(u16 fc)
+static inline int ieee80211_get_hdrlen(u16 fc)
 {
        int hdrlen = IEEE80211_3ADDR_LEN;
+       u16 stype = WLAN_FC_GET_STYPE(fc);
 
        switch (WLAN_FC_GET_TYPE(fc)) {
        case IEEE80211_FTYPE_DATA:
                if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
                        hdrlen = IEEE80211_4ADDR_LEN;
+               if (stype & IEEE80211_STYPE_QOS_DATA)
+                       hdrlen += 2;
                break;
        case IEEE80211_FTYPE_CTL:
                switch (WLAN_FC_GET_STYPE(fc)) {
@@ -808,7 +1030,20 @@ extern inline int ieee80211_get_hdrlen(u16 fc)
        return hdrlen;
 }
 
+static inline u8 *ieee80211_get_payload(struct ieee80211_hdr *hdr)
+{
+       switch (ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl))) {
+       case IEEE80211_1ADDR_LEN:
+               return ((struct ieee80211_hdr_1addr *)hdr)->payload;
+       case IEEE80211_2ADDR_LEN:
+               return ((struct ieee80211_hdr_2addr *)hdr)->payload;
+       case IEEE80211_3ADDR_LEN:
+               return ((struct ieee80211_hdr_3addr *)hdr)->payload;
+       case IEEE80211_4ADDR_LEN:
+               return ((struct ieee80211_hdr_4addr *)hdr)->payload;
+       }
 
+}
 
 /* ieee80211.c */
 extern void free_ieee80211(struct net_device *dev);
@@ -817,18 +1052,30 @@ extern struct net_device *alloc_ieee80211(int sizeof_priv);
 extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
 
 /* ieee80211_tx.c */
-extern int ieee80211_xmit(struct sk_buff *skb,
-                         struct net_device *dev);
+extern int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev);
 extern void ieee80211_txb_free(struct ieee80211_txb *);
-
+extern int ieee80211_tx_frame(struct ieee80211_device *ieee,
+                             struct ieee80211_hdr *frame, int len);
 
 /* ieee80211_rx.c */
 extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
                        struct ieee80211_rx_stats *rx_stats);
 extern void ieee80211_rx_mgt(struct ieee80211_device *ieee,
-                            struct ieee80211_hdr *header,
+                            struct ieee80211_hdr_4addr *header,
                             struct ieee80211_rx_stats *stats);
 
+/* ieee80211_geo.c */
+extern const struct ieee80211_geo *ieee80211_get_geo(struct ieee80211_device
+                                                    *ieee);
+extern int ieee80211_set_geo(struct ieee80211_device *ieee,
+                            const struct ieee80211_geo *geo);
+
+extern int ieee80211_is_valid_channel(struct ieee80211_device *ieee,
+                                     u8 channel);
+extern int ieee80211_channel_to_index(struct ieee80211_device *ieee,
+                                     u8 channel);
+extern u8 ieee80211_freq_to_channel(struct ieee80211_device *ieee, u32 freq);
+
 /* ieee80211_wx.c */
 extern int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
                                 struct iw_request_info *info,
@@ -839,17 +1086,21 @@ extern int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
 extern int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
                                   struct iw_request_info *info,
                                   union iwreq_data *wrqu, char *key);
-
-
-extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
+extern int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
+                                     struct iw_request_info *info,
+                                     union iwreq_data *wrqu, char *extra);
+extern int ieee80211_wx_get_encodeext(struct ieee80211_device *ieee,
+                                     struct iw_request_info *info,
+                                     union iwreq_data *wrqu, char *extra);
+
+static inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
 {
        ieee->scans++;
 }
 
-extern inline int ieee80211_get_scans(struct ieee80211_device *ieee)
+static inline int ieee80211_get_scans(struct ieee80211_device *ieee)
 {
        return ieee->scans;
 }
 
-
-#endif /* IEEE80211_H */
+#endif                         /* IEEE80211_H */
index b58a3bcc0dc0972c882f5992ad02264510769bf5..0c9d859d912edded9386a8c4448dcf3996609651 100644 (file)
 
 #include <linux/skbuff.h>
 
+enum {
+       IEEE80211_CRYPTO_TKIP_COUNTERMEASURES = (1<<0),
+};
+
 struct ieee80211_crypto_ops {
        const char *name;
 
        /* init new crypto context (e.g., allocate private data space,
         * select IV, etc.); returns NULL on failure or pointer to allocated
         * private data on success */
-       void * (*init)(int keyidx);
+       void *(*init) (int keyidx);
 
        /* deinitialize crypto context and free allocated private data */
-       void (*deinit)(void *priv);
+       void (*deinit) (void *priv);
+
+       int (*build_iv) (struct sk_buff * skb, int hdr_len, void *priv);
 
        /* encrypt/decrypt return < 0 on error or >= 0 on success. The return
         * value from decrypt_mpdu is passed as the keyidx value for
@@ -42,34 +48,39 @@ struct ieee80211_crypto_ops {
         * encryption; if not, error will be returned; these functions are
         * called for all MPDUs (i.e., fragments).
         */
-       int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
-       int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
+       int (*encrypt_mpdu) (struct sk_buff * skb, int hdr_len, void *priv);
+       int (*decrypt_mpdu) (struct sk_buff * skb, int hdr_len, void *priv);
 
        /* These functions are called for full MSDUs, i.e. full frames.
         * These can be NULL if full MSDU operations are not needed. */
-       int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv);
-       int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len,
-                           void *priv);
+       int (*encrypt_msdu) (struct sk_buff * skb, int hdr_len, void *priv);
+       int (*decrypt_msdu) (struct sk_buff * skb, int keyidx, int hdr_len,
+                            void *priv);
 
-       int (*set_key)(void *key, int len, u8 *seq, void *priv);
-       int (*get_key)(void *key, int len, u8 *seq, void *priv);
+       int (*set_key) (void *key, int len, u8 * seq, void *priv);
+       int (*get_key) (void *key, int len, u8 * seq, void *priv);
 
        /* procfs handler for printing out key information and possible
         * statistics */
-       char * (*print_stats)(char *p, void *priv);
+       char *(*print_stats) (char *p, void *priv);
+
+       /* Crypto specific flag get/set for configuration settings */
+       unsigned long (*get_flags)(void *priv);
+       unsigned long (*set_flags)(unsigned long flags, void *priv);
 
        /* maximum number of bytes added by encryption; encrypt buf is
         * allocated with extra_prefix_len bytes, copy of in_buf, and
         * extra_postfix_len; encrypt need not use all this space, but
         * the result must start at the beginning of the buffer and correct
         * length must be returned */
-       int extra_prefix_len, extra_postfix_len;
+       int extra_mpdu_prefix_len, extra_mpdu_postfix_len;
+       int extra_msdu_prefix_len, extra_msdu_postfix_len;
 
        struct module *owner;
 };
 
 struct ieee80211_crypt_data {
-       struct list_head list; /* delayed deletion list */
+       struct list_head list;  /* delayed deletion list */
        struct ieee80211_crypto_ops *ops;
        void *priv;
        atomic_t refcnt;
@@ -77,10 +88,11 @@ struct ieee80211_crypt_data {
 
 int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops);
 int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops);
-struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name);
+struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name);
 void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int);
 void ieee80211_crypt_deinit_handler(unsigned long);
 void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
                                    struct ieee80211_crypt_data **crypt);
+void ieee80211_crypt_quiescing(struct ieee80211_device *ieee);
 
 #endif
diff --git a/include/net/ieee80211_radiotap.h b/include/net/ieee80211_radiotap.h
new file mode 100644 (file)
index 0000000..429b738
--- /dev/null
@@ -0,0 +1,231 @@
+/* $FreeBSD: src/sys/net80211/ieee80211_radiotap.h,v 1.5 2005/01/22 20:12:05 sam Exp $ */
+/* $NetBSD: ieee80211_radiotap.h,v 1.11 2005/06/22 06:16:02 dyoung Exp $ */
+
+/*-
+ * Copyright (c) 2003, 2004 David Young.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of David Young may not be used to endorse or promote
+ *    products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DAVID
+ * YOUNG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ */
+
+/*
+ * Modifications to fit into the linux IEEE 802.11 stack,
+ * Mike Kershaw (dragorn@kismetwireless.net)
+ */
+
+#ifndef IEEE80211RADIOTAP_H
+#define IEEE80211RADIOTAP_H
+
+#include <linux/if_ether.h>
+#include <linux/kernel.h>
+
+/* Radiotap header version (from official NetBSD feed) */
+#define IEEE80211RADIOTAP_VERSION      "1.5"
+/* Base version of the radiotap packet header data */
+#define PKTHDR_RADIOTAP_VERSION                0
+
+/* A generic radio capture format is desirable. There is one for
+ * Linux, but it is neither rigidly defined (there were not even
+ * units given for some fields) nor easily extensible.
+ *
+ * I suggest the following extensible radio capture format. It is
+ * based on a bitmap indicating which fields are present.
+ *
+ * I am trying to describe precisely what the application programmer
+ * should expect in the following, and for that reason I tell the
+ * units and origin of each measurement (where it applies), or else I
+ * use sufficiently weaselly language ("is a monotonically nondecreasing
+ * function of...") that I cannot set false expectations for lawyerly
+ * readers.
+ */
+
+/* XXX tcpdump/libpcap do not tolerate variable-length headers,
+ * yet, so we pad every radiotap header to 64 bytes. Ugh.
+ */
+#define IEEE80211_RADIOTAP_HDRLEN      64
+
+/* The radio capture header precedes the 802.11 header. */
+struct ieee80211_radiotap_header {
+       u8 it_version;          /* Version 0. Only increases
+                                * for drastic changes,
+                                * introduction of compatible
+                                * new fields does not count.
+                                */
+       u8 it_pad;
+       u16 it_len;             /* length of the whole
+                                * header in bytes, including
+                                * it_version, it_pad,
+                                * it_len, and data fields.
+                                */
+       u32 it_present;         /* A bitmap telling which
+                                * fields are present. Set bit 31
+                                * (0x80000000) to extend the
+                                * bitmap by another 32 bits.
+                                * Additional extensions are made
+                                * by setting bit 31.
+                                */
+};
+
+/* Name                                 Data type       Units
+ * ----                                 ---------       -----
+ *
+ * IEEE80211_RADIOTAP_TSFT              u64       microseconds
+ *
+ *      Value in microseconds of the MAC's 64-bit 802.11 Time
+ *      Synchronization Function timer when the first bit of the
+ *      MPDU arrived at the MAC. For received frames, only.
+ *
+ * IEEE80211_RADIOTAP_CHANNEL           2 x u16   MHz, bitmap
+ *
+ *      Tx/Rx frequency in MHz, followed by flags (see below).
+ *
+ * IEEE80211_RADIOTAP_FHSS              u16       see below
+ *
+ *      For frequency-hopping radios, the hop set (first byte)
+ *      and pattern (second byte).
+ *
+ * IEEE80211_RADIOTAP_RATE              u8        500kb/s
+ *
+ *      Tx/Rx data rate
+ *
+ * IEEE80211_RADIOTAP_DBM_ANTSIGNAL     int8_t          decibels from
+ *                                                      one milliwatt (dBm)
+ *
+ *      RF signal power at the antenna, decibel difference from
+ *      one milliwatt.
+ *
+ * IEEE80211_RADIOTAP_DBM_ANTNOISE      int8_t          decibels from
+ *                                                      one milliwatt (dBm)
+ *
+ *      RF noise power at the antenna, decibel difference from one
+ *      milliwatt.
+ *
+ * IEEE80211_RADIOTAP_DB_ANTSIGNAL      u8        decibel (dB)
+ *
+ *      RF signal power at the antenna, decibel difference from an
+ *      arbitrary, fixed reference.
+ *
+ * IEEE80211_RADIOTAP_DB_ANTNOISE       u8        decibel (dB)
+ *
+ *      RF noise power at the antenna, decibel difference from an
+ *      arbitrary, fixed reference point.
+ *
+ * IEEE80211_RADIOTAP_LOCK_QUALITY      u16       unitless
+ *
+ *      Quality of Barker code lock. Unitless. Monotonically
+ *      nondecreasing with "better" lock strength. Called "Signal
+ *      Quality" in datasheets.  (Is there a standard way to measure
+ *      this?)
+ *
+ * IEEE80211_RADIOTAP_TX_ATTENUATION    u16       unitless
+ *
+ *      Transmit power expressed as unitless distance from max
+ *      power set at factory calibration.  0 is max power.
+ *      Monotonically nondecreasing with lower power levels.
+ *
+ * IEEE80211_RADIOTAP_DB_TX_ATTENUATION u16       decibels (dB)
+ *
+ *      Transmit power expressed as decibel distance from max power
+ *      set at factory calibration.  0 is max power.  Monotonically
+ *      nondecreasing with lower power levels.
+ *
+ * IEEE80211_RADIOTAP_DBM_TX_POWER      int8_t          decibels from
+ *                                                      one milliwatt (dBm)
+ *
+ *      Transmit power expressed as dBm (decibels from a 1 milliwatt
+ *      reference). This is the absolute power level measured at
+ *      the antenna port.
+ *
+ * IEEE80211_RADIOTAP_FLAGS             u8        bitmap
+ *
+ *      Properties of transmitted and received frames. See flags
+ *      defined below.
+ *
+ * IEEE80211_RADIOTAP_ANTENNA           u8        antenna index
+ *
+ *      Unitless indication of the Rx/Tx antenna for this packet.
+ *      The first antenna is antenna 0.
+ *
+ * IEEE80211_RADIOTAP_FCS              u32       data
+ *
+ *     FCS from frame in network byte order.
+ */
+enum ieee80211_radiotap_type {
+       IEEE80211_RADIOTAP_TSFT = 0,
+       IEEE80211_RADIOTAP_FLAGS = 1,
+       IEEE80211_RADIOTAP_RATE = 2,
+       IEEE80211_RADIOTAP_CHANNEL = 3,
+       IEEE80211_RADIOTAP_FHSS = 4,
+       IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5,
+       IEEE80211_RADIOTAP_DBM_ANTNOISE = 6,
+       IEEE80211_RADIOTAP_LOCK_QUALITY = 7,
+       IEEE80211_RADIOTAP_TX_ATTENUATION = 8,
+       IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9,
+       IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
+       IEEE80211_RADIOTAP_ANTENNA = 11,
+       IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
+       IEEE80211_RADIOTAP_DB_ANTNOISE = 13,
+       IEEE80211_RADIOTAP_EXT = 31,
+};
+
+/* Channel flags. */
+#define        IEEE80211_CHAN_TURBO    0x0010  /* Turbo channel */
+#define        IEEE80211_CHAN_CCK      0x0020  /* CCK channel */
+#define        IEEE80211_CHAN_OFDM     0x0040  /* OFDM channel */
+#define        IEEE80211_CHAN_2GHZ     0x0080  /* 2 GHz spectrum channel. */
+#define        IEEE80211_CHAN_5GHZ     0x0100  /* 5 GHz spectrum channel */
+#define        IEEE80211_CHAN_PASSIVE  0x0200  /* Only passive scan allowed */
+#define        IEEE80211_CHAN_DYN      0x0400  /* Dynamic CCK-OFDM channel */
+#define        IEEE80211_CHAN_GFSK     0x0800  /* GFSK channel (FHSS PHY) */
+
+/* For IEEE80211_RADIOTAP_FLAGS */
+#define        IEEE80211_RADIOTAP_F_CFP        0x01    /* sent/received
+                                                * during CFP
+                                                */
+#define        IEEE80211_RADIOTAP_F_SHORTPRE   0x02    /* sent/received
+                                                * with short
+                                                * preamble
+                                                */
+#define        IEEE80211_RADIOTAP_F_WEP        0x04    /* sent/received
+                                                * with WEP encryption
+                                                */
+#define        IEEE80211_RADIOTAP_F_FRAG       0x08    /* sent/received
+                                                * with fragmentation
+                                                */
+#define        IEEE80211_RADIOTAP_F_FCS        0x10    /* frame includes FCS */
+#define        IEEE80211_RADIOTAP_F_DATAPAD    0x20    /* frame has padding between
+                                                * 802.11 header and payload
+                                                * (to 32-bit boundary)
+                                                */
+
+/* Ugly macro to convert literal channel numbers into their mhz equivalents
+ * There are certianly some conditions that will break this (like feeding it '30')
+ * but they shouldn't arise since nothing talks on channel 30. */
+#define ieee80211chan2mhz(x) \
+       (((x) <= 14) ? \
+       (((x) == 14) ? 2484 : ((x) * 5) + 2407) : \
+       ((x) + 1000) * 5)
+
+#endif                         /* IEEE80211_RADIOTAP_H */
index 614cb6ba564e41c476381c0201c9c0e2a7076f5c..877efa434700bec7d7a997b8492568be0316af5a 100644 (file)
@@ -86,7 +86,6 @@ static inline struct sppp *sppp_of(struct net_device *dev)
 
 void sppp_attach (struct ppp_device *pd);
 void sppp_detach (struct net_device *dev);
-void sppp_input (struct net_device *dev, struct sk_buff *m);
 int sppp_do_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd);
 struct sk_buff *sppp_dequeue (struct net_device *dev);
 int sppp_isempty (struct net_device *dev);
index a6ccac5baea8863b77b967d2fe61358ea77cb158..f988417121da76646ad995ce3a556c09349b0338 100644 (file)
@@ -7,5 +7,6 @@ ieee80211-objs := \
        ieee80211_module.o \
        ieee80211_tx.o \
        ieee80211_rx.o \
-       ieee80211_wx.o
+       ieee80211_wx.o \
+       ieee80211_geo.o
 
index 61a9d92e455b67e5dc9651470780a32120e57d7a..f3b6aa3be63878a08708cf5542f654117882527e 100644 (file)
@@ -41,6 +41,12 @@ void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force)
 {
        struct list_head *ptr, *n;
        struct ieee80211_crypt_data *entry;
+       unsigned long flags;
+
+       spin_lock_irqsave(&ieee->lock, flags);
+
+       if (list_empty(&ieee->crypt_deinit_list))
+               goto unlock;
 
        for (ptr = ieee->crypt_deinit_list.next, n = ptr->next;
             ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) {
@@ -57,6 +63,18 @@ void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force)
                }
                kfree(entry);
        }
+      unlock:
+       spin_unlock_irqrestore(&ieee->lock, flags);
+}
+
+/* After this, crypt_deinit_list won't accept new members */
+void ieee80211_crypt_quiescing(struct ieee80211_device *ieee)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&ieee->lock, flags);
+       ieee->crypt_quiesced = 1;
+       spin_unlock_irqrestore(&ieee->lock, flags);
 }
 
 void ieee80211_crypt_deinit_handler(unsigned long data)
@@ -64,16 +82,16 @@ void ieee80211_crypt_deinit_handler(unsigned long data)
        struct ieee80211_device *ieee = (struct ieee80211_device *)data;
        unsigned long flags;
 
-       spin_lock_irqsave(&ieee->lock, flags);
        ieee80211_crypt_deinit_entries(ieee, 0);
-       if (!list_empty(&ieee->crypt_deinit_list)) {
+
+       spin_lock_irqsave(&ieee->lock, flags);
+       if (!list_empty(&ieee->crypt_deinit_list) && !ieee->crypt_quiesced) {
                printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
                       "deletion list\n", ieee->dev->name);
                ieee->crypt_deinit_timer.expires = jiffies + HZ;
                add_timer(&ieee->crypt_deinit_timer);
        }
        spin_unlock_irqrestore(&ieee->lock, flags);
-
 }
 
 void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
@@ -93,10 +111,12 @@ void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
         * locking. */
 
        spin_lock_irqsave(&ieee->lock, flags);
-       list_add(&tmp->list, &ieee->crypt_deinit_list);
-       if (!timer_pending(&ieee->crypt_deinit_timer)) {
-               ieee->crypt_deinit_timer.expires = jiffies + HZ;
-               add_timer(&ieee->crypt_deinit_timer);
+       if (!ieee->crypt_quiesced) {
+               list_add(&tmp->list, &ieee->crypt_deinit_list);
+               if (!timer_pending(&ieee->crypt_deinit_timer)) {
+                       ieee->crypt_deinit_timer.expires = jiffies + HZ;
+                       add_timer(&ieee->crypt_deinit_timer);
+               }
        }
        spin_unlock_irqrestore(&ieee->lock, flags);
 }
@@ -191,18 +211,18 @@ static void ieee80211_crypt_null_deinit(void *priv)
 }
 
 static struct ieee80211_crypto_ops ieee80211_crypt_null = {
-       .name                   = "NULL",
-       .init                   = ieee80211_crypt_null_init,
-       .deinit                 = ieee80211_crypt_null_deinit,
-       .encrypt_mpdu           = NULL,
-       .decrypt_mpdu           = NULL,
-       .encrypt_msdu           = NULL,
-       .decrypt_msdu           = NULL,
-       .set_key                = NULL,
-       .get_key                = NULL,
-       .extra_prefix_len       = 0,
-       .extra_postfix_len      = 0,
-       .owner                  = THIS_MODULE,
+       .name = "NULL",
+       .init = ieee80211_crypt_null_init,
+       .deinit = ieee80211_crypt_null_deinit,
+       .encrypt_mpdu = NULL,
+       .decrypt_mpdu = NULL,
+       .encrypt_msdu = NULL,
+       .decrypt_msdu = NULL,
+       .set_key = NULL,
+       .get_key = NULL,
+       .extra_mpdu_prefix_len = 0,
+       .extra_mpdu_postfix_len = 0,
+       .owner = THIS_MODULE,
 };
 
 static int __init ieee80211_crypto_init(void)
@@ -249,6 +269,7 @@ static void __exit ieee80211_crypto_deinit(void)
 EXPORT_SYMBOL(ieee80211_crypt_deinit_entries);
 EXPORT_SYMBOL(ieee80211_crypt_deinit_handler);
 EXPORT_SYMBOL(ieee80211_crypt_delayed_deinit);
+EXPORT_SYMBOL(ieee80211_crypt_quiescing);
 
 EXPORT_SYMBOL(ieee80211_register_crypto_ops);
 EXPORT_SYMBOL(ieee80211_unregister_crypto_ops);
index 8fc13f45971e3b895ffa508f4750319a5a6e641c..05a853c13012836fe518cf965049e84ce1f59b0a 100644 (file)
@@ -119,7 +119,7 @@ static inline void xor_block(u8 * b, u8 * a, size_t len)
 }
 
 static void ccmp_init_blocks(struct crypto_tfm *tfm,
-                            struct ieee80211_hdr *hdr,
+                            struct ieee80211_hdr_4addr *hdr,
                             u8 * pn, size_t dlen, u8 * b0, u8 * auth, u8 * s0)
 {
        u8 *pos, qc = 0;
@@ -191,26 +191,18 @@ static void ccmp_init_blocks(struct crypto_tfm *tfm,
        ieee80211_ccmp_aes_encrypt(tfm, b0, s0);
 }
 
-static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
+static int ieee80211_ccmp_hdr(struct sk_buff *skb, int hdr_len, void *priv)
 {
        struct ieee80211_ccmp_data *key = priv;
-       int data_len, i, blocks, last, len;
-       u8 *pos, *mic;
-       struct ieee80211_hdr *hdr;
-       u8 *b0 = key->tx_b0;
-       u8 *b = key->tx_b;
-       u8 *e = key->tx_e;
-       u8 *s0 = key->tx_s0;
+       int i;
+       u8 *pos;
 
-       if (skb_headroom(skb) < CCMP_HDR_LEN ||
-           skb_tailroom(skb) < CCMP_MIC_LEN || skb->len < hdr_len)
+       if (skb_headroom(skb) < CCMP_HDR_LEN || skb->len < hdr_len)
                return -1;
 
-       data_len = skb->len - hdr_len;
        pos = skb_push(skb, CCMP_HDR_LEN);
        memmove(pos, pos + CCMP_HDR_LEN, hdr_len);
        pos += hdr_len;
-       mic = skb_put(skb, CCMP_MIC_LEN);
 
        i = CCMP_PN_LEN - 1;
        while (i >= 0) {
@@ -229,7 +221,31 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
        *pos++ = key->tx_pn[1];
        *pos++ = key->tx_pn[0];
 
-       hdr = (struct ieee80211_hdr *)skb->data;
+       return CCMP_HDR_LEN;
+}
+
+static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
+{
+       struct ieee80211_ccmp_data *key = priv;
+       int data_len, i, blocks, last, len;
+       u8 *pos, *mic;
+       struct ieee80211_hdr_4addr *hdr;
+       u8 *b0 = key->tx_b0;
+       u8 *b = key->tx_b;
+       u8 *e = key->tx_e;
+       u8 *s0 = key->tx_s0;
+
+       if (skb_tailroom(skb) < CCMP_MIC_LEN || skb->len < hdr_len)
+               return -1;
+
+       data_len = skb->len - hdr_len;
+       len = ieee80211_ccmp_hdr(skb, hdr_len, priv);
+       if (len < 0)
+               return -1;
+
+       pos = skb->data + hdr_len + CCMP_HDR_LEN;
+       mic = skb_put(skb, CCMP_MIC_LEN);
+       hdr = (struct ieee80211_hdr_4addr *)skb->data;
        ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0);
 
        blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
@@ -258,7 +274,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 {
        struct ieee80211_ccmp_data *key = priv;
        u8 keyidx, *pos;
-       struct ieee80211_hdr *hdr;
+       struct ieee80211_hdr_4addr *hdr;
        u8 *b0 = key->rx_b0;
        u8 *b = key->rx_b;
        u8 *a = key->rx_a;
@@ -272,7 +288,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
                return -1;
        }
 
-       hdr = (struct ieee80211_hdr *)skb->data;
+       hdr = (struct ieee80211_hdr_4addr *)skb->data;
        pos = skb->data + hdr_len;
        keyidx = pos[3];
        if (!(keyidx & (1 << 5))) {
@@ -426,19 +442,20 @@ static char *ieee80211_ccmp_print_stats(char *p, void *priv)
 }
 
 static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = {
-       .name                   = "CCMP",
-       .init                   = ieee80211_ccmp_init,
-       .deinit                 = ieee80211_ccmp_deinit,
-       .encrypt_mpdu           = ieee80211_ccmp_encrypt,
-       .decrypt_mpdu           = ieee80211_ccmp_decrypt,
-       .encrypt_msdu           = NULL,
-       .decrypt_msdu           = NULL,
-       .set_key                = ieee80211_ccmp_set_key,
-       .get_key                = ieee80211_ccmp_get_key,
-       .print_stats            = ieee80211_ccmp_print_stats,
-       .extra_prefix_len       = CCMP_HDR_LEN,
-       .extra_postfix_len      = CCMP_MIC_LEN,
-       .owner                  = THIS_MODULE,
+       .name = "CCMP",
+       .init = ieee80211_ccmp_init,
+       .deinit = ieee80211_ccmp_deinit,
+       .build_iv = ieee80211_ccmp_hdr,
+       .encrypt_mpdu = ieee80211_ccmp_encrypt,
+       .decrypt_mpdu = ieee80211_ccmp_decrypt,
+       .encrypt_msdu = NULL,
+       .decrypt_msdu = NULL,
+       .set_key = ieee80211_ccmp_set_key,
+       .get_key = ieee80211_ccmp_get_key,
+       .print_stats = ieee80211_ccmp_print_stats,
+       .extra_mpdu_prefix_len = CCMP_HDR_LEN,
+       .extra_mpdu_postfix_len = CCMP_MIC_LEN,
+       .owner = THIS_MODULE,
 };
 
 static int __init ieee80211_crypto_ccmp_init(void)
index d4f9164be1a1848f75f49fd0ee631ce70aa6fdc6..2e34f29b7956f46c4f81fef31953af4953fd2752 100644 (file)
@@ -59,8 +59,24 @@ struct ieee80211_tkip_data {
 
        /* scratch buffers for virt_to_page() (crypto API) */
        u8 rx_hdr[16], tx_hdr[16];
+
+       unsigned long flags;
 };
 
+static unsigned long ieee80211_tkip_set_flags(unsigned long flags, void *priv)
+{
+       struct ieee80211_tkip_data *_priv = priv;
+       unsigned long old_flags = _priv->flags;
+       _priv->flags = flags;
+       return old_flags;
+}
+
+static unsigned long ieee80211_tkip_get_flags(void *priv)
+{
+       struct ieee80211_tkip_data *_priv = priv;
+       return _priv->flags;
+}
+
 static void *ieee80211_tkip_init(int key_idx)
 {
        struct ieee80211_tkip_data *priv;
@@ -69,6 +85,7 @@ static void *ieee80211_tkip_init(int key_idx)
        if (priv == NULL)
                goto fail;
        memset(priv, 0, sizeof(*priv));
+
        priv->key_idx = key_idx;
 
        priv->tfm_arc4 = crypto_alloc_tfm("arc4", 0);
@@ -255,25 +272,27 @@ static void tkip_mixing_phase2(u8 * WEPSeed, const u8 * TK, const u16 * TTAK,
 #endif
 }
 
-static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
+static u8 *ieee80211_tkip_hdr(struct sk_buff *skb, int hdr_len, void *priv)
 {
        struct ieee80211_tkip_data *tkey = priv;
        int len;
-       u8 rc4key[16], *pos, *icv;
-       struct ieee80211_hdr *hdr;
+       u8 *rc4key, *pos, *icv;
+       struct ieee80211_hdr_4addr *hdr;
        u32 crc;
-       struct scatterlist sg;
 
-       if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 ||
-           skb->len < hdr_len)
-               return -1;
+       hdr = (struct ieee80211_hdr_4addr *)skb->data;
+
+       if (skb_headroom(skb) < 8 || skb->len < hdr_len)
+               return NULL;
 
-       hdr = (struct ieee80211_hdr *)skb->data;
        if (!tkey->tx_phase1_done) {
                tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
                                   tkey->tx_iv32);
                tkey->tx_phase1_done = 1;
        }
+       rc4key = kmalloc(16, GFP_ATOMIC);
+       if (!rc4key)
+               return NULL;
        tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
 
        len = skb->len - hdr_len;
@@ -282,9 +301,9 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
        pos += hdr_len;
        icv = skb_put(skb, 4);
 
-       *pos++ = rc4key[0];
-       *pos++ = rc4key[1];
-       *pos++ = rc4key[2];
+       *pos++ = *rc4key;
+       *pos++ = *(rc4key + 1);
+       *pos++ = *(rc4key + 2);
        *pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */ ;
        *pos++ = tkey->tx_iv32 & 0xff;
        *pos++ = (tkey->tx_iv32 >> 8) & 0xff;
@@ -297,6 +316,38 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
        icv[2] = crc >> 16;
        icv[3] = crc >> 24;
 
+       return rc4key;
+}
+
+static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
+{
+       struct ieee80211_tkip_data *tkey = priv;
+       int len;
+       const u8 *rc4key;
+       u8 *pos;
+       struct scatterlist sg;
+
+       if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) {
+               if (net_ratelimit()) {
+                       struct ieee80211_hdr_4addr *hdr =
+                           (struct ieee80211_hdr_4addr *)skb->data;
+                       printk(KERN_DEBUG "TKIP countermeasures: dropped "
+                              "TX packet to " MAC_FMT "\n",
+                              MAC_ARG(hdr->addr1));
+               }
+               return -1;
+       }
+
+       if (skb_tailroom(skb) < 4 || skb->len < hdr_len)
+               return -1;
+
+       len = skb->len - hdr_len;
+       pos = skb->data + hdr_len;
+
+       rc4key = ieee80211_tkip_hdr(skb, hdr_len, priv);
+       if (!rc4key)
+               return -1;
+
        crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16);
        sg.page = virt_to_page(pos);
        sg.offset = offset_in_page(pos);
@@ -319,16 +370,26 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
        u8 keyidx, *pos;
        u32 iv32;
        u16 iv16;
-       struct ieee80211_hdr *hdr;
+       struct ieee80211_hdr_4addr *hdr;
        u8 icv[4];
        u32 crc;
        struct scatterlist sg;
        int plen;
 
+       hdr = (struct ieee80211_hdr_4addr *)skb->data;
+
+       if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) {
+               if (net_ratelimit()) {
+                       printk(KERN_DEBUG "TKIP countermeasures: dropped "
+                              "received packet from " MAC_FMT "\n",
+                              MAC_ARG(hdr->addr2));
+               }
+               return -1;
+       }
+
        if (skb->len < hdr_len + 8 + 4)
                return -1;
 
-       hdr = (struct ieee80211_hdr *)skb->data;
        pos = skb->data + hdr_len;
        keyidx = pos[3];
        if (!(keyidx & (1 << 5))) {
@@ -441,9 +502,9 @@ static int michael_mic(struct ieee80211_tkip_data *tkey, u8 * key, u8 * hdr,
 
 static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr)
 {
-       struct ieee80211_hdr *hdr11;
+       struct ieee80211_hdr_4addr *hdr11;
 
-       hdr11 = (struct ieee80211_hdr *)skb->data;
+       hdr11 = (struct ieee80211_hdr_4addr *)skb->data;
        switch (le16_to_cpu(hdr11->frame_ctl) &
                (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
        case IEEE80211_FCTL_TODS:
@@ -490,9 +551,9 @@ static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len,
        return 0;
 }
 
-#if WIRELESS_EXT >= 18
 static void ieee80211_michael_mic_failure(struct net_device *dev,
-                                         struct ieee80211_hdr *hdr, int keyidx)
+                                         struct ieee80211_hdr_4addr *hdr,
+                                         int keyidx)
 {
        union iwreq_data wrqu;
        struct iw_michaelmicfailure ev;
@@ -510,28 +571,6 @@ static void ieee80211_michael_mic_failure(struct net_device *dev,
        wrqu.data.length = sizeof(ev);
        wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev);
 }
-#elif WIRELESS_EXT >= 15
-static void ieee80211_michael_mic_failure(struct net_device *dev,
-                                         struct ieee80211_hdr *hdr, int keyidx)
-{
-       union iwreq_data wrqu;
-       char buf[128];
-
-       /* TODO: needed parameters: count, keyid, key type, TSC */
-       sprintf(buf, "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr="
-               MAC_FMT ")", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni",
-               MAC_ARG(hdr->addr2));
-       memset(&wrqu, 0, sizeof(wrqu));
-       wrqu.data.length = strlen(buf);
-       wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
-}
-#else                          /* WIRELESS_EXT >= 15 */
-static inline void ieee80211_michael_mic_failure(struct net_device *dev,
-                                                struct ieee80211_hdr *hdr,
-                                                int keyidx)
-{
-}
-#endif                         /* WIRELESS_EXT >= 15 */
 
 static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
                                        int hdr_len, void *priv)
@@ -547,8 +586,8 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
                        skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
                return -1;
        if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
-               struct ieee80211_hdr *hdr;
-               hdr = (struct ieee80211_hdr *)skb->data;
+               struct ieee80211_hdr_4addr *hdr;
+               hdr = (struct ieee80211_hdr_4addr *)skb->data;
                printk(KERN_DEBUG "%s: Michael MIC verification failed for "
                       "MSDU from " MAC_FMT " keyidx=%d\n",
                       skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2),
@@ -654,19 +693,22 @@ static char *ieee80211_tkip_print_stats(char *p, void *priv)
 }
 
 static struct ieee80211_crypto_ops ieee80211_crypt_tkip = {
-       .name                   = "TKIP",
-       .init                   = ieee80211_tkip_init,
-       .deinit                 = ieee80211_tkip_deinit,
-       .encrypt_mpdu           = ieee80211_tkip_encrypt,
-       .decrypt_mpdu           = ieee80211_tkip_decrypt,
-       .encrypt_msdu           = ieee80211_michael_mic_add,
-       .decrypt_msdu           = ieee80211_michael_mic_verify,
-       .set_key                = ieee80211_tkip_set_key,
-       .get_key                = ieee80211_tkip_get_key,
-       .print_stats            = ieee80211_tkip_print_stats,
-       .extra_prefix_len       = 4 + 4,        /* IV + ExtIV */
-       .extra_postfix_len      = 8 + 4,        /* MIC + ICV */
-       .owner                  = THIS_MODULE,
+       .name = "TKIP",
+       .init = ieee80211_tkip_init,
+       .deinit = ieee80211_tkip_deinit,
+       .encrypt_mpdu = ieee80211_tkip_encrypt,
+       .decrypt_mpdu = ieee80211_tkip_decrypt,
+       .encrypt_msdu = ieee80211_michael_mic_add,
+       .decrypt_msdu = ieee80211_michael_mic_verify,
+       .set_key = ieee80211_tkip_set_key,
+       .get_key = ieee80211_tkip_get_key,
+       .print_stats = ieee80211_tkip_print_stats,
+       .extra_mpdu_prefix_len = 4 + 4, /* IV + ExtIV */
+       .extra_mpdu_postfix_len = 4,    /* ICV */
+       .extra_msdu_postfix_len = 8,    /* MIC */
+       .get_flags = ieee80211_tkip_get_flags,
+       .set_flags = ieee80211_tkip_set_flags,
+       .owner = THIS_MODULE,
 };
 
 static int __init ieee80211_crypto_tkip_init(void)
index b4d2514a090270be5b5822e671678ded227231df..7c08ed2f2628f4dd439465f0abdd90358a8e39a9 100644 (file)
@@ -229,19 +229,19 @@ static char *prism2_wep_print_stats(char *p, void *priv)
 }
 
 static struct ieee80211_crypto_ops ieee80211_crypt_wep = {
-       .name                   = "WEP",
-       .init                   = prism2_wep_init,
-       .deinit                 = prism2_wep_deinit,
-       .encrypt_mpdu           = prism2_wep_encrypt,
-       .decrypt_mpdu           = prism2_wep_decrypt,
-       .encrypt_msdu           = NULL,
-       .decrypt_msdu           = NULL,
-       .set_key                = prism2_wep_set_key,
-       .get_key                = prism2_wep_get_key,
-       .print_stats            = prism2_wep_print_stats,
-       .extra_prefix_len       = 4,    /* IV */
-       .extra_postfix_len      = 4,    /* ICV */
-       .owner                  = THIS_MODULE,
+       .name = "WEP",
+       .init = prism2_wep_init,
+       .deinit = prism2_wep_deinit,
+       .encrypt_mpdu = prism2_wep_encrypt,
+       .decrypt_mpdu = prism2_wep_decrypt,
+       .encrypt_msdu = NULL,
+       .decrypt_msdu = NULL,
+       .set_key = prism2_wep_set_key,
+       .get_key = prism2_wep_get_key,
+       .print_stats = prism2_wep_print_stats,
+       .extra_mpdu_prefix_len = 4,     /* IV */
+       .extra_mpdu_postfix_len = 4,    /* ICV */
+       .owner = THIS_MODULE,
 };
 
 static int __init ieee80211_crypto_wep_init(void)
diff --git a/net/ieee80211/ieee80211_geo.c b/net/ieee80211/ieee80211_geo.c
new file mode 100644 (file)
index 0000000..c4b54ef
--- /dev/null
@@ -0,0 +1,141 @@
+/******************************************************************************
+
+  Copyright(c) 2005 Intel Corporation. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  This program is distributed in the hope that it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+  more details.
+
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc., 59
+  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+  The full GNU General Public License is included in this distribution in the
+  file called LICENSE.
+
+  Contact Information:
+  James P. Ketrenos <ipw2100-admin@linux.intel.com>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+******************************************************************************/
+#include <linux/compiler.h>
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/if_arp.h>
+#include <linux/in6.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/proc_fs.h>
+#include <linux/skbuff.h>
+#include <linux/slab.h>
+#include <linux/tcp.h>
+#include <linux/types.h>
+#include <linux/version.h>
+#include <linux/wireless.h>
+#include <linux/etherdevice.h>
+#include <asm/uaccess.h>
+
+#include <net/ieee80211.h>
+
+int ieee80211_is_valid_channel(struct ieee80211_device *ieee, u8 channel)
+{
+       int i;
+
+       /* Driver needs to initialize the geography map before using
+        * these helper functions */
+       BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
+
+       if (ieee->freq_band & IEEE80211_24GHZ_BAND)
+               for (i = 0; i < ieee->geo.bg_channels; i++)
+                       /* NOTE: If G mode is currently supported but
+                        * this is a B only channel, we don't see it
+                        * as valid. */
+                       if ((ieee->geo.bg[i].channel == channel) &&
+                           (!(ieee->mode & IEEE_G) ||
+                            !(ieee->geo.bg[i].flags & IEEE80211_CH_B_ONLY)))
+                               return IEEE80211_24GHZ_BAND;
+
+       if (ieee->freq_band & IEEE80211_52GHZ_BAND)
+               for (i = 0; i < ieee->geo.a_channels; i++)
+                       if (ieee->geo.a[i].channel == channel)
+                               return IEEE80211_52GHZ_BAND;
+
+       return 0;
+}
+
+int ieee80211_channel_to_index(struct ieee80211_device *ieee, u8 channel)
+{
+       int i;
+
+       /* Driver needs to initialize the geography map before using
+        * these helper functions */
+       BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
+
+       if (ieee->freq_band & IEEE80211_24GHZ_BAND)
+               for (i = 0; i < ieee->geo.bg_channels; i++)
+                       if (ieee->geo.bg[i].channel == channel)
+                               return i;
+
+       if (ieee->freq_band & IEEE80211_52GHZ_BAND)
+               for (i = 0; i < ieee->geo.a_channels; i++)
+                       if (ieee->geo.a[i].channel == channel)
+                               return i;
+
+       return -1;
+}
+
+u8 ieee80211_freq_to_channel(struct ieee80211_device * ieee, u32 freq)
+{
+       int i;
+
+       /* Driver needs to initialize the geography map before using
+        * these helper functions */
+       BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
+
+       freq /= 100000;
+
+       if (ieee->freq_band & IEEE80211_24GHZ_BAND)
+               for (i = 0; i < ieee->geo.bg_channels; i++)
+                       if (ieee->geo.bg[i].freq == freq)
+                               return ieee->geo.bg[i].channel;
+
+       if (ieee->freq_band & IEEE80211_52GHZ_BAND)
+               for (i = 0; i < ieee->geo.a_channels; i++)
+                       if (ieee->geo.a[i].freq == freq)
+                               return ieee->geo.a[i].channel;
+
+       return 0;
+}
+
+int ieee80211_set_geo(struct ieee80211_device *ieee,
+                     const struct ieee80211_geo *geo)
+{
+       memcpy(ieee->geo.name, geo->name, 3);
+       ieee->geo.name[3] = '\0';
+       ieee->geo.bg_channels = geo->bg_channels;
+       ieee->geo.a_channels = geo->a_channels;
+       memcpy(ieee->geo.bg, geo->bg, geo->bg_channels *
+              sizeof(struct ieee80211_channel));
+       memcpy(ieee->geo.a, geo->a, ieee->geo.a_channels *
+              sizeof(struct ieee80211_channel));
+       return 0;
+}
+
+const struct ieee80211_geo *ieee80211_get_geo(struct ieee80211_device *ieee)
+{
+       return &ieee->geo;
+}
+
+EXPORT_SYMBOL(ieee80211_is_valid_channel);
+EXPORT_SYMBOL(ieee80211_freq_to_channel);
+EXPORT_SYMBOL(ieee80211_channel_to_index);
+EXPORT_SYMBOL(ieee80211_set_geo);
+EXPORT_SYMBOL(ieee80211_get_geo);
index 6059e9e37123b711554c6e50a18daf8a5872c793..f66d792cd204b068976f7655e625cb4a21d99978 100644 (file)
@@ -1,6 +1,6 @@
 /*******************************************************************************
 
-  Copyright(c) 2004 Intel Corporation. All rights reserved.
+  Copyright(c) 2004-2005 Intel Corporation. All rights reserved.
 
   Portions of this file are based on the WEP enablement code provided by the
   Host AP project hostap-drivers v0.1.3
 
 #include <net/ieee80211.h>
 
-MODULE_DESCRIPTION("802.11 data/management/control stack");
-MODULE_AUTHOR
-    ("Copyright (C) 2004 Intel Corporation <jketreno@linux.intel.com>");
-MODULE_LICENSE("GPL");
+#define DRV_DESCRIPTION "802.11 data/management/control stack"
+#define DRV_NAME        "ieee80211"
+#define DRV_VERSION    IEEE80211_VERSION
+#define DRV_COPYRIGHT   "Copyright (C) 2004-2005 Intel Corporation <jketreno@linux.intel.com>"
 
-#define DRV_NAME "ieee80211"
+MODULE_VERSION(DRV_VERSION);
+MODULE_DESCRIPTION(DRV_DESCRIPTION);
+MODULE_AUTHOR(DRV_COPYRIGHT);
+MODULE_LICENSE("GPL");
 
 static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee)
 {
@@ -126,26 +129,34 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
 
        /* Default fragmentation threshold is maximum payload size */
        ieee->fts = DEFAULT_FTS;
+       ieee->rts = DEFAULT_FTS;
        ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
        ieee->open_wep = 1;
 
        /* Default to enabling full open WEP with host based encrypt/decrypt */
        ieee->host_encrypt = 1;
        ieee->host_decrypt = 1;
+       ieee->host_mc_decrypt = 1;
+
+       /* Host fragementation in Open mode. Default is enabled.
+        * Note: host fragmentation is always enabled if host encryption
+        * is enabled. For cards can do hardware encryption, they must do
+        * hardware fragmentation as well. So we don't need a variable
+        * like host_enc_frag. */
+       ieee->host_open_frag = 1;
        ieee->ieee802_1x = 1;   /* Default to supporting 802.1x */
 
        INIT_LIST_HEAD(&ieee->crypt_deinit_list);
        init_timer(&ieee->crypt_deinit_timer);
        ieee->crypt_deinit_timer.data = (unsigned long)ieee;
        ieee->crypt_deinit_timer.function = ieee80211_crypt_deinit_handler;
+       ieee->crypt_quiesced = 0;
 
        spin_lock_init(&ieee->lock);
 
        ieee->wpa_enabled = 0;
-       ieee->tkip_countermeasures = 0;
        ieee->drop_unencrypted = 0;
        ieee->privacy_invoked = 0;
-       ieee->ieee802_1x = 1;
 
        return dev;
 
@@ -161,6 +172,7 @@ void free_ieee80211(struct net_device *dev)
 
        int i;
 
+       ieee80211_crypt_quiescing(ieee);
        del_timer_sync(&ieee->crypt_deinit_timer);
        ieee80211_crypt_deinit_entries(ieee, 1);
 
@@ -195,38 +207,26 @@ static int show_debug_level(char *page, char **start, off_t offset,
 static int store_debug_level(struct file *file, const char __user * buffer,
                             unsigned long count, void *data)
 {
-       char buf[] = "0x00000000";
-       char *p = (char *)buf;
+       char buf[] = "0x00000000\n";
+       unsigned long len = min((unsigned long)sizeof(buf) - 1, count);
        unsigned long val;
 
-       if (count > sizeof(buf) - 1)
-               count = sizeof(buf) - 1;
-
-       if (copy_from_user(buf, buffer, count))
+       if (copy_from_user(buf, buffer, len))
                return count;
-       buf[count] = 0;
-       /*
-        * what a FPOS...  What, sscanf(buf, "%i", &val) would be too
-        * scary?
-        */
-       if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
-               p++;
-               if (p[0] == 'x' || p[0] == 'X')
-                       p++;
-               val = simple_strtoul(p, &p, 16);
-       } else
-               val = simple_strtoul(p, &p, 10);
-       if (p == buf)
+       buf[len] = 0;
+       if (sscanf(buf, "%li", &val) != 1)
                printk(KERN_INFO DRV_NAME
                       ": %s is not in hex or decimal form.\n", buf);
        else
                ieee80211_debug_level = val;
 
-       return strlen(buf);
+       return strnlen(buf, len);
 }
+#endif                         /* CONFIG_IEEE80211_DEBUG */
 
 static int __init ieee80211_init(void)
 {
+#ifdef CONFIG_IEEE80211_DEBUG
        struct proc_dir_entry *e;
 
        ieee80211_debug_level = debug;
@@ -246,26 +246,33 @@ static int __init ieee80211_init(void)
        e->read_proc = show_debug_level;
        e->write_proc = store_debug_level;
        e->data = NULL;
+#endif                         /* CONFIG_IEEE80211_DEBUG */
+
+       printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
+       printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
 
        return 0;
 }
 
 static void __exit ieee80211_exit(void)
 {
+#ifdef CONFIG_IEEE80211_DEBUG
        if (ieee80211_proc) {
                remove_proc_entry("debug_level", ieee80211_proc);
                remove_proc_entry(DRV_NAME, proc_net);
                ieee80211_proc = NULL;
        }
+#endif                         /* CONFIG_IEEE80211_DEBUG */
 }
 
+#ifdef CONFIG_IEEE80211_DEBUG
 #include <linux/moduleparam.h>
 module_param(debug, int, 0444);
 MODULE_PARM_DESC(debug, "debug output mask");
+#endif                         /* CONFIG_IEEE80211_DEBUG */
 
 module_exit(ieee80211_exit);
 module_init(ieee80211_init);
-#endif
 
 const char *escape_essid(const char *essid, u8 essid_len)
 {
index f7dcd854139e011c960643a76e2a40ae77566341..fcf05bf677b8983c75868f2b0249c77f896b4038 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
  * <jkmaline@cc.hut.fi>
  * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- * Copyright (c) 2004, Intel Corporation
+ * Copyright (c) 2004-2005, Intel Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -87,7 +87,7 @@ static struct ieee80211_frag_entry *ieee80211_frag_cache_find(struct
 
 /* Called only as a tasklet (software IRQ) */
 static struct sk_buff *ieee80211_frag_cache_get(struct ieee80211_device *ieee,
-                                               struct ieee80211_hdr *hdr)
+                                               struct ieee80211_hdr_4addr *hdr)
 {
        struct sk_buff *skb = NULL;
        u16 sc;
@@ -101,7 +101,7 @@ static struct sk_buff *ieee80211_frag_cache_get(struct ieee80211_device *ieee,
        if (frag == 0) {
                /* Reserve enough space to fit maximum frame length */
                skb = dev_alloc_skb(ieee->dev->mtu +
-                                   sizeof(struct ieee80211_hdr) +
+                                   sizeof(struct ieee80211_hdr_4addr) +
                                    8 /* LLC */  +
                                    2 /* alignment */  +
                                    8 /* WEP */  + ETH_ALEN /* WDS */ );
@@ -138,7 +138,7 @@ static struct sk_buff *ieee80211_frag_cache_get(struct ieee80211_device *ieee,
 
 /* Called only as a tasklet (software IRQ) */
 static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee,
-                                          struct ieee80211_hdr *hdr)
+                                          struct ieee80211_hdr_4addr *hdr)
 {
        u16 sc;
        unsigned int seq;
@@ -176,7 +176,7 @@ ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
                       ieee->dev->name);
                return 0;
 /*
-  hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr *)
+  hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr_4addr *)
   skb->data);*/
        }
 
@@ -232,13 +232,13 @@ static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
 {
        struct net_device *dev = ieee->dev;
        u16 fc, ethertype;
-       struct ieee80211_hdr *hdr;
+       struct ieee80211_hdr_3addr *hdr;
        u8 *pos;
 
        if (skb->len < 24)
                return 0;
 
-       hdr = (struct ieee80211_hdr *)skb->data;
+       hdr = (struct ieee80211_hdr_3addr *)skb->data;
        fc = le16_to_cpu(hdr->frame_ctl);
 
        /* check that the frame is unicast frame to us */
@@ -271,26 +271,15 @@ static inline int
 ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb,
                           struct ieee80211_crypt_data *crypt)
 {
-       struct ieee80211_hdr *hdr;
+       struct ieee80211_hdr_3addr *hdr;
        int res, hdrlen;
 
        if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
                return 0;
 
-       hdr = (struct ieee80211_hdr *)skb->data;
+       hdr = (struct ieee80211_hdr_3addr *)skb->data;
        hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
 
-#ifdef CONFIG_IEEE80211_CRYPT_TKIP
-       if (ieee->tkip_countermeasures && strcmp(crypt->ops->name, "TKIP") == 0) {
-               if (net_ratelimit()) {
-                       printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
-                              "received packet from " MAC_FMT "\n",
-                              ieee->dev->name, MAC_ARG(hdr->addr2));
-               }
-               return -1;
-       }
-#endif
-
        atomic_inc(&crypt->refcnt);
        res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
        atomic_dec(&crypt->refcnt);
@@ -314,13 +303,13 @@ ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee,
                                struct sk_buff *skb, int keyidx,
                                struct ieee80211_crypt_data *crypt)
 {
-       struct ieee80211_hdr *hdr;
+       struct ieee80211_hdr_3addr *hdr;
        int res, hdrlen;
 
        if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
                return 0;
 
-       hdr = (struct ieee80211_hdr *)skb->data;
+       hdr = (struct ieee80211_hdr_3addr *)skb->data;
        hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
 
        atomic_inc(&crypt->refcnt);
@@ -343,7 +332,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
                 struct ieee80211_rx_stats *rx_stats)
 {
        struct net_device *dev = ieee->dev;
-       struct ieee80211_hdr *hdr;
+       struct ieee80211_hdr_4addr *hdr;
        size_t hdrlen;
        u16 fc, type, stype, sc;
        struct net_device_stats *stats;
@@ -363,7 +352,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
        struct ieee80211_crypt_data *crypt = NULL;
        int keyidx = 0;
 
-       hdr = (struct ieee80211_hdr *)skb->data;
+       hdr = (struct ieee80211_hdr_4addr *)skb->data;
        stats = &ieee->stats;
 
        if (skb->len < 10) {
@@ -378,35 +367,50 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
        frag = WLAN_GET_SEQ_FRAG(sc);
        hdrlen = ieee80211_get_hdrlen(fc);
 
-#ifdef NOT_YET
-#if WIRELESS_EXT > 15
        /* Put this code here so that we avoid duplicating it in all
         * Rx paths. - Jean II */
 #ifdef IW_WIRELESS_SPY         /* defined in iw_handler.h */
        /* If spy monitoring on */
-       if (iface->spy_data.spy_number > 0) {
+       if (ieee->spy_data.spy_number > 0) {
                struct iw_quality wstats;
-               wstats.level = rx_stats->signal;
-               wstats.noise = rx_stats->noise;
-               wstats.updated = 6;     /* No qual value */
+
+               wstats.updated = 0;
+               if (rx_stats->mask & IEEE80211_STATMASK_RSSI) {
+                       wstats.level = rx_stats->rssi;
+                       wstats.updated |= IW_QUAL_LEVEL_UPDATED;
+               } else
+                       wstats.updated |= IW_QUAL_LEVEL_INVALID;
+
+               if (rx_stats->mask & IEEE80211_STATMASK_NOISE) {
+                       wstats.noise = rx_stats->noise;
+                       wstats.updated |= IW_QUAL_NOISE_UPDATED;
+               } else
+                       wstats.updated |= IW_QUAL_NOISE_INVALID;
+
+               if (rx_stats->mask & IEEE80211_STATMASK_SIGNAL) {
+                       wstats.qual = rx_stats->signal;
+                       wstats.updated |= IW_QUAL_QUAL_UPDATED;
+               } else
+                       wstats.updated |= IW_QUAL_QUAL_INVALID;
+
                /* Update spy records */
-               wireless_spy_update(dev, hdr->addr2, &wstats);
+               wireless_spy_update(ieee->dev, hdr->addr2, &wstats);
        }
 #endif                         /* IW_WIRELESS_SPY */
-#endif                         /* WIRELESS_EXT > 15 */
+
+#ifdef NOT_YET
        hostap_update_rx_stats(local->ap, hdr, rx_stats);
 #endif
 
-#if WIRELESS_EXT > 15
        if (ieee->iw_mode == IW_MODE_MONITOR) {
                ieee80211_monitor_rx(ieee, skb, rx_stats);
                stats->rx_packets++;
                stats->rx_bytes += skb->len;
                return 1;
        }
-#endif
 
-       if (ieee->host_decrypt) {
+       if (is_multicast_ether_addr(hdr->addr1) ? ieee->host_mc_decrypt :
+           ieee->host_decrypt) {
                int idx = 0;
                if (skb->len >= hdrlen + 3)
                        idx = skb->data[hdrlen + 3] >> 6;
@@ -531,6 +535,9 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 
        /* Nullfunc frames may have PS-bit set, so they must be passed to
         * hostap_handle_sta_rx() before being dropped here. */
+
+       stype &= ~IEEE80211_STYPE_QOS_DATA;
+
        if (stype != IEEE80211_STYPE_DATA &&
            stype != IEEE80211_STYPE_DATA_CFACK &&
            stype != IEEE80211_STYPE_DATA_CFPOLL &&
@@ -549,7 +556,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
            (keyidx = ieee80211_rx_frame_decrypt(ieee, 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 */
        // PR: FIXME: hostap has additional conditions in the "if" below:
@@ -603,7 +610,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, 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;
                ieee80211_frag_cache_invalidate(ieee, hdr);
        }
 
@@ -613,7 +620,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
            ieee80211_rx_frame_decrypt_msdu(ieee, 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) && !ieee->open_wep) {
                if (            /*ieee->ieee802_1x && */
                           ieee80211_is_eapol_frame(ieee, skb)) {
@@ -755,6 +762,264 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 
 #define MGMT_FRAME_FIXED_PART_LENGTH           0x24
 
+static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 };
+
+/*
+* Make ther structure we read from the beacon packet has
+* the right values
+*/
+static int ieee80211_verify_qos_info(struct ieee80211_qos_information_element
+                                    *info_element, int sub_type)
+{
+
+       if (info_element->qui_subtype != sub_type)
+               return -1;
+       if (memcmp(info_element->qui, qos_oui, QOS_OUI_LEN))
+               return -1;
+       if (info_element->qui_type != QOS_OUI_TYPE)
+               return -1;
+       if (info_element->version != QOS_VERSION_1)
+               return -1;
+
+       return 0;
+}
+
+/*
+ * Parse a QoS parameter element
+ */
+static int ieee80211_read_qos_param_element(struct ieee80211_qos_parameter_info
+                                           *element_param, struct ieee80211_info_element
+                                           *info_element)
+{
+       int ret = 0;
+       u16 size = sizeof(struct ieee80211_qos_parameter_info) - 2;
+
+       if ((info_element == NULL) || (element_param == NULL))
+               return -1;
+
+       if (info_element->id == QOS_ELEMENT_ID && info_element->len == size) {
+               memcpy(element_param->info_element.qui, info_element->data,
+                      info_element->len);
+               element_param->info_element.elementID = info_element->id;
+               element_param->info_element.length = info_element->len;
+       } else
+               ret = -1;
+       if (ret == 0)
+               ret = ieee80211_verify_qos_info(&element_param->info_element,
+                                               QOS_OUI_PARAM_SUB_TYPE);
+       return ret;
+}
+
+/*
+ * Parse a QoS information element
+ */
+static int ieee80211_read_qos_info_element(struct
+                                          ieee80211_qos_information_element
+                                          *element_info, struct ieee80211_info_element
+                                          *info_element)
+{
+       int ret = 0;
+       u16 size = sizeof(struct ieee80211_qos_information_element) - 2;
+
+       if (element_info == NULL)
+               return -1;
+       if (info_element == NULL)
+               return -1;
+
+       if ((info_element->id == QOS_ELEMENT_ID) && (info_element->len == size)) {
+               memcpy(element_info->qui, info_element->data,
+                      info_element->len);
+               element_info->elementID = info_element->id;
+               element_info->length = info_element->len;
+       } else
+               ret = -1;
+
+       if (ret == 0)
+               ret = ieee80211_verify_qos_info(element_info,
+                                               QOS_OUI_INFO_SUB_TYPE);
+       return ret;
+}
+
+/*
+ * Write QoS parameters from the ac parameters.
+ */
+static int ieee80211_qos_convert_ac_to_parameters(struct
+                                                 ieee80211_qos_parameter_info
+                                                 *param_elm, struct
+                                                 ieee80211_qos_parameters
+                                                 *qos_param)
+{
+       int rc = 0;
+       int i;
+       struct ieee80211_qos_ac_parameter *ac_params;
+       u32 txop;
+       u8 cw_min;
+       u8 cw_max;
+
+       for (i = 0; i < QOS_QUEUE_NUM; i++) {
+               ac_params = &(param_elm->ac_params_record[i]);
+
+               qos_param->aifs[i] = (ac_params->aci_aifsn) & 0x0F;
+               qos_param->aifs[i] -= (qos_param->aifs[i] < 2) ? 0 : 2;
+
+               cw_min = ac_params->ecw_min_max & 0x0F;
+               qos_param->cw_min[i] = (u16) ((1 << cw_min) - 1);
+
+               cw_max = (ac_params->ecw_min_max & 0xF0) >> 4;
+               qos_param->cw_max[i] = (u16) ((1 << cw_max) - 1);
+
+               qos_param->flag[i] =
+                   (ac_params->aci_aifsn & 0x10) ? 0x01 : 0x00;
+
+               txop = le16_to_cpu(ac_params->tx_op_limit) * 32;
+               qos_param->tx_op_limit[i] = (u16) txop;
+       }
+       return rc;
+}
+
+/*
+ * we have a generic data element which it may contain QoS information or
+ * parameters element. check the information element length to decide
+ * which type to read
+ */
+static int ieee80211_parse_qos_info_param_IE(struct ieee80211_info_element
+                                            *info_element,
+                                            struct ieee80211_network *network)
+{
+       int rc = 0;
+       struct ieee80211_qos_parameters *qos_param = NULL;
+       struct ieee80211_qos_information_element qos_info_element;
+
+       rc = ieee80211_read_qos_info_element(&qos_info_element, info_element);
+
+       if (rc == 0) {
+               network->qos_data.param_count = qos_info_element.ac_info & 0x0F;
+               network->flags |= NETWORK_HAS_QOS_INFORMATION;
+       } else {
+               struct ieee80211_qos_parameter_info param_element;
+
+               rc = ieee80211_read_qos_param_element(&param_element,
+                                                     info_element);
+               if (rc == 0) {
+                       qos_param = &(network->qos_data.parameters);
+                       ieee80211_qos_convert_ac_to_parameters(&param_element,
+                                                              qos_param);
+                       network->flags |= NETWORK_HAS_QOS_PARAMETERS;
+                       network->qos_data.param_count =
+                           param_element.info_element.ac_info & 0x0F;
+               }
+       }
+
+       if (rc == 0) {
+               IEEE80211_DEBUG_QOS("QoS is supported\n");
+               network->qos_data.supported = 1;
+       }
+       return rc;
+}
+
+static int ieee80211_handle_assoc_resp(struct ieee80211_device *ieee, struct ieee80211_assoc_response
+                                      *frame, struct ieee80211_rx_stats *stats)
+{
+       struct ieee80211_network network_resp;
+       struct ieee80211_network *network = &network_resp;
+       struct ieee80211_info_element *info_element;
+       struct net_device *dev = ieee->dev;
+       u16 left;
+
+       network->flags = 0;
+       network->qos_data.active = 0;
+       network->qos_data.supported = 0;
+       network->qos_data.param_count = 0;
+       network->qos_data.old_param_count = 0;
+
+       //network->atim_window = le16_to_cpu(frame->aid) & (0x3FFF);
+       network->atim_window = le16_to_cpu(frame->aid);
+       network->listen_interval = le16_to_cpu(frame->status);
+
+       info_element = frame->info_element;
+       left = stats->len - sizeof(*frame);
+
+       while (left >= sizeof(struct ieee80211_info_element)) {
+               if (sizeof(struct ieee80211_info_element) +
+                   info_element->len > left) {
+                       IEEE80211_DEBUG_QOS("ASSOC RESP: parse failed: "
+                                           "info_element->len + 2 > left : "
+                                           "info_element->len+2=%zd left=%d, id=%d.\n",
+                                           info_element->len +
+                                           sizeof(struct
+                                                  ieee80211_info_element),
+                                           left, info_element->id);
+                       return 1;
+               }
+
+               switch (info_element->id) {
+               case MFIE_TYPE_SSID:
+                       if (ieee80211_is_empty_essid(info_element->data,
+                                                    info_element->len)) {
+                               network->flags |= NETWORK_EMPTY_ESSID;
+                               break;
+                       }
+
+                       network->ssid_len = min(info_element->len,
+                                               (u8) IW_ESSID_MAX_SIZE);
+                       memcpy(network->ssid, info_element->data,
+                              network->ssid_len);
+                       if (network->ssid_len < IW_ESSID_MAX_SIZE)
+                               memset(network->ssid + network->ssid_len, 0,
+                                      IW_ESSID_MAX_SIZE - network->ssid_len);
+
+                       IEEE80211_DEBUG_QOS("MFIE_TYPE_SSID: '%s' len=%d.\n",
+                                           network->ssid, network->ssid_len);
+                       break;
+
+               case MFIE_TYPE_TIM:
+                       IEEE80211_DEBUG_QOS("MFIE_TYPE_TIM: ignored\n");
+                       break;
+
+               case MFIE_TYPE_IBSS_SET:
+                       IEEE80211_DEBUG_QOS("MFIE_TYPE_IBSS_SET: ignored\n");
+                       break;
+
+               case MFIE_TYPE_CHALLENGE:
+                       IEEE80211_DEBUG_QOS("MFIE_TYPE_CHALLENGE: ignored\n");
+                       break;
+
+               case MFIE_TYPE_GENERIC:
+                       IEEE80211_DEBUG_QOS("MFIE_TYPE_GENERIC: %d bytes\n",
+                                           info_element->len);
+                       ieee80211_parse_qos_info_param_IE(info_element,
+                                                         network);
+                       break;
+
+               case MFIE_TYPE_RSN:
+                       IEEE80211_DEBUG_QOS("MFIE_TYPE_RSN: %d bytes\n",
+                                           info_element->len);
+                       break;
+
+               case MFIE_TYPE_QOS_PARAMETER:
+                       printk("QoS Error need to parse QOS_PARAMETER IE\n");
+                       break;
+
+               default:
+                       IEEE80211_DEBUG_QOS("unsupported IE %d\n",
+                                           info_element->id);
+                       break;
+               }
+
+               left -= sizeof(struct ieee80211_info_element) +
+                   info_element->len;
+               info_element = (struct ieee80211_info_element *)
+                   &info_element->data[info_element->len];
+       }
+
+       if (ieee->handle_assoc_response != NULL)
+               ieee->handle_assoc_response(dev, frame, network);
+
+       return 0;
+}
+
+/***************************************************/
+
 static inline int ieee80211_is_ofdm_rate(u8 rate)
 {
        switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
@@ -771,8 +1036,7 @@ static inline int ieee80211_is_ofdm_rate(u8 rate)
        return 0;
 }
 
-static inline int ieee80211_network_init(struct ieee80211_device *ieee,
-                                        struct ieee80211_probe_response
+static inline int ieee80211_network_init(struct ieee80211_device *ieee, struct ieee80211_probe_response
                                         *beacon,
                                         struct ieee80211_network *network,
                                         struct ieee80211_rx_stats *stats)
@@ -784,14 +1048,17 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee,
        struct ieee80211_info_element *info_element;
        u16 left;
        u8 i;
+       network->qos_data.active = 0;
+       network->qos_data.supported = 0;
+       network->qos_data.param_count = 0;
 
        /* Pull out fixed field data */
        memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
-       network->capability = beacon->capability;
+       network->capability = le16_to_cpu(beacon->capability);
        network->last_scanned = jiffies;
-       network->time_stamp[0] = beacon->time_stamp[0];
-       network->time_stamp[1] = beacon->time_stamp[1];
-       network->beacon_interval = beacon->beacon_interval;
+       network->time_stamp[0] = le32_to_cpu(beacon->time_stamp[0]);
+       network->time_stamp[1] = le32_to_cpu(beacon->time_stamp[1]);
+       network->beacon_interval = le16_to_cpu(beacon->beacon_interval);
        /* Where to pull this? beacon->listen_interval; */
        network->listen_interval = 0x0A;
        network->rates_len = network->rates_ex_len = 0;
@@ -799,6 +1066,8 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee,
        network->ssid_len = 0;
        network->flags = 0;
        network->atim_window = 0;
+       network->erp_value = (network->capability & WLAN_CAPABILITY_IBSS) ?
+           0x3 : 0x0;
 
        if (stats->freq == IEEE80211_52GHZ_BAND) {
                /* for A band (No DS info) */
@@ -809,15 +1078,13 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee,
        network->wpa_ie_len = 0;
        network->rsn_ie_len = 0;
 
-       info_element = &beacon->info_element;
-       left = stats->len - ((void *)info_element - (void *)beacon);
-       while (left >= sizeof(struct ieee80211_info_element_hdr)) {
-               if (sizeof(struct ieee80211_info_element_hdr) +
-                   info_element->len > left) {
+       info_element = beacon->info_element;
+       left = stats->len - sizeof(*beacon);
+       while (left >= sizeof(*info_element)) {
+               if (sizeof(*info_element) + info_element->len > left) {
                        IEEE80211_DEBUG_SCAN
                            ("SCAN: parse failed: info_element->len + 2 > left : info_element->len+2=%Zd left=%d.\n",
-                            info_element->len +
-                            sizeof(struct ieee80211_info_element), left);
+                            info_element->len + sizeof(*info_element), left);
                        return 1;
                }
 
@@ -845,15 +1112,14 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee,
 #ifdef CONFIG_IEEE80211_DEBUG
                        p = rates_str;
 #endif
-                       network->rates_len =
-                           min(info_element->len, MAX_RATES_LENGTH);
+                       network->rates_len = min(info_element->len,
+                                                MAX_RATES_LENGTH);
                        for (i = 0; i < network->rates_len; i++) {
                                network->rates[i] = info_element->data[i];
 #ifdef CONFIG_IEEE80211_DEBUG
-                               p += snprintf(p,
-                                             sizeof(rates_str) - (p -
-                                                                  rates_str),
-                                             "%02X ", network->rates[i]);
+                               p += snprintf(p, sizeof(rates_str) -
+                                             (p - rates_str), "%02X ",
+                                             network->rates[i]);
 #endif
                                if (ieee80211_is_ofdm_rate
                                    (info_element->data[i])) {
@@ -873,15 +1139,14 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee,
 #ifdef CONFIG_IEEE80211_DEBUG
                        p = rates_str;
 #endif
-                       network->rates_ex_len =
-                           min(info_element->len, MAX_RATES_EX_LENGTH);
+                       network->rates_ex_len = min(info_element->len,
+                                                   MAX_RATES_EX_LENGTH);
                        for (i = 0; i < network->rates_ex_len; i++) {
                                network->rates_ex[i] = info_element->data[i];
 #ifdef CONFIG_IEEE80211_DEBUG
-                               p += snprintf(p,
-                                             sizeof(rates_str) - (p -
-                                                                  rates_str),
-                                             "%02X ", network->rates[i]);
+                               p += snprintf(p, sizeof(rates_str) -
+                                             (p - rates_str), "%02X ",
+                                             network->rates[i]);
 #endif
                                if (ieee80211_is_ofdm_rate
                                    (info_element->data[i])) {
@@ -916,8 +1181,16 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee,
                        IEEE80211_DEBUG_SCAN("MFIE_TYPE_TIM: ignored\n");
                        break;
 
+               case MFIE_TYPE_ERP_INFO:
+                       network->erp_value = info_element->data[0];
+                       IEEE80211_DEBUG_SCAN("MFIE_TYPE_ERP_SET: %d\n",
+                                            network->erp_value);
+                       break;
+
                case MFIE_TYPE_IBSS_SET:
-                       IEEE80211_DEBUG_SCAN("MFIE_TYPE_IBSS_SET: ignored\n");
+                       network->atim_window = info_element->data[0];
+                       IEEE80211_DEBUG_SCAN("MFIE_TYPE_IBSS_SET: %d\n",
+                                            network->atim_window);
                        break;
 
                case MFIE_TYPE_CHALLENGE:
@@ -927,6 +1200,10 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee,
                case MFIE_TYPE_GENERIC:
                        IEEE80211_DEBUG_SCAN("MFIE_TYPE_GENERIC: %d bytes\n",
                                             info_element->len);
+                       if (!ieee80211_parse_qos_info_param_IE(info_element,
+                                                              network))
+                               break;
+
                        if (info_element->len >= 4 &&
                            info_element->data[0] == 0x00 &&
                            info_element->data[1] == 0x50 &&
@@ -948,14 +1225,18 @@ static inline int ieee80211_network_init(struct ieee80211_device *ieee,
                               network->rsn_ie_len);
                        break;
 
+               case MFIE_TYPE_QOS_PARAMETER:
+                       printk(KERN_ERR
+                              "QoS Error need to parse QOS_PARAMETER IE\n");
+                       break;
+
                default:
                        IEEE80211_DEBUG_SCAN("unsupported IE %d\n",
                                             info_element->id);
                        break;
                }
 
-               left -= sizeof(struct ieee80211_info_element_hdr) +
-                   info_element->len;
+               left -= sizeof(*info_element) + info_element->len;
                info_element = (struct ieee80211_info_element *)
                    &info_element->data[info_element->len];
        }
@@ -1002,6 +1283,9 @@ static inline int is_same_network(struct ieee80211_network *src,
 static inline void update_network(struct ieee80211_network *dst,
                                  struct ieee80211_network *src)
 {
+       int qos_active;
+       u8 old_param;
+
        memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats));
        dst->capability = src->capability;
        memcpy(dst->rates, src->rates, src->rates_len);
@@ -1017,6 +1301,7 @@ static inline void update_network(struct ieee80211_network *dst,
        dst->beacon_interval = src->beacon_interval;
        dst->listen_interval = src->listen_interval;
        dst->atim_window = src->atim_window;
+       dst->erp_value = src->erp_value;
 
        memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len);
        dst->wpa_ie_len = src->wpa_ie_len;
@@ -1024,22 +1309,48 @@ static inline void update_network(struct ieee80211_network *dst,
        dst->rsn_ie_len = src->rsn_ie_len;
 
        dst->last_scanned = jiffies;
+       qos_active = src->qos_data.active;
+       old_param = dst->qos_data.old_param_count;
+       if (dst->flags & NETWORK_HAS_QOS_MASK)
+               memcpy(&dst->qos_data, &src->qos_data,
+                      sizeof(struct ieee80211_qos_data));
+       else {
+               dst->qos_data.supported = src->qos_data.supported;
+               dst->qos_data.param_count = src->qos_data.param_count;
+       }
+
+       if (dst->qos_data.supported == 1) {
+               if (dst->ssid_len)
+                       IEEE80211_DEBUG_QOS
+                           ("QoS the network %s is QoS supported\n",
+                            dst->ssid);
+               else
+                       IEEE80211_DEBUG_QOS
+                           ("QoS the network is QoS supported\n");
+       }
+       dst->qos_data.active = qos_active;
+       dst->qos_data.old_param_count = old_param;
+
        /* dst->last_associate is not overwritten */
 }
 
+static inline int is_beacon(int fc)
+{
+       return (WLAN_FC_GET_STYPE(le16_to_cpu(fc)) == IEEE80211_STYPE_BEACON);
+}
+
 static inline void ieee80211_process_probe_response(struct ieee80211_device
-                                                   *ieee,
-                                                   struct
+                                                   *ieee, struct
                                                    ieee80211_probe_response
-                                                   *beacon,
-                                                   struct ieee80211_rx_stats
+                                                   *beacon, struct ieee80211_rx_stats
                                                    *stats)
 {
+       struct net_device *dev = ieee->dev;
        struct ieee80211_network network;
        struct ieee80211_network *target;
        struct ieee80211_network *oldest = NULL;
 #ifdef CONFIG_IEEE80211_DEBUG
-       struct ieee80211_info_element *info_element = &beacon->info_element;
+       struct ieee80211_info_element *info_element = beacon->info_element;
 #endif
        unsigned long flags;
 
@@ -1070,10 +1381,10 @@ static inline void ieee80211_process_probe_response(struct ieee80211_device
                                     escape_essid(info_element->data,
                                                  info_element->len),
                                     MAC_ARG(beacon->header.addr3),
-                                    WLAN_FC_GET_STYPE(beacon->header.
-                                                      frame_ctl) ==
-                                    IEEE80211_STYPE_PROBE_RESP ?
-                                    "PROBE RESPONSE" : "BEACON");
+                                    is_beacon(le16_to_cpu
+                                              (beacon->header.
+                                               frame_ctl)) ?
+                                    "BEACON" : "PROBE RESPONSE");
                return;
        }
 
@@ -1122,10 +1433,10 @@ static inline void ieee80211_process_probe_response(struct ieee80211_device
                                     escape_essid(network.ssid,
                                                  network.ssid_len),
                                     MAC_ARG(network.bssid),
-                                    WLAN_FC_GET_STYPE(beacon->header.
-                                                      frame_ctl) ==
-                                    IEEE80211_STYPE_PROBE_RESP ?
-                                    "PROBE RESPONSE" : "BEACON");
+                                    is_beacon(le16_to_cpu
+                                              (beacon->header.
+                                               frame_ctl)) ?
+                                    "BEACON" : "PROBE RESPONSE");
 #endif
                memcpy(target, &network, sizeof(*target));
                list_add_tail(&target->list, &ieee->network_list);
@@ -1134,34 +1445,60 @@ static inline void ieee80211_process_probe_response(struct ieee80211_device
                                     escape_essid(target->ssid,
                                                  target->ssid_len),
                                     MAC_ARG(target->bssid),
-                                    WLAN_FC_GET_STYPE(beacon->header.
-                                                      frame_ctl) ==
-                                    IEEE80211_STYPE_PROBE_RESP ?
-                                    "PROBE RESPONSE" : "BEACON");
+                                    is_beacon(le16_to_cpu
+                                              (beacon->header.
+                                               frame_ctl)) ?
+                                    "BEACON" : "PROBE RESPONSE");
                update_network(target, &network);
        }
 
        spin_unlock_irqrestore(&ieee->lock, flags);
+
+       if (is_beacon(le16_to_cpu(beacon->header.frame_ctl))) {
+               if (ieee->handle_beacon != NULL)
+                       ieee->handle_beacon(dev, beacon, &network);
+       } else {
+               if (ieee->handle_probe_response != NULL)
+                       ieee->handle_probe_response(dev, beacon, &network);
+       }
 }
 
 void ieee80211_rx_mgt(struct ieee80211_device *ieee,
-                     struct ieee80211_hdr *header,
+                     struct ieee80211_hdr_4addr *header,
                      struct ieee80211_rx_stats *stats)
 {
-       switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
+       switch (WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl))) {
        case IEEE80211_STYPE_ASSOC_RESP:
                IEEE80211_DEBUG_MGMT("received ASSOCIATION RESPONSE (%d)\n",
-                                    WLAN_FC_GET_STYPE(header->frame_ctl));
+                                    WLAN_FC_GET_STYPE(le16_to_cpu
+                                                      (header->frame_ctl)));
+               ieee80211_handle_assoc_resp(ieee,
+                                           (struct ieee80211_assoc_response *)
+                                           header, stats);
                break;
 
        case IEEE80211_STYPE_REASSOC_RESP:
                IEEE80211_DEBUG_MGMT("received REASSOCIATION RESPONSE (%d)\n",
-                                    WLAN_FC_GET_STYPE(header->frame_ctl));
+                                    WLAN_FC_GET_STYPE(le16_to_cpu
+                                                      (header->frame_ctl)));
+               break;
+
+       case IEEE80211_STYPE_PROBE_REQ:
+               IEEE80211_DEBUG_MGMT("recieved auth (%d)\n",
+                                    WLAN_FC_GET_STYPE(le16_to_cpu
+                                                      (header->frame_ctl)));
+
+               if (ieee->handle_probe_request != NULL)
+                       ieee->handle_probe_request(ieee->dev,
+                                                  (struct
+                                                   ieee80211_probe_request *)
+                                                  header, stats);
                break;
 
        case IEEE80211_STYPE_PROBE_RESP:
                IEEE80211_DEBUG_MGMT("received PROBE RESPONSE (%d)\n",
-                                    WLAN_FC_GET_STYPE(header->frame_ctl));
+                                    WLAN_FC_GET_STYPE(le16_to_cpu
+                                                      (header->frame_ctl)));
                IEEE80211_DEBUG_SCAN("Probe response\n");
                ieee80211_process_probe_response(ieee,
                                                 (struct
@@ -1171,20 +1508,46 @@ void ieee80211_rx_mgt(struct ieee80211_device *ieee,
 
        case IEEE80211_STYPE_BEACON:
                IEEE80211_DEBUG_MGMT("received BEACON (%d)\n",
-                                    WLAN_FC_GET_STYPE(header->frame_ctl));
+                                    WLAN_FC_GET_STYPE(le16_to_cpu
+                                                      (header->frame_ctl)));
                IEEE80211_DEBUG_SCAN("Beacon\n");
                ieee80211_process_probe_response(ieee,
                                                 (struct
                                                  ieee80211_probe_response *)
                                                 header, stats);
                break;
+       case IEEE80211_STYPE_AUTH:
+
+               IEEE80211_DEBUG_MGMT("recieved auth (%d)\n",
+                                    WLAN_FC_GET_STYPE(le16_to_cpu
+                                                      (header->frame_ctl)));
+
+               if (ieee->handle_auth != NULL)
+                       ieee->handle_auth(ieee->dev,
+                                         (struct ieee80211_auth *)header);
+               break;
 
+       case IEEE80211_STYPE_DISASSOC:
+               if (ieee->handle_disassoc != NULL)
+                       ieee->handle_disassoc(ieee->dev,
+                                             (struct ieee80211_disassoc *)
+                                             header);
+               break;
+
+       case IEEE80211_STYPE_DEAUTH:
+               printk("DEAUTH from AP\n");
+               if (ieee->handle_deauth != NULL)
+                       ieee->handle_deauth(ieee->dev, (struct ieee80211_auth *)
+                                           header);
+               break;
        default:
                IEEE80211_DEBUG_MGMT("received UNKNOWN (%d)\n",
-                                    WLAN_FC_GET_STYPE(header->frame_ctl));
+                                    WLAN_FC_GET_STYPE(le16_to_cpu
+                                                      (header->frame_ctl)));
                IEEE80211_WARNING("%s: Unknown management packet: %d\n",
                                  ieee->dev->name,
-                                 WLAN_FC_GET_STYPE(header->frame_ctl));
+                                 WLAN_FC_GET_STYPE(le16_to_cpu
+                                                   (header->frame_ctl)));
                break;
        }
 }
index f9153671168e7a5cae0432e0975a0b9b7f6780e5..e860777ab8d34cd4fa37cebfca694f40db1ac02f 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
 
-  Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
+  Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of version 2 of the GNU General Public License as
@@ -128,7 +128,7 @@ payload of each frame is reduced to 492 bytes.
 static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
 static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
 
-static inline int ieee80211_put_snap(u8 * data, u16 h_proto)
+static inline int ieee80211_copy_snap(u8 * data, u16 h_proto)
 {
        struct ieee80211_snap_hdr *snap;
        u8 *oui;
@@ -157,31 +157,11 @@ static inline int ieee80211_encrypt_fragment(struct ieee80211_device *ieee,
        struct ieee80211_crypt_data *crypt = ieee->crypt[ieee->tx_keyidx];
        int res;
 
-#ifdef CONFIG_IEEE80211_CRYPT_TKIP
-       struct ieee80211_hdr *header;
-
-       if (ieee->tkip_countermeasures &&
-           crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
-               header = (struct ieee80211_hdr *)frag->data;
-               if (net_ratelimit()) {
-                       printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
-                              "TX packet to " MAC_FMT "\n",
-                              ieee->dev->name, MAC_ARG(header->addr1));
-               }
-               return -1;
-       }
-#endif
        /* To encrypt, frame format is:
         * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
-
-       // PR: FIXME: Copied from hostap. Check fragmentation/MSDU/MPDU encryption.
-       /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
-        * call both MSDU and MPDU encryption functions from here. */
        atomic_inc(&crypt->refcnt);
        res = 0;
-       if (crypt->ops->encrypt_msdu)
-               res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv);
-       if (res == 0 && crypt->ops->encrypt_mpdu)
+       if (crypt->ops->encrypt_mpdu)
                res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv);
 
        atomic_dec(&crypt->refcnt);
@@ -236,25 +216,31 @@ static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
        return txb;
 }
 
-/* SKBs are added to the ieee->tx_queue. */
+/* Incoming skb is converted to a txb which consists of
+ * a block of 802.11 fragment packets (stored as skbs) */
 int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct ieee80211_device *ieee = netdev_priv(dev);
        struct ieee80211_txb *txb = NULL;
-       struct ieee80211_hdr *frag_hdr;
-       int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
+       struct ieee80211_hdr_3addr *frag_hdr;
+       int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size,
+           rts_required;
        unsigned long flags;
        struct net_device_stats *stats = &ieee->stats;
-       int ether_type, encrypt;
+       int ether_type, encrypt, host_encrypt, host_encrypt_msdu, host_build_iv;
        int bytes, fc, hdr_len;
        struct sk_buff *skb_frag;
-       struct ieee80211_hdr header = { /* Ensure zero initialized */
+       struct ieee80211_hdr_3addr header = {   /* Ensure zero initialized */
                .duration_id = 0,
                .seq_ctl = 0
        };
        u8 dest[ETH_ALEN], src[ETH_ALEN];
-
        struct ieee80211_crypt_data *crypt;
+       int priority = skb->priority;
+       int snapped = 0;
+
+       if (ieee->is_queue_full && (*ieee->is_queue_full) (dev, priority))
+               return NETDEV_TX_BUSY;
 
        spin_lock_irqsave(&ieee->lock, flags);
 
@@ -276,7 +262,11 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
        crypt = ieee->crypt[ieee->tx_keyidx];
 
        encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
-           ieee->host_encrypt && crypt && crypt->ops;
+           ieee->sec.encrypt;
+
+       host_encrypt = ieee->host_encrypt && encrypt;
+       host_encrypt_msdu = ieee->host_encrypt_msdu && encrypt;
+       host_build_iv = ieee->host_build_iv && encrypt;
 
        if (!encrypt && ieee->ieee802_1x &&
            ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
@@ -285,8 +275,8 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
        }
 
        /* Save source and destination addresses */
-       memcpy(&dest, skb->data, ETH_ALEN);
-       memcpy(&src, skb->data + ETH_ALEN, ETH_ALEN);
+       memcpy(dest, skb->data, ETH_ALEN);
+       memcpy(src, skb->data + ETH_ALEN, ETH_ALEN);
 
        /* Advance the SKB to the start of the payload */
        skb_pull(skb, sizeof(struct ethhdr));
@@ -294,7 +284,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
        /* Determine total amount of storage required for TXB packets */
        bytes = skb->len + SNAP_SIZE + sizeof(u16);
 
-       if (encrypt)
+       if (host_encrypt)
                fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |
                    IEEE80211_FCTL_PROTECTED;
        else
@@ -302,50 +292,90 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
 
        if (ieee->iw_mode == IW_MODE_INFRA) {
                fc |= IEEE80211_FCTL_TODS;
-               /* To DS: Addr1 = BSSID, Addr2 = SA,
-                  Addr3 = DA */
-               memcpy(&header.addr1, ieee->bssid, ETH_ALEN);
-               memcpy(&header.addr2, &src, ETH_ALEN);
-               memcpy(&header.addr3, &dest, ETH_ALEN);
+               /* To DS: Addr1 = BSSID, Addr2 = SA, Addr3 = DA */
+               memcpy(header.addr1, ieee->bssid, ETH_ALEN);
+               memcpy(header.addr2, src, ETH_ALEN);
+               memcpy(header.addr3, dest, ETH_ALEN);
        } else if (ieee->iw_mode == IW_MODE_ADHOC) {
-               /* not From/To DS: Addr1 = DA, Addr2 = SA,
-                  Addr3 = BSSID */
-               memcpy(&header.addr1, dest, ETH_ALEN);
-               memcpy(&header.addr2, src, ETH_ALEN);
-               memcpy(&header.addr3, ieee->bssid, ETH_ALEN);
+               /* not From/To DS: Addr1 = DA, Addr2 = SA, Addr3 = BSSID */
+               memcpy(header.addr1, dest, ETH_ALEN);
+               memcpy(header.addr2, src, ETH_ALEN);
+               memcpy(header.addr3, ieee->bssid, ETH_ALEN);
        }
        header.frame_ctl = cpu_to_le16(fc);
        hdr_len = IEEE80211_3ADDR_LEN;
 
-       /* Determine fragmentation size based on destination (multicast
-        * and broadcast are not fragmented) */
-       if (is_multicast_ether_addr(dest) || is_broadcast_ether_addr(dest))
-               frag_size = MAX_FRAG_THRESHOLD;
-       else
-               frag_size = ieee->fts;
+       /* Encrypt msdu first on the whole data packet. */
+       if ((host_encrypt || host_encrypt_msdu) &&
+           crypt && crypt->ops && crypt->ops->encrypt_msdu) {
+               int res = 0;
+               int len = bytes + hdr_len + crypt->ops->extra_msdu_prefix_len +
+                   crypt->ops->extra_msdu_postfix_len;
+               struct sk_buff *skb_new = dev_alloc_skb(len);
+
+               if (unlikely(!skb_new))
+                       goto failed;
+
+               skb_reserve(skb_new, crypt->ops->extra_msdu_prefix_len);
+               memcpy(skb_put(skb_new, hdr_len), &header, hdr_len);
+               snapped = 1;
+               ieee80211_copy_snap(skb_put(skb_new, SNAP_SIZE + sizeof(u16)),
+                                   ether_type);
+               memcpy(skb_put(skb_new, skb->len), skb->data, skb->len);
+               res = crypt->ops->encrypt_msdu(skb_new, hdr_len, crypt->priv);
+               if (res < 0) {
+                       IEEE80211_ERROR("msdu encryption failed\n");
+                       dev_kfree_skb_any(skb_new);
+                       goto failed;
+               }
+               dev_kfree_skb_any(skb);
+               skb = skb_new;
+               bytes += crypt->ops->extra_msdu_prefix_len +
+                   crypt->ops->extra_msdu_postfix_len;
+               skb_pull(skb, hdr_len);
+       }
 
-       /* Determine amount of payload per fragment.  Regardless of if
-        * this stack is providing the full 802.11 header, one will
-        * eventually be affixed to this fragment -- so we must account for
-        * it when determining the amount of payload space. */
-       bytes_per_frag = frag_size - IEEE80211_3ADDR_LEN;
-       if (ieee->config &
-           (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
-               bytes_per_frag -= IEEE80211_FCS_LEN;
-
-       /* Each fragment may need to have room for encryptiong pre/postfix */
-       if (encrypt)
-               bytes_per_frag -= crypt->ops->extra_prefix_len +
-                   crypt->ops->extra_postfix_len;
-
-       /* Number of fragments is the total bytes_per_frag /
-        * payload_per_fragment */
-       nr_frags = bytes / bytes_per_frag;
-       bytes_last_frag = bytes % bytes_per_frag;
-       if (bytes_last_frag)
+       if (host_encrypt || ieee->host_open_frag) {
+               /* Determine fragmentation size based on destination (multicast
+                * and broadcast are not fragmented) */
+               if (is_multicast_ether_addr(dest))
+                       frag_size = MAX_FRAG_THRESHOLD;
+               else
+                       frag_size = ieee->fts;
+
+               /* Determine amount of payload per fragment.  Regardless of if
+                * this stack is providing the full 802.11 header, one will
+                * eventually be affixed to this fragment -- so we must account
+                * for it when determining the amount of payload space. */
+               bytes_per_frag = frag_size - IEEE80211_3ADDR_LEN;
+               if (ieee->config &
+                   (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
+                       bytes_per_frag -= IEEE80211_FCS_LEN;
+
+               /* Each fragment may need to have room for encryptiong
+                * pre/postfix */
+               if (host_encrypt)
+                       bytes_per_frag -= crypt->ops->extra_mpdu_prefix_len +
+                           crypt->ops->extra_mpdu_postfix_len;
+
+               /* Number of fragments is the total
+                * bytes_per_frag / payload_per_fragment */
+               nr_frags = bytes / bytes_per_frag;
+               bytes_last_frag = bytes % bytes_per_frag;
+               if (bytes_last_frag)
+                       nr_frags++;
+               else
+                       bytes_last_frag = bytes_per_frag;
+       } else {
+               nr_frags = 1;
+               bytes_per_frag = bytes_last_frag = bytes;
+               frag_size = bytes + IEEE80211_3ADDR_LEN;
+       }
+
+       rts_required = (frag_size > ieee->rts
+                       && ieee->config & CFG_IEEE80211_RTS);
+       if (rts_required)
                nr_frags++;
-       else
-               bytes_last_frag = bytes_per_frag;
 
        /* When we allocate the TXB we allocate enough space for the reserve
         * and full fragment bytes (bytes_per_frag doesn't include prefix,
@@ -357,15 +387,47 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
                goto failed;
        }
        txb->encrypted = encrypt;
-       txb->payload_size = bytes;
+       if (host_encrypt)
+               txb->payload_size = frag_size * (nr_frags - 1) +
+                   bytes_last_frag;
+       else
+               txb->payload_size = bytes;
+
+       if (rts_required) {
+               skb_frag = txb->fragments[0];
+               frag_hdr =
+                   (struct ieee80211_hdr_3addr *)skb_put(skb_frag, hdr_len);
+
+               /*
+                * Set header frame_ctl to the RTS.
+                */
+               header.frame_ctl =
+                   cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
+               memcpy(frag_hdr, &header, hdr_len);
 
-       for (i = 0; i < nr_frags; i++) {
+               /*
+                * Restore header frame_ctl to the original data setting.
+                */
+               header.frame_ctl = cpu_to_le16(fc);
+
+               if (ieee->config &
+                   (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
+                       skb_put(skb_frag, 4);
+
+               txb->rts_included = 1;
+               i = 1;
+       } else
+               i = 0;
+
+       for (; i < nr_frags; i++) {
                skb_frag = txb->fragments[i];
 
-               if (encrypt)
-                       skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
+               if (host_encrypt || host_build_iv)
+                       skb_reserve(skb_frag,
+                                   crypt->ops->extra_mpdu_prefix_len);
 
-               frag_hdr = (struct ieee80211_hdr *)skb_put(skb_frag, hdr_len);
+               frag_hdr =
+                   (struct ieee80211_hdr_3addr *)skb_put(skb_frag, hdr_len);
                memcpy(frag_hdr, &header, hdr_len);
 
                /* If this is not the last fragment, then add the MOREFRAGS
@@ -379,11 +441,10 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
                        bytes = bytes_last_frag;
                }
 
-               /* Put a SNAP header on the first fragment */
-               if (i == 0) {
-                       ieee80211_put_snap(skb_put
-                                          (skb_frag, SNAP_SIZE + sizeof(u16)),
-                                          ether_type);
+               if (i == 0 && !snapped) {
+                       ieee80211_copy_snap(skb_put
+                                           (skb_frag, SNAP_SIZE + sizeof(u16)),
+                                           ether_type);
                        bytes -= SNAP_SIZE + sizeof(u16);
                }
 
@@ -394,8 +455,19 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
 
                /* Encryption routine will move the header forward in order
                 * to insert the IV between the header and the payload */
-               if (encrypt)
+               if (host_encrypt)
                        ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
+               else if (host_build_iv) {
+                       struct ieee80211_crypt_data *crypt;
+
+                       crypt = ieee->crypt[ieee->tx_keyidx];
+                       atomic_inc(&crypt->refcnt);
+                       if (crypt->ops->build_iv)
+                               crypt->ops->build_iv(skb_frag, hdr_len,
+                                                    crypt->priv);
+                       atomic_dec(&crypt->refcnt);
+               }
+
                if (ieee->config &
                    (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
                        skb_put(skb_frag, 4);
@@ -407,11 +479,20 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
        dev_kfree_skb_any(skb);
 
        if (txb) {
-               if ((*ieee->hard_start_xmit) (txb, dev) == 0) {
+               int ret = (*ieee->hard_start_xmit) (txb, dev, priority);
+               if (ret == 0) {
                        stats->tx_packets++;
                        stats->tx_bytes += txb->payload_size;
                        return 0;
                }
+
+               if (ret == NETDEV_TX_BUSY) {
+                       printk(KERN_ERR "%s: NETDEV_TX_BUSY returned; "
+                              "driver should report queue full via "
+                              "ieee_device->is_queue_full.\n",
+                              ieee->dev->name);
+               }
+
                ieee80211_txb_free(txb);
        }
 
@@ -422,7 +503,72 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
        netif_stop_queue(dev);
        stats->tx_errors++;
        return 1;
+}
+
+/* Incoming 802.11 strucure is converted to a TXB
+ * a block of 802.11 fragment packets (stored as skbs) */
+int ieee80211_tx_frame(struct ieee80211_device *ieee,
+                      struct ieee80211_hdr *frame, int len)
+{
+       struct ieee80211_txb *txb = NULL;
+       unsigned long flags;
+       struct net_device_stats *stats = &ieee->stats;
+       struct sk_buff *skb_frag;
+       int priority = -1;
+
+       spin_lock_irqsave(&ieee->lock, flags);
 
+       /* If there is no driver handler to take the TXB, dont' bother
+        * creating it... */
+       if (!ieee->hard_start_xmit) {
+               printk(KERN_WARNING "%s: No xmit handler.\n", ieee->dev->name);
+               goto success;
+       }
+
+       if (unlikely(len < 24)) {
+               printk(KERN_WARNING "%s: skb too small (%d).\n",
+                      ieee->dev->name, len);
+               goto success;
+       }
+
+       /* When we allocate the TXB we allocate enough space for the reserve
+        * and full fragment bytes (bytes_per_frag doesn't include prefix,
+        * postfix, header, FCS, etc.) */
+       txb = ieee80211_alloc_txb(1, len, GFP_ATOMIC);
+       if (unlikely(!txb)) {
+               printk(KERN_WARNING "%s: Could not allocate TXB\n",
+                      ieee->dev->name);
+               goto failed;
+       }
+       txb->encrypted = 0;
+       txb->payload_size = len;
+
+       skb_frag = txb->fragments[0];
+
+       memcpy(skb_put(skb_frag, len), frame, len);
+
+       if (ieee->config &
+           (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
+               skb_put(skb_frag, 4);
+
+      success:
+       spin_unlock_irqrestore(&ieee->lock, flags);
+
+       if (txb) {
+               if ((*ieee->hard_start_xmit) (txb, ieee->dev, priority) == 0) {
+                       stats->tx_packets++;
+                       stats->tx_bytes += txb->payload_size;
+                       return 0;
+               }
+               ieee80211_txb_free(txb);
+       }
+       return 0;
+
+      failed:
+       spin_unlock_irqrestore(&ieee->lock, flags);
+       stats->tx_errors++;
+       return 1;
 }
 
+EXPORT_SYMBOL(ieee80211_tx_frame);
 EXPORT_SYMBOL(ieee80211_txb_free);
index 94882f39b0728f9ec92c11f7545f9755bdd10c90..ee7a70a132500c5834c8bb8d5e826f2bb8c0c235 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
 
-  Copyright(c) 2004 Intel Corporation. All rights reserved.
+  Copyright(c) 2004-2005 Intel Corporation. All rights reserved.
 
   Portions of this file are based on the WEP enablement code provided by the
   Host AP project hostap-drivers v0.1.3
@@ -32,6 +32,7 @@
 
 #include <linux/kmod.h>
 #include <linux/module.h>
+#include <linux/jiffies.h>
 
 #include <net/ieee80211.h>
 #include <linux/wireless.h>
@@ -140,18 +141,38 @@ static inline char *ipw2100_translate_scan(struct ieee80211_device *ieee,
                start = iwe_stream_add_point(start, stop, &iwe, custom);
 
        /* Add quality statistics */
-       /* TODO: Fix these values... */
        iwe.cmd = IWEVQUAL;
-       iwe.u.qual.qual = network->stats.signal;
-       iwe.u.qual.level = network->stats.rssi;
-       iwe.u.qual.noise = network->stats.noise;
-       iwe.u.qual.updated = network->stats.mask & IEEE80211_STATMASK_WEMASK;
-       if (!(network->stats.mask & IEEE80211_STATMASK_RSSI))
-               iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID;
-       if (!(network->stats.mask & IEEE80211_STATMASK_NOISE))
+       iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED |
+           IW_QUAL_NOISE_UPDATED;
+
+       if (!(network->stats.mask & IEEE80211_STATMASK_RSSI)) {
+               iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID |
+                   IW_QUAL_LEVEL_INVALID;
+               iwe.u.qual.qual = 0;
+               iwe.u.qual.level = 0;
+       } else {
+               iwe.u.qual.level = network->stats.rssi;
+               iwe.u.qual.qual =
+                   (100 *
+                    (ieee->perfect_rssi - ieee->worst_rssi) *
+                    (ieee->perfect_rssi - ieee->worst_rssi) -
+                    (ieee->perfect_rssi - network->stats.rssi) *
+                    (15 * (ieee->perfect_rssi - ieee->worst_rssi) +
+                     62 * (ieee->perfect_rssi - network->stats.rssi))) /
+                   ((ieee->perfect_rssi - ieee->worst_rssi) *
+                    (ieee->perfect_rssi - ieee->worst_rssi));
+               if (iwe.u.qual.qual > 100)
+                       iwe.u.qual.qual = 100;
+               else if (iwe.u.qual.qual < 1)
+                       iwe.u.qual.qual = 0;
+       }
+
+       if (!(network->stats.mask & IEEE80211_STATMASK_NOISE)) {
                iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID;
-       if (!(network->stats.mask & IEEE80211_STATMASK_SIGNAL))
-               iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID;
+               iwe.u.qual.noise = 0;
+       } else {
+               iwe.u.qual.noise = network->stats.noise;
+       }
 
        start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN);
 
@@ -162,7 +183,7 @@ static inline char *ipw2100_translate_scan(struct ieee80211_device *ieee,
        if (iwe.u.data.length)
                start = iwe_stream_add_point(start, stop, &iwe, custom);
 
-       if (ieee->wpa_enabled && network->wpa_ie_len) {
+       if (network->wpa_ie_len) {
                char buf[MAX_WPA_IE_LEN * 2 + 30];
 
                u8 *p = buf;
@@ -177,7 +198,7 @@ static inline char *ipw2100_translate_scan(struct ieee80211_device *ieee,
                start = iwe_stream_add_point(start, stop, &iwe, buf);
        }
 
-       if (ieee->wpa_enabled && network->rsn_ie_len) {
+       if (network->rsn_ie_len) {
                char buf[MAX_WPA_IE_LEN * 2 + 30];
 
                u8 *p = buf;
@@ -197,8 +218,8 @@ static inline char *ipw2100_translate_scan(struct ieee80211_device *ieee,
        iwe.cmd = IWEVCUSTOM;
        p = custom;
        p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
-                     " Last beacon: %lums ago",
-                     (jiffies - network->last_scanned) / (HZ / 100));
+                     " Last beacon: %dms ago",
+                     jiffies_to_msecs(jiffies - network->last_scanned));
        iwe.u.data.length = p - custom;
        if (iwe.u.data.length)
                start = iwe_stream_add_point(start, stop, &iwe, custom);
@@ -228,13 +249,13 @@ int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
                        ev = ipw2100_translate_scan(ieee, ev, stop, network);
                else
                        IEEE80211_DEBUG_SCAN("Not showing network '%s ("
-                                            MAC_FMT ")' due to age (%lums).\n",
+                                            MAC_FMT ")' due to age (%dms).\n",
                                             escape_essid(network->ssid,
                                                          network->ssid_len),
                                             MAC_ARG(network->bssid),
-                                            (jiffies -
-                                             network->last_scanned) / (HZ /
-                                                                       100));
+                                            jiffies_to_msecs(jiffies -
+                                                             network->
+                                                             last_scanned));
        }
 
        spin_unlock_irqrestore(&ieee->lock, flags);
@@ -258,6 +279,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
        };
        int i, key, key_provided, len;
        struct ieee80211_crypt_data **crypt;
+       int host_crypto = ieee->host_encrypt || ieee->host_decrypt;
 
        IEEE80211_DEBUG_WX("SET_ENCODE\n");
 
@@ -298,15 +320,17 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
 
                if (i == WEP_KEYS) {
                        sec.enabled = 0;
+                       sec.encrypt = 0;
                        sec.level = SEC_LEVEL_0;
-                       sec.flags |= SEC_ENABLED | SEC_LEVEL;
+                       sec.flags |= SEC_ENABLED | SEC_LEVEL | SEC_ENCRYPT;
                }
 
                goto done;
        }
 
        sec.enabled = 1;
-       sec.flags |= SEC_ENABLED;
+       sec.encrypt = 1;
+       sec.flags |= SEC_ENABLED | SEC_ENCRYPT;
 
        if (*crypt != NULL && (*crypt)->ops != NULL &&
            strcmp((*crypt)->ops->name, "WEP") != 0) {
@@ -315,7 +339,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
                ieee80211_crypt_delayed_deinit(ieee, crypt);
        }
 
-       if (*crypt == NULL) {
+       if (*crypt == NULL && host_crypto) {
                struct ieee80211_crypt_data *new_crypt;
 
                /* take WEP into use */
@@ -355,49 +379,56 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
                                   key, escape_essid(sec.keys[key], len),
                                   erq->length, len);
                sec.key_sizes[key] = len;
-               (*crypt)->ops->set_key(sec.keys[key], len, NULL,
-                                      (*crypt)->priv);
+               if (*crypt)
+                       (*crypt)->ops->set_key(sec.keys[key], len, NULL,
+                                              (*crypt)->priv);
                sec.flags |= (1 << key);
                /* This ensures a key will be activated if no key is
                 * explicitely set */
                if (key == sec.active_key)
                        sec.flags |= SEC_ACTIVE_KEY;
+
        } else {
-               len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
-                                            NULL, (*crypt)->priv);
-               if (len == 0) {
-                       /* Set a default key of all 0 */
-                       IEEE80211_DEBUG_WX("Setting key %d to all zero.\n",
-                                          key);
-                       memset(sec.keys[key], 0, 13);
-                       (*crypt)->ops->set_key(sec.keys[key], 13, NULL,
-                                              (*crypt)->priv);
-                       sec.key_sizes[key] = 13;
-                       sec.flags |= (1 << key);
+               if (host_crypto) {
+                       len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
+                                                    NULL, (*crypt)->priv);
+                       if (len == 0) {
+                               /* Set a default key of all 0 */
+                               IEEE80211_DEBUG_WX("Setting key %d to all "
+                                                  "zero.\n", key);
+                               memset(sec.keys[key], 0, 13);
+                               (*crypt)->ops->set_key(sec.keys[key], 13, NULL,
+                                                      (*crypt)->priv);
+                               sec.key_sizes[key] = 13;
+                               sec.flags |= (1 << key);
+                       }
                }
-
                /* No key data - just set the default TX key index */
                if (key_provided) {
-                       IEEE80211_DEBUG_WX
-                           ("Setting key %d to default Tx key.\n", key);
+                       IEEE80211_DEBUG_WX("Setting key %d to default Tx "
+                                          "key.\n", key);
                        ieee->tx_keyidx = key;
                        sec.active_key = key;
                        sec.flags |= SEC_ACTIVE_KEY;
                }
        }
-
-      done:
-       ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
-       sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
-       sec.flags |= SEC_AUTH_MODE;
-       IEEE80211_DEBUG_WX("Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ?
-                          "OPEN" : "SHARED KEY");
+       if (erq->flags & (IW_ENCODE_OPEN | IW_ENCODE_RESTRICTED)) {
+               ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
+               sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN :
+                   WLAN_AUTH_SHARED_KEY;
+               sec.flags |= SEC_AUTH_MODE;
+               IEEE80211_DEBUG_WX("Auth: %s\n",
+                                  sec.auth_mode == WLAN_AUTH_OPEN ?
+                                  "OPEN" : "SHARED KEY");
+       }
 
        /* For now we just support WEP, so only set that security level...
         * TODO: When WPA is added this is one place that needs to change */
        sec.flags |= SEC_LEVEL;
        sec.level = SEC_LEVEL_1;        /* 40 and 104 bit WEP */
+       sec.encode_alg[key] = SEC_ALG_WEP;
 
+      done:
        if (ieee->set_security)
                ieee->set_security(dev, &sec);
 
@@ -422,6 +453,7 @@ int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
        struct iw_point *erq = &(wrqu->encoding);
        int len, key;
        struct ieee80211_crypt_data *crypt;
+       struct ieee80211_security *sec = &ieee->sec;
 
        IEEE80211_DEBUG_WX("GET_ENCODE\n");
 
@@ -436,23 +468,16 @@ int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
        crypt = ieee->crypt[key];
        erq->flags = key + 1;
 
-       if (crypt == NULL || crypt->ops == NULL) {
+       if (!sec->enabled) {
                erq->length = 0;
                erq->flags |= IW_ENCODE_DISABLED;
                return 0;
        }
 
-       if (strcmp(crypt->ops->name, "WEP") != 0) {
-               /* only WEP is supported with wireless extensions, so just
-                * report that encryption is used */
-               erq->length = 0;
-               erq->flags |= IW_ENCODE_ENABLED;
-               return 0;
-       }
+       len = sec->key_sizes[key];
+       memcpy(keybuf, sec->keys[key], len);
 
-       len = crypt->ops->get_key(keybuf, WEP_KEY_LEN, NULL, crypt->priv);
        erq->length = (len >= 0 ? len : 0);
-
        erq->flags |= IW_ENCODE_ENABLED;
 
        if (ieee->open_wep)
@@ -463,6 +488,240 @@ int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
        return 0;
 }
 
+int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
+                              struct iw_request_info *info,
+                              union iwreq_data *wrqu, char *extra)
+{
+       struct net_device *dev = ieee->dev;
+       struct iw_point *encoding = &wrqu->encoding;
+       struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+       int i, idx, ret = 0;
+       int group_key = 0;
+       const char *alg, *module;
+       struct ieee80211_crypto_ops *ops;
+       struct ieee80211_crypt_data **crypt;
+
+       struct ieee80211_security sec = {
+               .flags = 0,
+       };
+
+       idx = encoding->flags & IW_ENCODE_INDEX;
+       if (idx) {
+               if (idx < 1 || idx > WEP_KEYS)
+                       return -EINVAL;
+               idx--;
+       } else
+               idx = ieee->tx_keyidx;
+
+       if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
+               crypt = &ieee->crypt[idx];
+               group_key = 1;
+       } else {
+               if (idx != 0)
+                       return -EINVAL;
+               if (ieee->iw_mode == IW_MODE_INFRA)
+                       crypt = &ieee->crypt[idx];
+               else
+                       return -EINVAL;
+       }
+
+       sec.flags |= SEC_ENABLED | SEC_ENCRYPT;
+       if ((encoding->flags & IW_ENCODE_DISABLED) ||
+           ext->alg == IW_ENCODE_ALG_NONE) {
+               if (*crypt)
+                       ieee80211_crypt_delayed_deinit(ieee, crypt);
+
+               for (i = 0; i < WEP_KEYS; i++)
+                       if (ieee->crypt[i] != NULL)
+                               break;
+
+               if (i == WEP_KEYS) {
+                       sec.enabled = 0;
+                       sec.encrypt = 0;
+                       sec.level = SEC_LEVEL_0;
+                       sec.flags |= SEC_LEVEL;
+               }
+               goto done;
+       }
+
+       sec.enabled = 1;
+       sec.encrypt = 1;
+
+       if (group_key ? !ieee->host_mc_decrypt :
+           !(ieee->host_encrypt || ieee->host_decrypt ||
+             ieee->host_encrypt_msdu))
+               goto skip_host_crypt;
+
+       switch (ext->alg) {
+       case IW_ENCODE_ALG_WEP:
+               alg = "WEP";
+               module = "ieee80211_crypt_wep";
+               break;
+       case IW_ENCODE_ALG_TKIP:
+               alg = "TKIP";
+               module = "ieee80211_crypt_tkip";
+               break;
+       case IW_ENCODE_ALG_CCMP:
+               alg = "CCMP";
+               module = "ieee80211_crypt_ccmp";
+               break;
+       default:
+               IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
+                                  dev->name, ext->alg);
+               ret = -EINVAL;
+               goto done;
+       }
+
+       ops = ieee80211_get_crypto_ops(alg);
+       if (ops == NULL) {
+               request_module(module);
+               ops = ieee80211_get_crypto_ops(alg);
+       }
+       if (ops == NULL) {
+               IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
+                                  dev->name, ext->alg);
+               ret = -EINVAL;
+               goto done;
+       }
+
+       if (*crypt == NULL || (*crypt)->ops != ops) {
+               struct ieee80211_crypt_data *new_crypt;
+
+               ieee80211_crypt_delayed_deinit(ieee, crypt);
+
+               new_crypt = (struct ieee80211_crypt_data *)
+                   kmalloc(sizeof(*new_crypt), GFP_KERNEL);
+               if (new_crypt == NULL) {
+                       ret = -ENOMEM;
+                       goto done;
+               }
+               memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
+               new_crypt->ops = ops;
+               if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
+                       new_crypt->priv = new_crypt->ops->init(idx);
+               if (new_crypt->priv == NULL) {
+                       kfree(new_crypt);
+                       ret = -EINVAL;
+                       goto done;
+               }
+               *crypt = new_crypt;
+       }
+
+       if (ext->key_len > 0 && (*crypt)->ops->set_key &&
+           (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
+                                  (*crypt)->priv) < 0) {
+               IEEE80211_DEBUG_WX("%s: key setting failed\n", dev->name);
+               ret = -EINVAL;
+               goto done;
+       }
+
+      skip_host_crypt:
+       if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
+               ieee->tx_keyidx = idx;
+               sec.active_key = idx;
+               sec.flags |= SEC_ACTIVE_KEY;
+       }
+
+       if (ext->alg != IW_ENCODE_ALG_NONE) {
+               memcpy(sec.keys[idx], ext->key, ext->key_len);
+               sec.key_sizes[idx] = ext->key_len;
+               sec.flags |= (1 << idx);
+               if (ext->alg == IW_ENCODE_ALG_WEP) {
+                       sec.encode_alg[idx] = SEC_ALG_WEP;
+                       sec.flags |= SEC_LEVEL;
+                       sec.level = SEC_LEVEL_1;
+               } else if (ext->alg == IW_ENCODE_ALG_TKIP) {
+                       sec.encode_alg[idx] = SEC_ALG_TKIP;
+                       sec.flags |= SEC_LEVEL;
+                       sec.level = SEC_LEVEL_2;
+               } else if (ext->alg == IW_ENCODE_ALG_CCMP) {
+                       sec.encode_alg[idx] = SEC_ALG_CCMP;
+                       sec.flags |= SEC_LEVEL;
+                       sec.level = SEC_LEVEL_3;
+               }
+               /* Don't set sec level for group keys. */
+               if (group_key)
+                       sec.flags &= ~SEC_LEVEL;
+       }
+      done:
+       if (ieee->set_security)
+               ieee->set_security(ieee->dev, &sec);
+
+       /*
+        * Do not reset port if card is in Managed mode since resetting will
+        * generate new IEEE 802.11 authentication which may end up in looping
+        * with IEEE 802.1X. If your hardware requires a reset after WEP
+        * configuration (for example... Prism2), implement the reset_port in
+        * the callbacks structures used to initialize the 802.11 stack.
+        */
+       if (ieee->reset_on_keychange &&
+           ieee->iw_mode != IW_MODE_INFRA &&
+           ieee->reset_port && ieee->reset_port(dev)) {
+               IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name);
+               return -EINVAL;
+       }
+
+       return ret;
+}
+
+int ieee80211_wx_get_encodeext(struct ieee80211_device *ieee,
+                              struct iw_request_info *info,
+                              union iwreq_data *wrqu, char *extra)
+{
+       struct iw_point *encoding = &wrqu->encoding;
+       struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+       struct ieee80211_security *sec = &ieee->sec;
+       int idx, max_key_len;
+
+       max_key_len = encoding->length - sizeof(*ext);
+       if (max_key_len < 0)
+               return -EINVAL;
+
+       idx = encoding->flags & IW_ENCODE_INDEX;
+       if (idx) {
+               if (idx < 1 || idx > WEP_KEYS)
+                       return -EINVAL;
+               idx--;
+       } else
+               idx = ieee->tx_keyidx;
+
+       if (!ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
+               if (idx != 0 || ieee->iw_mode != IW_MODE_INFRA)
+                       return -EINVAL;
+
+       encoding->flags = idx + 1;
+       memset(ext, 0, sizeof(*ext));
+
+       if (!sec->enabled) {
+               ext->alg = IW_ENCODE_ALG_NONE;
+               ext->key_len = 0;
+               encoding->flags |= IW_ENCODE_DISABLED;
+       } else {
+               if (sec->encode_alg[idx] == SEC_ALG_WEP)
+                       ext->alg = IW_ENCODE_ALG_WEP;
+               else if (sec->encode_alg[idx] == SEC_ALG_TKIP)
+                       ext->alg = IW_ENCODE_ALG_TKIP;
+               else if (sec->encode_alg[idx] == SEC_ALG_CCMP)
+                       ext->alg = IW_ENCODE_ALG_CCMP;
+               else
+                       return -EINVAL;
+
+               ext->key_len = sec->key_sizes[idx];
+               memcpy(ext->key, sec->keys[idx], ext->key_len);
+               encoding->flags |= IW_ENCODE_ENABLED;
+               if (ext->key_len &&
+                   (ext->alg == IW_ENCODE_ALG_TKIP ||
+                    ext->alg == IW_ENCODE_ALG_CCMP))
+                       ext->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID;
+
+       }
+
+       return 0;
+}
+
+EXPORT_SYMBOL(ieee80211_wx_set_encodeext);
+EXPORT_SYMBOL(ieee80211_wx_get_encodeext);
+
 EXPORT_SYMBOL(ieee80211_wx_get_scan);
 EXPORT_SYMBOL(ieee80211_wx_set_encode);
 EXPORT_SYMBOL(ieee80211_wx_get_encode);