]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/wireless/hostap/hostap_hw.c
Merge git://git.skbuff.net/gitroot/yoshfuji/linux-2.6.14+advapi-fix/
[linux-2.6-omap-h63xx.git] / drivers / net / wireless / hostap / hostap_hw.c
index 80d0cd30c9d3b293f0ee8cb130b0c10e4407e68e..abfae7fedebcfcc31a75b9631b8e6bcd993bd287 100644 (file)
@@ -4,7 +4,7 @@
  *
  * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
  * <jkmaline@cc.hut.fi>
- * Copyright (c) 2002-2004, Jouni Malinen <jkmaline@cc.hut.fi>
+ * Copyright (c) 2002-2005, Jouni Malinen <jkmaline@cc.hut.fi>
  *
  * 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
@@ -31,7 +31,6 @@
 
 
 #include <linux/config.h>
-#include <linux/version.h>
 
 #include <asm/delay.h>
 #include <asm/uaccess.h>
 #include <linux/rtnetlink.h>
 #include <linux/wireless.h>
 #include <net/iw_handler.h>
+#include <net/ieee80211.h>
+#include <net/ieee80211_crypt.h>
 #include <asm/irq.h>
 
-
 #include "hostap_80211.h"
 #include "hostap.h"
 #include "hostap_ap.h"
@@ -82,18 +82,6 @@ static int dtim_period[MAX_PARM_DEVICES] = { 1, DEF_INTS };
 module_param_array(dtim_period, int, NULL, 0444);
 MODULE_PARM_DESC(dtim_period, "DTIM period");
 
