net: convert print_mac to %pM
[safe/jmp/linux-2.6] / drivers / net / wireless / hostap / hostap_hw.c
index b1f142d..fd7f7ce 100644 (file)
@@ -3,8 +3,8 @@
  * Intersil Prism2/2.5/3.
  *
  * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- * <jkmaline@cc.hut.fi>
- * Copyright (c) 2002-2005, Jouni Malinen <jkmaline@cc.hut.fi>
+ * <j@w1.fi>
+ * Copyright (c) 2002-2005, Jouni Malinen <j@w1.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
@@ -30,7 +30,6 @@
  */
 
 
-#include <linux/config.h>
 
 #include <asm/delay.h>
 #include <asm/uaccess.h>
@@ -348,14 +347,12 @@ static int hfa384x_cmd(struct net_device *dev, u16 cmd, u16 param0,
        if (signal_pending(current))
                return -EINTR;
 
-       entry = (struct hostap_cmd_queue *)
-               kmalloc(sizeof(*entry), GFP_ATOMIC);
+       entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
        if (entry == NULL) {
                printk(KERN_DEBUG "%s: hfa384x_cmd - kmalloc failed\n",
                       dev->name);
                return -ENOMEM;
        }
-       memset(entry, 0, sizeof(*entry));
        atomic_set(&entry->usecnt, 1);
        entry->type = CMD_SLEEP;
        entry->cmd = cmd;
@@ -518,14 +515,12 @@ static int hfa384x_cmd_callback(struct net_device *dev, u16 cmd, u16 param0,
                return -1;
        }
 
-       entry = (struct hostap_cmd_queue *)
-               kmalloc(sizeof(*entry), GFP_ATOMIC);
+       entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
        if (entry == NULL) {
                printk(KERN_DEBUG "%s: hfa384x_cmd_callback - kmalloc "
                       "failed\n", dev->name);
                return -ENOMEM;
        }
-       memset(entry, 0, sizeof(*entry));
        atomic_set(&entry->usecnt, 1);
        entry->type = CMD_CALLBACK;
        entry->cmd = cmd;
@@ -830,7 +825,7 @@ static int hfa384x_get_rid(struct net_device *dev, u16 rid, void *buf, int len,
            local->hw_downloading)
                return -ENODEV;
 
-       res = down_interruptible(&local->rid_bap_sem);
+       res = mutex_lock_interruptible(&local->rid_bap_mtx);
        if (res)
                return res;
 
@@ -839,7 +834,7 @@ static int hfa384x_get_rid(struct net_device *dev, u16 rid, void *buf, int len,
                printk(KERN_DEBUG "%s: hfa384x_get_rid: CMDCODE_ACCESS failed "
                       "(res=%d, rid=%04x, len=%d)\n",
                       dev->name, res, rid, len);
-               up(&local->rid_bap_sem);
+               mutex_unlock(&local->rid_bap_mtx);
                return res;
        }
 
@@ -866,7 +861,7 @@ static int hfa384x_get_rid(struct net_device *dev, u16 rid, void *buf, int len,
                res = hfa384x_from_bap(dev, BAP0, buf, len);
 
        spin_unlock_bh(&local->baplock);
-       up(&local->rid_bap_sem);
+       mutex_unlock(&local->rid_bap_mtx);
 
        if (res) {
                if (res != -ENODATA)
@@ -907,7 +902,7 @@ static int hfa384x_set_rid(struct net_device *dev, u16 rid, void *buf, int len)
        /* RID len in words and +1 for rec.rid */
        rec.len = cpu_to_le16(len / 2 + len % 2 + 1);
 
-       res = down_interruptible(&local->rid_bap_sem);
+       res = mutex_lock_interruptible(&local->rid_bap_mtx);
        if (res)
                return res;
 
@@ -922,21 +917,21 @@ static int hfa384x_set_rid(struct net_device *dev, u16 rid, void *buf, int len)
        if (res) {
                printk(KERN_DEBUG "%s: hfa384x_set_rid (rid=%04x, len=%d) - "
                       "failed - res=%d\n", dev->name, rid, len, res);
-               up(&local->rid_bap_sem);
+               mutex_unlock(&local->rid_bap_mtx);
                return res;
        }
 
        res = hfa384x_cmd(dev, HFA384X_CMDCODE_ACCESS_WRITE, rid, NULL, NULL);
-       up(&local->rid_bap_sem);
+       mutex_unlock(&local->rid_bap_mtx);
+
        if (res) {
                printk(KERN_DEBUG "%s: hfa384x_set_rid: CMDCODE_ACCESS_WRITE "
                       "failed (res=%d, rid=%04x, len=%d)\n",
                       dev->name, res, rid, len);
-               return res;
-       }
 
-       if (res == -ETIMEDOUT)
-               prism2_hw_reset(dev);
+               if (res == -ETIMEDOUT)
+                       prism2_hw_reset(dev);
+       }
 
        return res;
 }
@@ -1043,6 +1038,9 @@ static int prism2_reset_port(struct net_device *dev)
                       dev->name, local->fragm_threshold);
        }
 
