Merge branch 'upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/linville...
authorJeff Garzik <jeff@garzik.org>
Thu, 8 Jun 2006 19:48:25 +0000 (15:48 -0400)
committerJeff Garzik <jeff@garzik.org>
Thu, 8 Jun 2006 19:48:25 +0000 (15:48 -0400)
15 files changed:
drivers/net/wireless/Kconfig
drivers/net/wireless/Makefile
drivers/net/wireless/bcm43xx/bcm43xx_main.c
drivers/net/wireless/zd1201.c [moved from drivers/usb/net/zd1201.c with 97% similarity]
drivers/net/wireless/zd1201.h [moved from drivers/usb/net/zd1201.h with 100% similarity]
drivers/usb/net/Kconfig
drivers/usb/net/Makefile
include/net/ieee80211.h
include/net/ieee80211softmac.h
net/ieee80211/ieee80211_tx.c
net/ieee80211/softmac/Kconfig
net/ieee80211/softmac/ieee80211softmac_assoc.c
net/ieee80211/softmac/ieee80211softmac_auth.c
net/ieee80211/softmac/ieee80211softmac_event.c
net/ieee80211/softmac/ieee80211softmac_io.c

index d7691c4..30ec235 100644 (file)
@@ -531,6 +531,23 @@ config PRISM54
          say M here and read <file:Documentation/modules.txt>.  The module
          will be called prism54.ko.
 
+config USB_ZD1201
+       tristate "USB ZD1201 based Wireless device support"
+       depends on USB && NET_RADIO
+       select FW_LOADER
+       ---help---
+         Say Y if you want to use wireless LAN adapters based on the ZyDAS
+         ZD1201 chip.
+
+         This driver makes the adapter appear as a normal Ethernet interface,
+         typically on wlan0.
+
+         The zd1201 device requires external firmware to be loaded.
+         This can be found at http://linux-lc100020.sourceforge.net/
+
+         To compile this driver as a module, choose M here: the
+         module will be called zd1201.
+
 source "drivers/net/wireless/hostap/Kconfig"
 source "drivers/net/wireless/bcm43xx/Kconfig"
 
index c867798..512603d 100644 (file)
@@ -40,3 +40,5 @@ obj-$(CONFIG_BCM43XX)         += bcm43xx/
 # 16-bit wireless PCMCIA client drivers
 obj-$(CONFIG_PCMCIA_RAYCS)     += ray_cs.o
 obj-$(CONFIG_PCMCIA_WL3501)    += wl3501_cs.o