-#if defined(PRISM2_PCI) && defined(PRISM2_BUS_MASTER)
-static int bus_master_threshold_rx[MAX_PARM_DEVICES] = { 100, DEF_INTS };
-module_param_array(bus_master_threshold_rx, int, NULL, 0444);
-MODULE_PARM_DESC(bus_master_threshold_rx, "Packet length threshold for using "
-                "PCI bus master on RX");
-
-static int bus_master_threshold_tx[MAX_PARM_DEVICES] = { 100, DEF_INTS };
-module_param_array(bus_master_threshold_tx, int, NULL, 0444);
-MODULE_PARM_DESC(bus_master_threshold_tx, "Packet length threshold for using "
-                "PCI bus master on TX");
-#endif /* PRISM2_PCI and PRISM2_BUS_MASTER */
-
 static char dev_template[16] = "wlan%d";
 module_param_string(dev_template, dev_template, sizeof(dev_template), 0444);
 MODULE_PARM_DESC(dev_template, "Prefix for network device name (default: "
@@ -106,12 +94,6 @@ MODULE_PARM_DESC(dev_template, "Prefix for network device name (default: "
 #define EXTRA_EVENTS_WTERR HFA384X_EV_WTERR
 #endif
 
-#if defined(PRISM2_PCI) && defined(PRISM2_BUS_MASTER)
-#define EXTRA_EVENTS_BUS_MASTER (HFA384X_EV_PCI_M0 | HFA384X_EV_PCI_M1)
-#else
-#define EXTRA_EVENTS_BUS_MASTER 0
-#endif
-
 /* Events that will be using BAP0 */
 #define HFA384X_BAP0_EVENTS \
        (HFA384X_EV_TXEXC | HFA384X_EV_RX | HFA384X_EV_INFO | HFA384X_EV_TX)
@@ -120,7 +102,7 @@ MODULE_PARM_DESC(dev_template, "Prefix for network device name (default: "
 #define HFA384X_EVENT_MASK \
        (HFA384X_BAP0_EVENTS | HFA384X_EV_ALLOC | HFA384X_EV_INFDROP | \
        HFA384X_EV_CMD | HFA384X_EV_TICK | \
-       EXTRA_EVENTS_WTERR | EXTRA_EVENTS_BUS_MASTER)
+       EXTRA_EVENTS_WTERR)
 
 /* Default TX control flags: use 802.11 headers and request interrupt for
  * failed transmits. Frames that request ACK callback, will add
@@ -1826,34 +1808,6 @@ static int prism2_transmit(struct net_device *dev, int idx)
 }
 
 
-#if defined(PRISM2_PCI) && defined(PRISM2_BUS_MASTER)
-/* Called only from hardware IRQ */
-static void prism2_tx_cb(struct net_device *dev, void *context,
-                        u16 resp0, u16 res)
-{
-       struct hostap_interface *iface;
-       local_info_t *local;
-       unsigned long addr;
-       int buf_len = (int) context;
-
-       iface = netdev_priv(dev);
-       local = iface->local;
-
-       if (res) {
-               printk(KERN_DEBUG "%s: prism2_tx_cb - res=0x%02x\n",
-                      dev->name, res);
-               return;
-       }
-
-       addr = virt_to_phys(local->bus_m0_buf);
-       HFA384X_OUTW((addr & 0xffff0000) >> 16, HFA384X_PCI_M0_ADDRH_OFF);
-       HFA384X_OUTW(addr & 0x0000ffff, HFA384X_PCI_M0_ADDRL_OFF);
-       HFA384X_OUTW(buf_len / 2, HFA384X_PCI_M0_LEN_OFF);
-       HFA384X_OUTW(HFA384X_PCI_CTL_TO_BAP, HFA384X_PCI_M0_CTL_OFF);
-}
-#endif /* PRISM2_PCI and PRISM2_BUS_MASTER */
-
-
 /* Send IEEE 802.11 frame (convert the header into Prism2 TX descriptor and
  * send the payload with this descriptor) */
 /* Called only from software IRQ */
@@ -1862,7 +1816,6 @@ static int prism2_tx_80211(struct sk_buff *skb, struct net_device *dev)
        struct hostap_interface *iface;
        local_info_t *local;
        struct hfa384x_tx_frame txdesc;
-       struct hostap_ieee80211_hdr *hdr;
        struct hostap_skb_tx_data *meta;
        int hdr_len, data_len, idx, res, ret = -1;
        u16 tx_control, fc;
@@ -1871,7 +1824,6 @@ static int prism2_tx_80211(struct sk_buff *skb, struct net_device *dev)
        local = iface->local;
 
        meta = (struct hostap_skb_tx_data *) skb->cb;
-       hdr = (struct hostap_ieee80211_hdr *) skb->data;
 
        prism2_callback(local, PRISM2_CALLBACK_TX_START);
 
@@ -1890,8 +1842,9 @@ static int prism2_tx_80211(struct sk_buff *skb, struct net_device *dev)
        hdr_len = 24;
        memcpy(&txdesc.frame_control, skb->data, hdr_len);
        fc = le16_to_cpu(txdesc.frame_control);
-       if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA &&
-           (fc & WLAN_FC_FROMDS) && (fc & WLAN_FC_TODS) && skb->len >= 30) {
+       if (WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA &&
+           (fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS) &&
+           skb->len >= 30) {
                /* Addr4 */
                memcpy(txdesc.addr4, skb->data + hdr_len, ETH_ALEN);
                hdr_len += ETH_ALEN;
@@ -1919,53 +1872,6 @@ static int prism2_tx_80211(struct sk_buff *skb, struct net_device *dev)
        spin_lock(&local->baplock);
        res = hfa384x_setup_bap(dev, BAP0, local->txfid[idx], 0);
 
-#if defined(PRISM2_PCI) && defined(PRISM2_BUS_MASTER)
-       if (!res && skb->len >= local->bus_master_threshold_tx) {
-               u8 *pos;
-               int buf_len;
-
-               local->bus_m0_tx_idx = idx;
-
-               /* FIX: BAP0 should be locked during bus master transfer, but
-                * baplock with BH's disabled is not OK for this; netif queue
-                * stopping is not enough since BAP0 is used also for RID
-                * read/write */
-
-               /* stop the queue for the time that bus mastering on BAP0 is
-                * in use */
-               netif_stop_queue(dev);
-
-               spin_unlock(&local->baplock);
-
-               /* Copy frame data to bus_m0_buf */
-               pos = local->bus_m0_buf;
-               memcpy(pos, &txdesc, sizeof(txdesc));
-               pos += sizeof(txdesc);
-               memcpy(pos, skb->data + hdr_len, skb->len - hdr_len);
-               pos += skb->len - hdr_len;
-               buf_len = pos - local->bus_m0_buf;
-               if (buf_len & 1)
-                       buf_len++;
-
-#ifdef PRISM2_ENABLE_BEFORE_TX_BUS_MASTER
-               /* Any RX packet seems to break something with TX bus
-                * mastering; enable command is enough to fix this.. */
-               if (hfa384x_cmd_callback(dev, HFA384X_CMDCODE_ENABLE, 0,
-                                        prism2_tx_cb, (long) buf_len)) {
-                       printk(KERN_DEBUG "%s: TX: enable port0 failed\n",
-                              dev->name);
-               }
-#else /* PRISM2_ENABLE_BEFORE_TX_BUS_MASTER */
-               prism2_tx_cb(dev, (void *) buf_len, 0, 0);
-#endif /* PRISM2_ENABLE_BEFORE_TX_BUS_MASTER */
-
-               /* Bus master transfer will be started from command completion
-                * event handler and TX handling will be finished by calling
-                * prism2_transmit() from bus master event handler */
-               goto tx_stats;
-       }
-#endif /* PRISM2_PCI and PRISM2_BUS_MASTER */
-
        if (!res)
                res = hfa384x_to_bap(dev, BAP0, &txdesc, sizeof(txdesc));
        if (!res)
@@ -2106,50 +2012,18 @@ static void prism2_rx(local_info_t *local)
        skb->dev = dev;
        memcpy(skb_put(skb, hdr_len), &rxdesc, hdr_len);
 
-#if defined(PRISM2_PCI) && defined(PRISM2_BUS_MASTER)
-       if (len >= local->bus_master_threshold_rx) {
-               unsigned long addr;
-
-               hfa384x_events_no_bap1(dev);
-
-               local->rx_skb = skb;
-               /* Internal BAP0 offset points to the byte following rxdesc;
-                * copy rest of the data using bus master */
-               addr = virt_to_phys(skb_put(skb, len));
-               HFA384X_OUTW((addr & 0xffff0000) >> 16,
-                            HFA384X_PCI_M0_ADDRH_OFF);
-               HFA384X_OUTW(addr & 0x0000ffff, HFA384X_PCI_M0_ADDRL_OFF);
-               if (len & 1)
-                       len++;
-               HFA384X_OUTW(len / 2, HFA384X_PCI_M0_LEN_OFF);
-               HFA384X_OUTW(HFA384X_PCI_CTL_FROM_BAP, HFA384X_PCI_M0_CTL_OFF);
-
-               /* pci_bus_m1 event will be generated when data transfer is
-                * complete and the frame will then be added to rx_list and
-                * rx_tasklet is scheduled */
-               rx_pending = 1;
-
-               /* Have to release baplock before returning, although BAP0
-                * should really not be used before DMA transfer has been
-                * completed. */
-               spin_unlock(&local->baplock);
-       } else
-#endif /* PRISM2_PCI and PRISM2_BUS_MASTER */
-       {
-               if (len > 0)
-                       res = hfa384x_from_bap(dev, BAP0, skb_put(skb, len),
-                                              len);
-               spin_unlock(&local->baplock);
-               if (res) {
-                       printk(KERN_DEBUG "%s: RX failed to read "
-                              "frame data\n", dev->name);
-                       goto rx_dropped;
-               }
-
-               skb_queue_tail(&local->rx_list, skb);
-               tasklet_schedule(&local->rx_tasklet);
+       if (len > 0)
+               res = hfa384x_from_bap(dev, BAP0, skb_put(skb, len), len);
+       spin_unlock(&local->baplock);
+       if (res) {
+               printk(KERN_DEBUG "%s: RX failed to read "
+                      "frame data\n", dev->name);
+               goto rx_dropped;
        }
 
+       skb_queue_tail(&local->rx_list, skb);
+       tasklet_schedule(&local->rx_tasklet);
+
  rx_exit:
        prism2_callback(local, PRISM2_CALLBACK_RX_END);
        if (!rx_pending) {
@@ -2521,12 +2395,12 @@ static void prism2_txexc(local_info_t *local)
        PDEBUG(DEBUG_EXTRA, "   retry_count=%d tx_rate=%d fc=0x%04x "
               "(%s%s%s::%d%s%s)\n",
               txdesc.retry_count, txdesc.tx_rate, fc,
-              WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT ? "Mgmt" : "",
-              WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_CTRL ? "Ctrl" : "",
-              WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA ? "Data" : "",
-              WLAN_FC_GET_STYPE(fc),
-              fc & WLAN_FC_TODS ? " ToDS" : "",
-              fc & WLAN_FC_FROMDS ? " FromDS" : "");
+              WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_MGMT ? "Mgmt" : "",
+              WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_CTL ? "Ctrl" : "",
+              WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA ? "Data" : "",
+              WLAN_FC_GET_STYPE(fc) >> 4,
+              fc & IEEE80211_FCTL_TODS ? " ToDS" : "",
+              fc & IEEE80211_FCTL_FROMDS ? " FromDS" : "");
        PDEBUG(DEBUG_EXTRA, "   A1=" MACSTR " A2=" MACSTR " A3="
               MACSTR " A4=" MACSTR "\n",
               MAC2STR(txdesc.addr1), MAC2STR(txdesc.addr2),
@@ -2653,36 +2527,6 @@ static void hostap_bap_tasklet(unsigned long data)
 }
 
 
-#if defined(PRISM2_PCI) && defined(PRISM2_BUS_MASTER)
-/* Called only from hardware IRQ */
-static void prism2_bus_master_ev(struct net_device *dev, int bap)
-{
-       struct hostap_interface *iface;
-       local_info_t *local;
-
-       iface = netdev_priv(dev);
-       local = iface->local;
-
-       if (bap == BAP1) {
-               /* FIX: frame payload was DMA'd to skb->data; might need to
-                * invalidate data cache for that memory area */
-               skb_queue_tail(&local->rx_list, local->rx_skb);
-               tasklet_schedule(&local->rx_tasklet);
-               HFA384X_OUTW(HFA384X_EV_RX, HFA384X_EVACK_OFF);
-       } else {
-               if (prism2_transmit(dev, local->bus_m0_tx_idx)) {
-                       printk(KERN_DEBUG "%s: prism2_transmit() failed "
-                              "when called from bus master event\n",
-                              dev->name);
-                       local->intransmitfid[local->bus_m0_tx_idx] =
-                               PRISM2_TXFID_EMPTY;
-                       schedule_work(&local->reset_queue);
-               }
-       }
-}
-#endif /* PRISM2_PCI and PRISM2_BUS_MASTER */
-
-
 /* Called only from hardware IRQ */
 static void prism2_infdrop(struct net_device *dev)
 {
@@ -2851,21 +2695,6 @@ static irqreturn_t prism2_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                        HFA384X_OUTW(HFA384X_EV_TICK, HFA384X_EVACK_OFF);
                }
 
-#if defined(PRISM2_PCI) && defined(PRISM2_BUS_MASTER)
-               if (ev & HFA384X_EV_PCI_M0) {
-                       prism2_bus_master_ev(dev, BAP0);
-                       HFA384X_OUTW(HFA384X_EV_PCI_M0, HFA384X_EVACK_OFF);
-               }
-
-               if (ev & HFA384X_EV_PCI_M1) {
-                       /* previous RX has been copied can be ACKed now */
-                       HFA384X_OUTW(HFA384X_EV_RX, HFA384X_EVACK_OFF);
-
-                       prism2_bus_master_ev(dev, BAP1);
-                       HFA384X_OUTW(HFA384X_EV_PCI_M1, HFA384X_EVACK_OFF);
-               }
-#endif /* PRISM2_PCI and PRISM2_BUS_MASTER */
-
                if (ev & HFA384X_EV_ALLOC) {
                        prism2_alloc_ev(dev);
                        HFA384X_OUTW(HFA384X_EV_ALLOC, HFA384X_EVACK_OFF);
@@ -2966,11 +2795,11 @@ static void prism2_check_sta_fw_version(local_info_t *local)
 static void prism2_crypt_deinit_entries(local_info_t *local, int force)
 {
        struct list_head *ptr, *n;
-       struct prism2_crypt_data *entry;
+       struct ieee80211_crypt_data *entry;
 
        for (ptr = local->crypt_deinit_list.next, n = ptr->next;
             ptr != &local->crypt_deinit_list; ptr = n, n = ptr->next) {
-               entry = list_entry(ptr, struct prism2_crypt_data, list);
+               entry = list_entry(ptr, struct ieee80211_crypt_data, list);
 
                if (atomic_read(&entry->refcnt) != 0 && !force)
                        continue;
@@ -3308,13 +3137,6 @@ prism2_init_local_data(struct prism2_helper_functions *funcs, int card_idx,
        local->io_debug_enabled = 1;
 #endif /* PRISM2_IO_DEBUG */
 
-#if defined(PRISM2_PCI) && defined(PRISM2_BUS_MASTER)
-       local->bus_m0_buf = (u8 *) kmalloc(sizeof(struct hfa384x_tx_frame) +
-                                          PRISM2_DATA_MAXLEN, GFP_DMA);
-       if (local->bus_m0_buf == NULL)
-               goto fail;
-#endif /* PRISM2_PCI and PRISM2_BUS_MASTER */
-
        local->func = funcs;
        local->func->cmd = hfa384x_cmd;
        local->func->read_regs = hfa384x_read_regs;
@@ -3375,12 +3197,6 @@ prism2_init_local_data(struct prism2_helper_functions *funcs, int card_idx,
        local->auth_algs = PRISM2_AUTH_OPEN | PRISM2_AUTH_SHARED_KEY;
        local->sram_type = -1;
        local->scan_channel_mask = 0xffff;
-#if defined(PRISM2_PCI) && defined(PRISM2_BUS_MASTER)
-       local->bus_master_threshold_rx = GET_INT_PARM(bus_master_threshold_rx,
-                                                     card_idx);
-       local->bus_master_threshold_tx = GET_INT_PARM(bus_master_threshold_tx,
-                                                     card_idx);
-#endif /* PRISM2_PCI and PRISM2_BUS_MASTER */
 
        /* Initialize task queue structures */
        INIT_WORK(&local->reset_queue, handle_reset_queue, local);
@@ -3461,9 +3277,6 @@ while (0)
        return dev;
 
  fail:
-#if defined(PRISM2_PCI) && defined(PRISM2_BUS_MASTER)
-       kfree(local->bus_m0_buf);
-#endif /* PRISM2_PCI and PRISM2_BUS_MASTER */
        free_netdev(dev);
        return NULL;
 }
@@ -3508,6 +3321,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))
@@ -3530,7 +3355,7 @@ static void prism2_free_local_data(struct net_device *dev)
                prism2_callback(local, PRISM2_CALLBACK_DISABLE);
 
        for (i = 0; i < WEP_KEYS; i++) {
-               struct prism2_crypt_data *crypt = local->crypt[i];
+               struct ieee80211_crypt_data *crypt = local->crypt[i];
                if (crypt) {
                        if (crypt->ops)
                                crypt->ops->deinit(crypt->priv);
@@ -3568,15 +3393,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) {
@@ -3585,14 +3401,10 @@ static void prism2_free_local_data(struct net_device *dev)
                kfree(bss);
        }
 
-#if defined(PRISM2_PCI) && defined(PRISM2_BUS_MASTER)
-       kfree(local->bus_m0_buf);
-#endif /* PRISM2_PCI and PRISM2_BUS_MASTER */
        kfree(local->pda);
        kfree(local->last_scan_results);
        kfree(local->generic_elem);
 
-       unregister_netdev(local->dev);
        free_netdev(local->dev);
 }