+       /* Some firmwares lose antenna selection settings on reset */
+       (void) hostap_set_antsel(local);
+
        return res;
 }
 
@@ -1077,7 +1075,7 @@ static int prism2_setup_rids(struct net_device *dev)
 {
        struct hostap_interface *iface;
        local_info_t *local;
-       u16 tmp;
+       __le16 tmp;
        int ret = 0;
 
        iface = netdev_priv(dev);
@@ -1086,11 +1084,11 @@ static int prism2_setup_rids(struct net_device *dev)
        hostap_set_word(dev, HFA384X_RID_TICKTIME, 2000);
 
        if (!local->fw_ap) {
-               tmp = hostap_get_porttype(local);
-               ret = hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE, tmp);
+               u16 tmp1 = hostap_get_porttype(local);
+               ret = hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE, tmp1);
                if (ret) {
                        printk("%s: Port type setting to %d failed\n",
-                              dev->name, tmp);
+                              dev->name, tmp1);
                        goto fail;
                }
        }
@@ -1119,7 +1117,7 @@ static int prism2_setup_rids(struct net_device *dev)
                ret = -EINVAL;
                goto fail;
        }
-       local->channel_mask = __le16_to_cpu(tmp);
+       local->channel_mask = le16_to_cpu(tmp);
 
        if (local->channel < 1 || local->channel > 14 ||
            !(local->channel_mask & (1 << (local->channel - 1)))) {
@@ -1643,9 +1641,9 @@ static void prism2_schedule_reset(local_info_t *local)
 
 /* Called only as scheduled task after noticing card timeout in interrupt
  * context */
-static void handle_reset_queue(void *data)
+static void handle_reset_queue(struct work_struct *work)
 {
-       local_info_t *local = (local_info_t *) data;
+       local_info_t *local = container_of(work, local_info_t, reset_queue);
 
        printk(KERN_DEBUG "%s: scheduled card reset\n", local->dev->name);
        prism2_hw_reset(local->dev);
@@ -1840,20 +1838,21 @@ static int prism2_tx_80211(struct sk_buff *skb, struct net_device *dev)
 
        /* skb->data starts with txdesc->frame_control */
        hdr_len = 24;
-       memcpy(&txdesc.frame_control, skb->data, hdr_len);
+       skb_copy_from_linear_data(skb, &txdesc.frame_control, hdr_len);
        fc = le16_to_cpu(txdesc.frame_control);
        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);
+               skb_copy_from_linear_data_offset(skb, hdr_len, txdesc.addr4,
+                                                ETH_ALEN);
                hdr_len += ETH_ALEN;
        }
 
        tx_control = local->tx_control;
        if (meta->tx_cb_idx) {
                tx_control |= HFA384X_TX_CTRL_TX_OK;
-               txdesc.sw_support = cpu_to_le16(meta->tx_cb_idx);
+               txdesc.sw_support = cpu_to_le32(meta->tx_cb_idx);
        }
        txdesc.tx_control = cpu_to_le16(tx_control);
        txdesc.tx_rate = meta->rate;
@@ -2191,7 +2190,7 @@ static void hostap_tx_callback(local_info_t *local,
                return;
        }
 