+
+obj-$(CONFIG_USB_ZD1201)       += zd1201.o
index c050290..736dde9 100644 (file)
@@ -3555,7 +3555,7 @@ static void bcm43xx_ieee80211_set_security(struct net_device *net_dev,
        unsigned long flags;
        int keyidx;
        
-       dprintk(KERN_INFO PFX "set security called\n");
+       dprintk(KERN_INFO PFX "set security called");
 
        bcm43xx_lock_mmio(bcm, flags);
 
@@ -3568,24 +3568,25 @@ static void bcm43xx_ieee80211_set_security(struct net_device *net_dev,
        
        if (sec->flags & SEC_ACTIVE_KEY) {
                secinfo->active_key = sec->active_key;
-               dprintk(KERN_INFO PFX "   .active_key = %d\n", sec->active_key);
+               dprintk(", .active_key = %d", sec->active_key);
        }
        if (sec->flags & SEC_UNICAST_GROUP) {
                secinfo->unicast_uses_group = sec->unicast_uses_group;
-               dprintk(KERN_INFO PFX "   .unicast_uses_group = %d\n", sec->unicast_uses_group);
+               dprintk(", .unicast_uses_group = %d", sec->unicast_uses_group);
        }
        if (sec->flags & SEC_LEVEL) {
                secinfo->level = sec->level;
-               dprintk(KERN_INFO PFX "   .level = %d\n", sec->level);
+               dprintk(", .level = %d", sec->level);
        }
        if (sec->flags & SEC_ENABLED) {
                secinfo->enabled = sec->enabled;
-               dprintk(KERN_INFO PFX "   .enabled = %d\n", sec->enabled);
+               dprintk(", .enabled = %d", sec->enabled);
        }
        if (sec->flags & SEC_ENCRYPT) {
                secinfo->encrypt = sec->encrypt;
-               dprintk(KERN_INFO PFX "   .encrypt = %d\n", sec->encrypt);
+               dprintk(", .encrypt = %d", sec->encrypt);
        }
+       dprintk("\n");
        if (bcm->initialized && !bcm->ieee->host_encrypt) {
                if (secinfo->enabled) {
                        /* upload WEP keys to hardware */
similarity index 97%
rename from drivers/usb/net/zd1201.c
rename to drivers/net/wireless/zd1201.c
index 9b1e4ed..662ecc8 100644 (file)
@@ -33,7 +33,7 @@ static struct usb_device_id zd1201_table[] = {
        {}
 };
 
-static int ap = 0;     /* Are we an AP or a normal station? */
+static int ap; /* Are we an AP or a normal station? */
 
 #define ZD1201_VERSION "0.15"
 
@@ -49,7 +49,7 @@ MODULE_DEVICE_TABLE(usb, zd1201_table);
 static int zd1201_fw_upload(struct usb_device *dev, int apfw)
 {
        const struct firmware *fw_entry;
-       chardata;
+       char *data;
        unsigned long len;
        int err;
        unsigned char ret;
@@ -65,7 +65,7 @@ static int zd1201_fw_upload(struct usb_device *dev, int apfw)
        if (err) {
                dev_err(&dev->dev, "Failed to load %s firmware file!\n", fwfile);
                dev_err(&dev->dev, "Make sure the hotplug firmware loader is installed.\n");
-               dev_err(&dev->dev, "Goto http://linux-lc100020.sourceforge.net for more info\n");
+               dev_err(&dev->dev, "Goto http://linux-lc100020.sourceforge.net for more info.\n");
                return err;
        }
 
@@ -94,12 +94,12 @@ static int zd1201_fw_upload(struct usb_device *dev, int apfw)
            USB_DIR_OUT | 0x40, 0, 0, NULL, 0, ZD1201_FW_TIMEOUT);
        if (err < 0)
                goto exit;
-                                                                                                                                                                
+
        err = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 0x4,
            USB_DIR_IN | 0x40, 0,0, &ret, sizeof(ret), ZD1201_FW_TIMEOUT);
        if (err < 0)
                goto exit;
-                                                                                                                                                                                                                                                                                        
+
        if (ret & 0x80) {
                err = -EIO;
                goto exit;
@@ -166,13 +166,13 @@ static int zd1201_docmd(struct zd1201 *zd, int cmd, int parm0,
                return -ENOMEM;
        }
        usb_fill_bulk_urb(urb, zd->usb, usb_sndbulkpipe(zd->usb, zd->endp_out2),
-            command, 16, zd1201_usbfree, zd);
+                         command, 16, zd1201_usbfree, zd);
        ret = usb_submit_urb(urb, GFP_ATOMIC);
        if (ret) {
                kfree(command);
                usb_free_urb(urb);
        }
-       
+
        return ret;
 }
 
@@ -316,7 +316,7 @@ static void zd1201_usbrx(struct urb *urb, struct pt_regs *regs)
                fc = le16_to_cpu(*(__le16 *)&data[datalen-16]);
                seq = le16_to_cpu(*(__le16 *)&data[datalen-24]);
 
-               if(zd->monitor) {
+               if (zd->monitor) {
                        if (datalen < 24)
                                goto resubmit;
                        if (!(skb = dev_alloc_skb(datalen+24)))
@@ -364,7 +364,7 @@ static void zd1201_usbrx(struct urb *urb, struct pt_regs *regs)
                                goto resubmit;
                        }
                        hlist_for_each_entry(frag, node, &zd->fraglist, fnode)
-                               if(frag->seq == (seq&IEEE80211_SCTL_SEQ))
+                               if (frag->seq == (seq&IEEE80211_SCTL_SEQ))
                                        break;
                        if (!frag)
                                goto resubmit;
@@ -376,7 +376,6 @@ static void zd1201_usbrx(struct urb *urb, struct pt_regs *regs)
                                goto resubmit;
                        hlist_del_init(&frag->fnode);
                        kfree(frag);
-                       /* Fallthrough */
                } else {
                        if (datalen<14)
                                goto resubmit;
@@ -422,7 +421,7 @@ static int zd1201_getconfig(struct zd1201 *zd, int rid, void *riddata,
        int rid_fid;
        int length;
        unsigned char *pdata;
-       
+
        zd->rxdatas = 0;
        err = zd1201_docmd(zd, ZD1201_CMDCODE_ACCESS, rid, 0, 0);
        if (err)
@@ -471,11 +470,11 @@ static int zd1201_getconfig(struct zd1201 *zd, int rid, void *riddata,
        length = zd->rxlen;
 
        do {
-               int  actual_length;
+               int actual_length;
 
                actual_length = (length > 64) ? 64 : length;
 
-               if(pdata[0] != 0x3) {
+               if (pdata[0] != 0x3) {
                        dev_dbg(&zd->usb->dev, "Rx Resource packet type error: %02X\n",
                            pdata[0]);
                        return -EINVAL;
@@ -487,11 +486,10 @@ static int zd1201_getconfig(struct zd1201 *zd, int rid, void *riddata,
                }
 
                /* Skip the 4 bytes header (RID length and RID) */
-               if(i == 0) {
+               if (i == 0) {
                        pdata += 8;
                        actual_length -= 8;
-               }
-               else {
+               } else {
                        pdata += 4;
                        actual_length -= 4;
                }
@@ -620,7 +618,7 @@ static int zd1201_drvr_start(struct zd1201 *zd)
        short max;
        __le16 zdmax;
        unsigned char *buffer;
-       
+
        buffer = kzalloc(ZD1201_RXSIZE, GFP_KERNEL);
        if (!buffer)
                return -ENOMEM;
@@ -632,7 +630,7 @@ static int zd1201_drvr_start(struct zd1201 *zd)
        err = usb_submit_urb(zd->rx_urb, GFP_KERNEL);
        if (err)
                goto err_buffer;
-       
+
        err = zd1201_docmd(zd, ZD1201_CMDCODE_INIT, 0, 0, 0);
        if (err)
                goto err_urb;
@@ -684,7 +682,7 @@ static int zd1201_enable(struct zd1201 *zd)
 static int zd1201_disable(struct zd1201 *zd)
 {
        int err;
-       
+
        if (!zd->mac_enabled)
                return 0;
        if (zd->monitor) {
@@ -764,7 +762,6 @@ static int zd1201_net_open(struct net_device *dev)
 static int zd1201_net_stop(struct net_device *dev)
 {
        netif_stop_queue(dev);
-       
        return 0;
 }
 
@@ -915,7 +912,6 @@ static int zd1201_get_name(struct net_device *dev,
     struct iw_request_info *info, char *name, char *extra)
 {
        strcpy(name, "IEEE 802.11b");
-
        return 0;
 }
 
@@ -1013,11 +1009,10 @@ static int zd1201_set_mode(struct net_device *dev,
                        if (err)
                                return err;
        }
-       zd->monitor=monitor;
+       zd->monitor = monitor;
        /* If monitor mode is set we don't actually turn it on here since it
         * is done during mac reset anyway (see zd1201_mac_enable).
         */
-
        zd1201_mac_reset(zd);
 
        return 0;
@@ -1117,7 +1112,7 @@ static int zd1201_get_wap(struct net_device *dev,
                zd->iwstats.qual.updated = 2;
        }
 
-       return zd1201_getconfig(zd,ZD1201_RID_CURRENTBSSID,ap_addr->sa_data,6);
+       return zd1201_getconfig(zd, ZD1201_RID_CURRENTBSSID, ap_addr->sa_data, 6);
 }
 
 static int zd1201_set_scan(struct net_device *dev,
@@ -1275,7 +1270,7 @@ static int zd1201_set_rate(struct net_device *dev,
        if (!rrq->fixed) { /* Also enable all lower bitrates */
                rate |= rate-1;
        }
-       
+
        err = zd1201_setconfig16(zd, ZD1201_RID_TXRATECNTL, rate);
        if (err)
                return err;
@@ -1486,7 +1481,7 @@ static int zd1201_get_encode(struct net_device *dev,
                return -EINVAL;
 
        erq->flags |= i+1;
-       
+
        erq->length = zd->encode_keylen[i];
        memcpy(key, zd->encode_keys[i], erq->length);
 
@@ -1529,11 +1524,7 @@ static int zd1201_set_power(struct net_device *dev,
                return -EINVAL;
        }
 out:
-       err = zd1201_setconfig16(zd, ZD1201_RID_CNFPMENABLED, enabled);
-       if (err)
-               return err;
-
-       return 0;
+       return zd1201_setconfig16(zd, ZD1201_RID_CNFPMENABLED, enabled);
 }
 
 static int zd1201_get_power(struct net_device *dev,
@@ -1627,15 +1618,11 @@ static int zd1201_set_hostauth(struct net_device *dev,
     struct iw_request_info *info, struct iw_param *rrq, char *extra)
 {
        struct zd1201 *zd = (struct zd1201 *)dev->priv;
-       int err;
 
        if (!zd->ap)
                return -EOPNOTSUPP;
 
-       err = zd1201_setconfig16(zd, ZD1201_RID_CNFHOSTAUTH, rrq->value);
-       if (err)
-               return err;
-       return 0;
+       return zd1201_setconfig16(zd, ZD1201_RID_CNFHOSTAUTH, rrq->value);
 }
 
 static int zd1201_get_hostauth(struct net_device *dev,
@@ -1744,7 +1731,7 @@ static int zd1201_probe(struct usb_interface *interface,
 {
        struct zd1201 *zd;
        struct usb_device *usb;
-       int i, err;
+       int err;
        short porttype;
        char buf[IW_ESSID_MAX_SIZE+2];
 
@@ -1773,9 +1760,7 @@ static int zd1201_probe(struct usb_interface *interface,
        if (!zd->rx_urb || !zd->tx_urb)
                goto err_zd;
 
-       for(i = 0; i<100; i++)
-               udelay(1000);
-
+       mdelay(100);
        err = zd1201_drvr_start(zd);
        if (err)
                goto err_zd;
@@ -1833,7 +1818,7 @@ static int zd1201_probe(struct usb_interface *interface,
                goto err_net;
        dev_info(&usb->dev, "%s: ZD1201 USB Wireless interface\n",
            zd->dev->name);
-       
+
        usb_set_intfdata(interface, zd);
        return 0;
 
index efd6ca7..0540596 100644 (file)
@@ -301,21 +301,4 @@ config USB_NET_ZAURUS
          some cases CDC MDLM) protocol, not "g_ether".
 
 
-config USB_ZD1201
-       tristate "USB ZD1201 based Wireless device support"
-       depends on NET_RADIO
-       select FW_LOADER
-       ---help---
-         Say Y if you want to use wireless LAN adapters based on the ZyDAS
-         ZD1201 chip.
-
-         This driver makes the adapter appear as a normal Ethernet interface,
-         typically on wlan0.
-         
-         The zd1201 device requires external firmware to be loaded.
-         This can be found at http://linux-lc100020.sourceforge.net/
-         
-         To compile this driver as a module, choose M here: the
-         module will be called zd1201.
-
 endmenu
index a21e6ea..160f19d 100644 (file)
@@ -15,7 +15,6 @@ obj-$(CONFIG_USB_NET_RNDIS_HOST)      += rndis_host.o
 obj-$(CONFIG_USB_NET_CDC_SUBSET)       += cdc_subset.o
 obj-$(CONFIG_USB_NET_ZAURUS)   += zaurus.o
 obj-$(CONFIG_USB_USBNET)       += usbnet.o
-obj-$(CONFIG_USB_ZD1201)       += zd1201.o
 
 ifeq ($(CONFIG_USB_DEBUG),y)
 EXTRA_CFLAGS += -DDEBUG
index 293e920..d514777 100644 (file)
@@ -1247,7 +1247,8 @@ extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
 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);
+                             struct ieee80211_hdr *frame, int hdr_len,
+                             int total_len, int encrypt_mpdu);
 
 /* ieee80211_rx.c */
 extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
index 703463a..7a483ab 100644 (file)
@@ -310,7 +310,7 @@ extern void ieee80211softmac_stop(struct net_device *dev);
  *     - context set to the context data you want passed
  * The return value is 0, or an error.
  */
-typedef void (*notify_function_ptr)(struct net_device *dev, void *context);
+typedef void (*notify_function_ptr)(struct net_device *dev, int event_type, void *context);
 
 #define ieee80211softmac_notify(dev, event, fun, context) ieee80211softmac_notify_gfp(dev, event, fun, context, GFP_KERNEL);
 #define ieee80211softmac_notify_atomic(dev, event, fun, context) ieee80211softmac_notify_gfp(dev, event, fun, context, GFP_ATOMIC);
index 233d527..6a5de1b 100644 (file)
@@ -555,7 +555,8 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
 /* 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_hdr *frame, int hdr_len, int total_len,
+                      int encrypt_mpdu)
 {
        struct ieee80211_txb *txb = NULL;
        unsigned long flags;
@@ -565,6 +566,9 @@ int ieee80211_tx_frame(struct ieee80211_device *ieee,
 
        spin_lock_irqsave(&ieee->lock, flags);
 
+       if (encrypt_mpdu && !ieee->sec.encrypt)
+               encrypt_mpdu = 0;
+
        /* If there is no driver handler to take the TXB, dont' bother
         * creating it... */
        if (!ieee->hard_start_xmit) {
@@ -572,32 +576,41 @@ int ieee80211_tx_frame(struct ieee80211_device *ieee,
                goto success;
        }
 
-       if (unlikely(len < 24)) {
+       if (unlikely(total_len < 24)) {
                printk(KERN_WARNING "%s: skb too small (%d).\n",
-                      ieee->dev->name, len);
+                      ieee->dev->name, total_len);
                goto success;
        }
 
+       if (encrypt_mpdu)
+               frame->frame_ctl |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
+
        /* 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, ieee->tx_headroom, GFP_ATOMIC);
+       txb = ieee80211_alloc_txb(1, total_len, ieee->tx_headroom, 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;
+       txb->payload_size = total_len;
 
        skb_frag = txb->fragments[0];
 
-       memcpy(skb_put(skb_frag, len), frame, len);
+       memcpy(skb_put(skb_frag, total_len), frame, total_len);
 
        if (ieee->config &
            (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
                skb_put(skb_frag, 4);
 
+       /* To avoid overcomplicating things, we do the corner-case frame
+        * encryption in software. The only real situation where encryption is
+        * needed here is during software-based shared key authentication. */
+       if (encrypt_mpdu)
+               ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
+
       success:
        spin_unlock_irqrestore(&ieee->lock, flags);
 
index f2a27cc..2811651 100644 (file)
@@ -2,6 +2,7 @@ config IEEE80211_SOFTMAC
        tristate "Software MAC add-on to the IEEE 802.11 networking stack"
        depends on IEEE80211 && EXPERIMENTAL
        select WIRELESS_EXT
+       select IEEE80211_CRYPT_WEP
        ---help---
        This option enables the hardware independent software MAC addon
        for the IEEE 802.11 networking stack.
index 5d90b9a..5e9a906 100644 (file)
@@ -164,12 +164,28 @@ network_matches_request(struct ieee80211softmac_device *mac, struct ieee80211_ne
 }
 
 static void
-ieee80211softmac_assoc_notify(struct net_device *dev, void *context)
+ieee80211softmac_assoc_notify_scan(struct net_device *dev, int event_type, void *context)
 {
        struct ieee80211softmac_device *mac = ieee80211_priv(dev);
        ieee80211softmac_assoc_work((void*)mac);
 }
 
+static void
+ieee80211softmac_assoc_notify_auth(struct net_device *dev, int event_type, void *context)
+{
+       struct ieee80211softmac_device *mac = ieee80211_priv(dev);
+
+       switch (event_type) {
+       case IEEE80211SOFTMAC_EVENT_AUTHENTICATED:
+               ieee80211softmac_assoc_work((void*)mac);
+               break;
+       case IEEE80211SOFTMAC_EVENT_AUTH_FAILED:
+       case IEEE80211SOFTMAC_EVENT_AUTH_TIMEOUT:
+               ieee80211softmac_disassoc(mac);
+               break;
+       }
+}
+
 /* This function is called to handle userspace requests (asynchronously) */
 void
 ieee80211softmac_assoc_work(void *d)
@@ -249,7 +265,7 @@ ieee80211softmac_assoc_work(void *d)
                         * Maybe we can hope to have more memory after scanning finishes ;)
                         */
                        dprintk(KERN_INFO PFX "Associate: Scanning for networks first.\n");
-                       ieee80211softmac_notify(mac->dev, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, ieee80211softmac_assoc_notify, NULL);
+                       ieee80211softmac_notify(mac->dev, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, ieee80211softmac_assoc_notify_scan, NULL);
                        if (ieee80211softmac_start_scan(mac))
                                dprintk(KERN_INFO PFX "Associate: failed to initiate scan. Is device up?\n");
                        return;
@@ -284,7 +300,7 @@ ieee80211softmac_assoc_work(void *d)
                 * otherwise adding the notification would be racy. */
                if (!ieee80211softmac_auth_req(mac, found)) {
                        dprintk(KERN_INFO PFX "cannot associate without being authenticated, requested authentication\n");
-                       ieee80211softmac_notify_internal(mac, IEEE80211SOFTMAC_EVENT_ANY, found, ieee80211softmac_assoc_notify, NULL, GFP_KERNEL);
+                       ieee80211softmac_notify_internal(mac, IEEE80211SOFTMAC_EVENT_ANY, found, ieee80211softmac_assoc_notify_auth, NULL, GFP_KERNEL);
                } else {
                        printkl(KERN_WARNING PFX "Not authenticated, but requesting authentication failed. Giving up to associate\n");
                        ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, found);
index 084b621..90b8484 100644 (file)
@@ -107,6 +107,7 @@ ieee80211softmac_auth_queue(void *data)
        printkl(KERN_WARNING PFX "Authentication timed out with "MAC_FMT"\n", MAC_ARG(net->bssid));
        /* Remove this item from the queue */
        spin_lock_irqsave(&mac->lock, flags);
+       net->authenticating = 0;
        ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_AUTH_TIMEOUT, net);
        cancel_delayed_work(&auth->work); /* just to make sure... */
        list_del(&auth->list);
@@ -212,13 +213,13 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth)
                        aq->state = IEEE80211SOFTMAC_AUTH_SHARED_RESPONSE; 
                        spin_unlock_irqrestore(&mac->lock, flags);
 
-                       /* Switch to correct channel for this network */
-                       mac->set_channel(mac->dev, net->channel);
-                       
-                       /* Send our response (How to encrypt?) */
+                       /* Send our response */
                        ieee80211softmac_send_mgt_frame(mac, aq->net, IEEE80211_STYPE_AUTH, aq->state);
-                       break;
+                       return 0;
                case IEEE80211SOFTMAC_AUTH_SHARED_PASS:
+                       kfree(net->challenge);
+                       net->challenge = NULL;
+                       net->challenge_len = 0;
                        /* Check the status code of the response */
                        switch(auth->status) {
                        case WLAN_STATUS_SUCCESS:
@@ -229,6 +230,7 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth)
                                spin_unlock_irqrestore(&mac->lock, flags);
                                printkl(KERN_NOTICE PFX "Shared Key Authentication completed with "MAC_FMT"\n", 
                                        MAC_ARG(net->bssid));
+                               ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_AUTHENTICATED, net);
                                break;
                        default:
                                printkl(KERN_NOTICE PFX "Shared Key Authentication with "MAC_FMT" failed, error code: %i\n", 
index 4b153f7..f34fa2e 100644 (file)
@@ -78,7 +78,7 @@ ieee80211softmac_notify_callback(void *d)
        struct ieee80211softmac_event event = *(struct ieee80211softmac_event*) d;
        kfree(d);
        
-       event.fun(event.mac->dev, event.context);
+       event.fun(event.mac->dev, event.event_type, event.context);
 }
 
 int
@@ -167,6 +167,9 @@ ieee80211softmac_call_events_locked(struct ieee80211softmac_device *mac, int eve
                        if ((eventptr->event_type == event || eventptr->event_type == -1)
                                && (eventptr->event_context == NULL || eventptr->event_context == event_ctx)) {
                                list_del(&eventptr->list);
+                               /* User may have subscribed to ANY event, so
+                                * we tell them which event triggered it. */
+                               eventptr->event_type = event;
                                schedule_work(&eventptr->work);
                        }
                }
index cc6cd56..0954161 100644 (file)
@@ -149,6 +149,56 @@ ieee80211softmac_hdr_3addr(struct ieee80211softmac_device *mac,
         * shouldn't the sequence number be in ieee80211? */
 }
 
+static u16
+ieee80211softmac_capabilities(struct ieee80211softmac_device *mac,
+       struct ieee80211softmac_network *net)
+{
+       u16 capability = 0;
+
+       /* ESS and IBSS bits are set according to the current mode */
+       switch (mac->ieee->iw_mode) {
+       case IW_MODE_INFRA:
+               capability = cpu_to_le16(WLAN_CAPABILITY_ESS);
+               break;
+       case IW_MODE_ADHOC:
+               capability = cpu_to_le16(WLAN_CAPABILITY_IBSS);
+               break;
+       case IW_MODE_AUTO:
+               capability = net->capabilities &
+                       (WLAN_CAPABILITY_ESS|WLAN_CAPABILITY_IBSS);
+               break;
+       default:
+               /* bleh. we don't ever go to these modes */
+               printk(KERN_ERR PFX "invalid iw_mode!\n");
+               break;
+       }
+
+       /* CF Pollable / CF Poll Request */
+       /* Needs to be implemented, for now, the 0's == not supported */
+
+       /* Privacy Bit */
+       capability |= mac->ieee->sec.level ?
+               cpu_to_le16(WLAN_CAPABILITY_PRIVACY) : 0;
+
+       /* Short Preamble */
+       /* Always supported: we probably won't ever be powering devices which
+        * dont support this... */
+       capability |= WLAN_CAPABILITY_SHORT_PREAMBLE;
+
+       /* PBCC */
+       /* Not widely used */
+
+       /* Channel Agility */
+       /* Not widely used */
+
+       /* Short Slot */
+       /* Will be implemented later */
+
+       /* DSSS-OFDM */
+       /* Not widely used */
+
+       return capability;
+}
 
 /*****************************************************************************
  * Create Management packets
@@ -179,27 +229,6 @@ ieee80211softmac_assoc_req(struct ieee80211_assoc_request **pkt,
                return 0;
        ieee80211softmac_hdr_3addr(mac, &((*pkt)->header), IEEE80211_STYPE_ASSOC_REQ, net->bssid, net->bssid);
 
-       /* Fill in capability Info */
-       switch (mac->ieee->iw_mode) {
-       case IW_MODE_INFRA:
-               (*pkt)->capability = cpu_to_le16(WLAN_CAPABILITY_ESS);
-               break;
-       case IW_MODE_ADHOC:
-               (*pkt)->capability = cpu_to_le16(WLAN_CAPABILITY_IBSS);
-               break;
-       case IW_MODE_AUTO:
-               (*pkt)->capability = net->capabilities & (WLAN_CAPABILITY_ESS|WLAN_CAPABILITY_IBSS);
-               break;
-       default:
-               /* bleh. we don't ever go to these modes */
-               printk(KERN_ERR PFX "invalid iw_mode!\n");
-               break;
-       }
-       /* Need to add this
-       (*pkt)->capability |= mac->ieee->short_slot ? 
-                       cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME) : 0;
-        */
-       (*pkt)->capability |= mac->ieee->sec.level ? cpu_to_le16(WLAN_CAPABILITY_PRIVACY) : 0;
        /* Fill in Listen Interval (?) */
        (*pkt)->listen_interval = cpu_to_le16(10);
        
@@ -239,17 +268,9 @@ ieee80211softmac_reassoc_req(struct ieee80211_reassoc_request **pkt,
                return 0;
        ieee80211softmac_hdr_3addr(mac, &((*pkt)->header), IEEE80211_STYPE_REASSOC_REQ, net->bssid, net->bssid);
 
-       /* Fill in capability Info */
-       (*pkt)->capability = mac->ieee->iw_mode == IW_MODE_MASTER ? 
-                               cpu_to_le16(WLAN_CAPABILITY_ESS) :
-                               cpu_to_le16(WLAN_CAPABILITY_IBSS);
-       /*
-       (*pkt)->capability |= mac->ieee->short_slot ? 
-                       cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME) : 0;
-        */
-       (*pkt)->capability |= mac->ieee->sec.level ?
-                       cpu_to_le16(WLAN_CAPABILITY_PRIVACY) : 0;
-               
+       /* Fill in the capabilities */
+       (*pkt)->capability = ieee80211softmac_capabilities(mac, net);
+
        /* Fill in Listen Interval (?) */
        (*pkt)->listen_interval = cpu_to_le16(10);
        /* Fill in the current AP MAC */
@@ -268,26 +289,27 @@ ieee80211softmac_reassoc_req(struct ieee80211_reassoc_request **pkt,
 static u32
 ieee80211softmac_auth(struct ieee80211_auth **pkt, 
        struct ieee80211softmac_device *mac, struct ieee80211softmac_network *net,
-       u16 transaction, u16 status)
+       u16 transaction, u16 status, int *encrypt_mpdu)
 {
        u8 *data;
+       int auth_mode = mac->ieee->sec.auth_mode;
+       int is_shared_response = (auth_mode == WLAN_AUTH_SHARED_KEY
+               && transaction == IEEE80211SOFTMAC_AUTH_SHARED_RESPONSE);
+
        /* Allocate Packet */
        (*pkt) = (struct ieee80211_auth *)ieee80211softmac_alloc_mgt(
                2 +             /* Auth Algorithm */
                2 +             /* Auth Transaction Seq */
                2 +             /* Status Code */
                 /* Challenge Text IE */
-               mac->ieee->open_wep ? 0 : 
-               1 + 1 + WLAN_AUTH_CHALLENGE_LEN
-       );      
+               is_shared_response ? 0 : 1 + 1 + net->challenge_len
+       );
        if (unlikely((*pkt) == NULL))
                return 0;
        ieee80211softmac_hdr_3addr(mac, &((*pkt)->header), IEEE80211_STYPE_AUTH, net->bssid, net->bssid);
                
        /* Algorithm */
-       (*pkt)->algorithm = mac->ieee->open_wep ? 
-               cpu_to_le16(WLAN_AUTH_OPEN) :
-               cpu_to_le16(WLAN_AUTH_SHARED_KEY);
+       (*pkt)->algorithm = cpu_to_le16(auth_mode);
        /* Transaction */
        (*pkt)->transaction = cpu_to_le16(transaction);
        /* Status */
@@ -295,18 +317,20 @@ ieee80211softmac_auth(struct ieee80211_auth **pkt,
        
        data = (u8 *)(*pkt)->info_element;
        /* Challenge Text */
-       if(!mac->ieee->open_wep){
+       if (is_shared_response) {
                *data = MFIE_TYPE_CHALLENGE;
                data++;
                
                /* Copy the challenge in */
-               // *data = challenge length
-               // data += sizeof(u16);
-               // memcpy(data, challenge, challenge length);
-               // data += challenge length;
-               
-               /* Add the full size to the packet length */
-       }
+               *data = net->challenge_len;
+               data++;
+               memcpy(data, net->challenge, net->challenge_len);
+               data += net->challenge_len;
+
+               /* Make sure this frame gets encrypted with the shared key */
+               *encrypt_mpdu = 1;
+       } else
+               *encrypt_mpdu = 0;
 
        /* Return the packet size */
        return (data - (u8 *)(*pkt));
@@ -396,6 +420,7 @@ ieee80211softmac_send_mgt_frame(struct ieee80211softmac_device *mac,
 {
        void *pkt = NULL;
        u32 pkt_size = 0;
+       int encrypt_mpdu = 0;
 
        switch(type) {
        case IEEE80211_STYPE_ASSOC_REQ:
@@ -405,7 +430,7 @@ ieee80211softmac_send_mgt_frame(struct ieee80211softmac_device *mac,
                pkt_size = ieee80211softmac_reassoc_req((struct ieee80211_reassoc_request **)(&pkt), mac, (struct ieee80211softmac_network *)ptrarg);
                break;
        case IEEE80211_STYPE_AUTH:
-               pkt_size = ieee80211softmac_auth((struct ieee80211_auth **)(&pkt), mac, (struct ieee80211softmac_network *)ptrarg, (u16)(arg & 0xFFFF), (u16) (arg >> 16));
+               pkt_size = ieee80211softmac_auth((struct ieee80211_auth **)(&pkt), mac, (struct ieee80211softmac_network *)ptrarg, (u16)(arg & 0xFFFF), (u16) (arg >> 16), &encrypt_mpdu);
                break;
        case IEEE80211_STYPE_DISASSOC:
        case IEEE80211_STYPE_DEAUTH:
@@ -434,52 +459,8 @@ ieee80211softmac_send_mgt_frame(struct ieee80211softmac_device *mac,
         * or get rid of it alltogether?
         * Does this work for you now?
         */
-       ieee80211_tx_frame(mac->ieee, (struct ieee80211_hdr *)pkt, pkt_size);
-
-       kfree(pkt);
-       return 0;
-}
-
-
-/* Create an rts/cts frame */
-static u32
-ieee80211softmac_rts_cts(struct ieee80211_hdr_2addr **pkt,
-       struct ieee80211softmac_device *mac, struct ieee80211softmac_network *net, 
-       u32 type)
-{
-       /* Allocate Packet */
-       (*pkt) = kmalloc(IEEE80211_2ADDR_LEN, GFP_ATOMIC);      
-       memset(*pkt, 0, IEEE80211_2ADDR_LEN);
-       if((*pkt) == NULL)
-               return 0;
-       ieee80211softmac_hdr_2addr(mac, (*pkt), type, net->bssid);
-       return IEEE80211_2ADDR_LEN;
-}
-
-
-/* Sends a control packet */
-static int
-ieee80211softmac_send_ctl_frame(struct ieee80211softmac_device *mac,
-       struct ieee80211softmac_network *net, u32 type, u32 arg)
-{
-       void *pkt = NULL;
-       u32 pkt_size = 0;
-       
-       switch(type) {
-       case IEEE80211_STYPE_RTS:
-       case IEEE80211_STYPE_CTS:
-               pkt_size = ieee80211softmac_rts_cts((struct ieee80211_hdr_2addr **)(&pkt), mac, net, type);
-               break;
-       default:
-               printkl(KERN_DEBUG PFX "Unsupported Control Frame type: %i\n", type);
-               return -EINVAL;
-       }
-
-       if(pkt_size == 0)
-               return -ENOMEM;
-       
-       /* Send the packet to the ieee80211 layer for tx */
-       ieee80211_tx_frame(mac->ieee, (struct ieee80211_hdr *) pkt, pkt_size);
+       ieee80211_tx_frame(mac->ieee, (struct ieee80211_hdr *)pkt,
+               IEEE80211_3ADDR_LEN, pkt_size, encrypt_mpdu);
 
        kfree(pkt);
        return 0;