-       sw_support = le16_to_cpu(txdesc->sw_support);
+       sw_support = le32_to_cpu(txdesc->sw_support);
 
        spin_lock(&local->lock);
        cb = local->tx_callback;
@@ -2219,7 +2218,7 @@ static void hostap_tx_callback(local_info_t *local,
                memcpy(skb_put(skb, len), payload, len);
 
        skb->dev = local->dev;
-       skb->mac.raw = skb->data;
+       skb_reset_mac_header(skb);
 
        cb->func(skb, ok, cb->data);
 }
@@ -2254,7 +2253,7 @@ static int hostap_tx_compl_read(local_info_t *local, int error,
        if (txdesc->sw_support) {
                len = le16_to_cpu(txdesc->data_len);
                if (len < PRISM2_DATA_MAXLEN) {
-                       *payload = (char *) kmalloc(len, GFP_ATOMIC);
+                       *payload = kmalloc(len, GFP_ATOMIC);
                        if (*payload == NULL ||
                            hfa384x_from_bap(dev, BAP0, *payload, len)) {
                                PDEBUG(DEBUG_EXTRA, "%s: could not read TX "
@@ -2401,10 +2400,9 @@ static void prism2_txexc(local_info_t *local)
               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),
-              MAC2STR(txdesc.addr3), MAC2STR(txdesc.addr4));
+       PDEBUG(DEBUG_EXTRA, "   A1=%pM A2=%pM A3=%pM A4=%pM\n",
+              txdesc.addr1, txdesc.addr2,
+              txdesc.addr3, txdesc.addr4);
 }
 
 
@@ -2446,18 +2444,16 @@ static void prism2_info(local_info_t *local)
                goto out;
        }
 
-       le16_to_cpus(&info.len);
-       le16_to_cpus(&info.type);
-       left = (info.len - 1) * 2;
+       left = (le16_to_cpu(info.len) - 1) * 2;
 
-       if (info.len & 0x8000 || info.len == 0 || left > 2060) {
+       if (info.len & cpu_to_le16(0x8000) || info.len == 0 || left > 2060) {
                /* data register seems to give 0x8000 in some error cases even
                 * though busy bit is not set in offset register;
                 * in addition, length must be at least 1 due to type field */
                spin_unlock(&local->baplock);
                printk(KERN_DEBUG "%s: Received info frame with invalid "
-                      "length 0x%04x (type 0x%04x)\n", dev->name, info.len,
-                      info.type);
+                      "length 0x%04x (type 0x%04x)\n", dev->name,
+                      le16_to_cpu(info.len), le16_to_cpu(info.type));
                goto out;
        }
 
@@ -2474,8 +2470,8 @@ static void prism2_info(local_info_t *local)
        {
                spin_unlock(&local->baplock);
                printk(KERN_WARNING "%s: Info frame read failed (fid=0x%04x, "
-                      "len=0x%04x, type=0x%04x\n",
-                      dev->name, fid, info.len, info.type);
+                      "len=0x%04x, type=0x%04x\n", dev->name, fid,
+                      le16_to_cpu(info.len), le16_to_cpu(info.type));
                dev_kfree_skb(skb);
                goto out;
        }
@@ -2620,9 +2616,9 @@ static void prism2_check_magic(local_info_t *local)
 
 
 /* Called only from hardware IRQ */
-static irqreturn_t prism2_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t prism2_interrupt(int irq, void *dev_id)
 {
-       struct net_device *dev = (struct net_device *) dev_id;
+       struct net_device *dev = dev_id;
        struct hostap_interface *iface;
        local_info_t *local;
        int events = 0;
@@ -2835,7 +2831,7 @@ static void hostap_passive_scan(unsigned long data)
 {
        local_info_t *local = (local_info_t *) data;
        struct net_device *dev = local->dev;
-       u16 channel;
+       u16 chan;
 
        if (local->passive_scan_interval <= 0)
                return;
@@ -2872,11 +2868,11 @@ static void hostap_passive_scan(unsigned long data)
 
                printk(KERN_DEBUG "%s: passive scan channel %d\n",
                       dev->name, local->passive_scan_channel);
-               channel = local->passive_scan_channel;
+               chan = local->passive_scan_channel;
                local->passive_scan_state = PASSIVE_SCAN_WAIT;
                local->passive_scan_timer.expires = jiffies + HZ / 10;
        } else {
-               channel = local->channel;
+               chan = local->channel;
                local->passive_scan_state = PASSIVE_SCAN_LISTEN;
                local->passive_scan_timer.expires = jiffies +
                        local->passive_scan_interval * HZ;
@@ -2884,9 +2880,9 @@ static void hostap_passive_scan(unsigned long data)
 
        if (hfa384x_cmd_callback(dev, HFA384X_CMDCODE_TEST |
                                 (HFA384X_TEST_CHANGE_CHANNEL << 8),
-                                channel, NULL, 0))
+                                chan, NULL, 0))
                printk(KERN_ERR "%s: passive scan channel set %d "
-                      "failed\n", dev->name, channel);
+                      "failed\n", dev->name, chan);
 
        add_timer(&local->passive_scan_timer);
 }
@@ -2894,9 +2890,10 @@ static void hostap_passive_scan(unsigned long data)
 
 /* Called only as a scheduled task when communications quality values should
  * be updated. */
-static void handle_comms_qual_update(void *data)
+static void handle_comms_qual_update(struct work_struct *work)
 {
-       local_info_t *local = data;
+       local_info_t *local =
+               container_of(work, local_info_t, comms_qual_update);
        prism2_update_comms_qual(local->dev);
 }
 
@@ -3013,14 +3010,12 @@ static int prism2_set_tim(struct net_device *dev, int aid, int set)
        iface = netdev_priv(dev);
        local = iface->local;
 
-       new_entry = (struct set_tim_data *)
-               kmalloc(sizeof(*new_entry), GFP_ATOMIC);
+       new_entry = kzalloc(sizeof(*new_entry), GFP_ATOMIC);
        if (new_entry == NULL) {
                printk(KERN_DEBUG "%s: prism2_set_tim: kmalloc failed\n",
                       local->dev->name);
                return -ENOMEM;
        }
-       memset(new_entry, 0, sizeof(*new_entry));
        new_entry->aid = aid;
        new_entry->set = set;
 
@@ -3048,9 +3043,9 @@ static int prism2_set_tim(struct net_device *dev, int aid, int set)
 }
 
 
-static void handle_set_tim_queue(void *data)
+static void handle_set_tim_queue(struct work_struct *work)
 {
-       local_info_t *local = (local_info_t *) data;
+       local_info_t *local = container_of(work, local_info_t, set_tim_queue);
        struct set_tim_data *entry;
        u16 val;
 
@@ -3096,6 +3091,29 @@ static void prism2_clear_set_tim_queue(local_info_t *local)
 }
 
 
+/*
+ * HostAP uses two layers of net devices, where the inner
+ * layer gets called all the time from the outer layer.
+ * This is a natural nesting, which needs a split lock type.
+ */
+static struct lock_class_key hostap_netdev_xmit_lock_key;
+static struct lock_class_key hostap_netdev_addr_lock_key;
+
+static void prism2_set_lockdep_class_one(struct net_device *dev,
+                                        struct netdev_queue *txq,
+                                        void *_unused)
+{
+       lockdep_set_class(&txq->_xmit_lock,
+                         &hostap_netdev_xmit_lock_key);
+}
+
+static void prism2_set_lockdep_class(struct net_device *dev)
+{
+       lockdep_set_class(&dev->addr_list_lock,
+                         &hostap_netdev_addr_lock_key);
+       netdev_for_each_tx_queue(dev, prism2_set_lockdep_class_one, NULL);
+}
+
 static struct net_device *
 prism2_init_local_data(struct prism2_helper_functions *funcs, int card_idx,
                       struct device *sdev)
@@ -3165,7 +3183,7 @@ prism2_init_local_data(struct prism2_helper_functions *funcs, int card_idx,
        spin_lock_init(&local->cmdlock);
        spin_lock_init(&local->baplock);
        spin_lock_init(&local->lock);
-       init_MUTEX(&local->rid_bap_sem);
+       mutex_init(&local->rid_bap_mtx);
 
        if (card_idx < 0 || card_idx >= MAX_PARM_DEVICES)
                card_idx = 0;
@@ -3197,17 +3215,18 @@ 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;
+       local->monitor_type = PRISM2_MONITOR_RADIOTAP;
 
        /* Initialize task queue structures */
-       INIT_WORK(&local->reset_queue, handle_reset_queue, local);
+       INIT_WORK(&local->reset_queue, handle_reset_queue);
        INIT_WORK(&local->set_multicast_list_queue,
-                 hostap_set_multicast_list_queue, local->dev);
+                 hostap_set_multicast_list_queue);
 
-       INIT_WORK(&local->set_tim_queue, handle_set_tim_queue, local);
+       INIT_WORK(&local->set_tim_queue, handle_set_tim_queue);
        INIT_LIST_HEAD(&local->set_tim_list);
        spin_lock_init(&local->set_tim_lock);
 
-       INIT_WORK(&local->comms_qual_update, handle_comms_qual_update, local);
+       INIT_WORK(&local->comms_qual_update, handle_comms_qual_update);
 
        /* Initialize tasklets for handling hardware IRQ related operations
         * outside hw IRQ handler */
@@ -3248,18 +3267,19 @@ while (0)
 
        INIT_LIST_HEAD(&local->bss_list);
 
-       hostap_setup_dev(dev, local, 1);
-       local->saved_eth_header_parse = dev->hard_header_parse;
+       hostap_setup_dev(dev, local, HOSTAP_INTERFACE_MASTER);
 
        dev->hard_start_xmit = hostap_master_start_xmit;
        dev->type = ARPHRD_IEEE80211;
-       dev->hard_header_parse = hostap_80211_header_parse;
+       dev->header_ops = &hostap_80211_ops;
 
        rtnl_lock();
        ret = dev_alloc_name(dev, "wifi%d");
        SET_NETDEV_DEV(dev, sdev);
        if (ret >= 0)
                ret = register_netdevice(dev);
+
+       prism2_set_lockdep_class(dev);
        rtnl_unlock();
        if (ret < 0) {
                printk(KERN_WARNING "%s: register netdevice failed!\n",
@@ -3268,11 +3288,6 @@ while (0)
        }
        printk(KERN_INFO "%s: Registered netdevice %s\n", dev_info, dev->name);
 
-#ifndef PRISM2_NO_PROCFS_DEBUG
-       create_proc_read_entry("registers", 0, local->proc,
-                              prism2_registers_proc_read, local);
-#endif /* PRISM2_NO_PROCFS_DEBUG */
-
        hostap_init_data(local);
        return dev;
 
@@ -3299,6 +3314,10 @@ static int hostap_hw_ready(struct net_device *dev)
                        netif_carrier_off(local->ddev);
                }
                hostap_init_proc(local);
+#ifndef PRISM2_NO_PROCFS_DEBUG
+               create_proc_read_entry("registers", 0, local->proc,
+                                      prism2_registers_proc_read, local);
+#endif /* PRISM2_NO_PROCFS_DEBUG */
                hostap_init_ap_proc(local);
                return 0;
        }
@@ -3409,14 +3428,14 @@ static void prism2_free_local_data(struct net_device *dev)
 }
 
 
-#ifndef PRISM2_PLX
+#if (defined(PRISM2_PCI) && defined(CONFIG_PM)) || defined(PRISM2_PCCARD)
 static void prism2_suspend(struct net_device *dev)
 {
        struct hostap_interface *iface;
        struct local_info *local;
        union iwreq_data wrqu;
 
-       iface = dev->priv;
+       iface = netdev_priv(dev);
        local = iface->local;
 
        /* Send disconnect event, e.g., to trigger reassociation after resume
@@ -3428,7 +3447,7 @@ static void prism2_suspend(struct net_device *dev)
        /* Disable hardware and firmware */
        prism2_hw_shutdown(dev, 0);
 }
-#endif /* PRISM2_PLX */
+#endif /* (PRISM2_PCI && CONFIG_PM) || PRISM2_PCCARD */
 
 
 /* These might at some point be compiled separately and used as separate