diff options
Diffstat (limited to 'net/ieee80211')
-rw-r--r-- | net/ieee80211/ieee80211_crypt_tkip.c | 1 | ||||
-rw-r--r-- | net/ieee80211/ieee80211_crypt_wep.c | 1 | ||||
-rw-r--r-- | net/ieee80211/ieee80211_module.c | 25 | ||||
-rw-r--r-- | net/ieee80211/ieee80211_rx.c | 80 | ||||
-rw-r--r-- | net/ieee80211/ieee80211_tx.c | 4 | ||||
-rw-r--r-- | net/ieee80211/softmac/ieee80211softmac_assoc.c | 30 | ||||
-rw-r--r-- | net/ieee80211/softmac/ieee80211softmac_auth.c | 49 | ||||
-rw-r--r-- | net/ieee80211/softmac/ieee80211softmac_event.c | 12 | ||||
-rw-r--r-- | net/ieee80211/softmac/ieee80211softmac_module.c | 4 | ||||
-rw-r--r-- | net/ieee80211/softmac/ieee80211softmac_priv.h | 15 | ||||
-rw-r--r-- | net/ieee80211/softmac/ieee80211softmac_scan.c | 20 | ||||
-rw-r--r-- | net/ieee80211/softmac/ieee80211softmac_wx.c | 9 |
12 files changed, 174 insertions, 76 deletions
diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c index 4200ec50986..fc1f99a5973 100644 --- a/net/ieee80211/ieee80211_crypt_tkip.c +++ b/net/ieee80211/ieee80211_crypt_tkip.c @@ -16,6 +16,7 @@ #include <linux/random.h> #include <linux/skbuff.h> #include <linux/netdevice.h> +#include <linux/mm.h> #include <linux/if_ether.h> #include <linux/if_arp.h> #include <asm/string.h> diff --git a/net/ieee80211/ieee80211_crypt_wep.c b/net/ieee80211/ieee80211_crypt_wep.c index 1b2efff11d3..7a95c3d8131 100644 --- a/net/ieee80211/ieee80211_crypt_wep.c +++ b/net/ieee80211/ieee80211_crypt_wep.c @@ -15,6 +15,7 @@ #include <linux/slab.h> #include <linux/random.h> #include <linux/skbuff.h> +#include <linux/mm.h> #include <asm/string.h> #include <net/ieee80211.h> diff --git a/net/ieee80211/ieee80211_module.c b/net/ieee80211/ieee80211_module.c index 13b1e5fff7e..b1c6d1f717d 100644 --- a/net/ieee80211/ieee80211_module.c +++ b/net/ieee80211/ieee80211_module.c @@ -67,7 +67,7 @@ static int ieee80211_networks_allocate(struct ieee80211_device *ieee) return 0; ieee->networks = - kmalloc(MAX_NETWORK_COUNT * sizeof(struct ieee80211_network), + kzalloc(MAX_NETWORK_COUNT * sizeof(struct ieee80211_network), GFP_KERNEL); if (!ieee->networks) { printk(KERN_WARNING "%s: Out of memory allocating beacons\n", @@ -75,9 +75,6 @@ static int ieee80211_networks_allocate(struct ieee80211_device *ieee) return -ENOMEM; } - memset(ieee->networks, 0, - MAX_NETWORK_COUNT * sizeof(struct ieee80211_network)); - return 0; } @@ -118,6 +115,21 @@ static void ieee80211_networks_initialize(struct ieee80211_device *ieee) &ieee->network_free_list); } +static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) +{ + if ((new_mtu < 68) || (new_mtu > IEEE80211_DATA_LEN)) + return -EINVAL; + dev->mtu = new_mtu; + return 0; +} + +static struct net_device_stats *ieee80211_generic_get_stats( + struct net_device *dev) +{ + struct ieee80211_device *ieee = netdev_priv(dev); + return &ieee->stats; +} + struct net_device *alloc_ieee80211(int sizeof_priv) { struct ieee80211_device *ieee; @@ -133,6 +145,11 @@ struct net_device *alloc_ieee80211(int sizeof_priv) } ieee = netdev_priv(dev); dev->hard_start_xmit = ieee80211_xmit; + dev->change_mtu = ieee80211_change_mtu; + + /* Drivers are free to override this if the generic implementation + * does not meet their needs. */ + dev->get_stats = ieee80211_generic_get_stats; ieee->dev = dev; diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c index 770704183a1..d97e5412e31 100644 --- a/net/ieee80211/ieee80211_rx.c +++ b/net/ieee80211/ieee80211_rx.c @@ -415,17 +415,16 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, ieee->host_mc_decrypt : ieee->host_decrypt; if (can_be_decrypted) { - int idx = 0; if (skb->len >= hdrlen + 3) { /* Top two-bits of byte 3 are the key index */ - idx = skb->data[hdrlen + 3] >> 6; + keyidx = skb->data[hdrlen + 3] >> 6; } - /* ieee->crypt[] is WEP_KEY (4) in length. Given that idx - * is only allowed 2-bits of storage, no value of idx can - * be provided via above code that would result in idx + /* ieee->crypt[] is WEP_KEY (4) in length. Given that keyidx + * is only allowed 2-bits of storage, no value of keyidx can + * be provided via above code that would result in keyidx * being out of range */ - crypt = ieee->crypt[idx]; + crypt = ieee->crypt[keyidx]; #ifdef NOT_YET sta = NULL; @@ -479,6 +478,11 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, goto rx_exit; } #endif + /* drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.29) */ + if (sc == ieee->prev_seq_ctl) + goto rx_dropped; + else + ieee->prev_seq_ctl = sc; /* Data frame - extract src/dst addresses */ if (skb->len < IEEE80211_3ADDR_LEN) @@ -655,6 +659,51 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb, goto rx_dropped; } + /* If the frame was decrypted in hardware, we may need to strip off + * any security data (IV, ICV, etc) that was left behind */ + if (!can_be_decrypted && (fc & IEEE80211_FCTL_PROTECTED) && + ieee->host_strip_iv_icv) { + int trimlen = 0; + + /* Top two-bits of byte 3 are the key index */ + if (skb->len >= hdrlen + 3) + keyidx = skb->data[hdrlen + 3] >> 6; + + /* To strip off any security data which appears before the + * payload, we simply increase hdrlen (as the header gets + * chopped off immediately below). For the security data which + * appears after the payload, we use skb_trim. */ + + switch (ieee->sec.encode_alg[keyidx]) { + case SEC_ALG_WEP: + /* 4 byte IV */ + hdrlen += 4; + /* 4 byte ICV */ + trimlen = 4; + break; + case SEC_ALG_TKIP: + /* 4 byte IV, 4 byte ExtIV */ + hdrlen += 8; + /* 8 byte MIC, 4 byte ICV */ + trimlen = 12; + break; + case SEC_ALG_CCMP: + /* 8 byte CCMP header */ + hdrlen += 8; + /* 8 byte MIC */ + trimlen = 8; + break; + } + + if (skb->len < trimlen) + goto rx_dropped; + + __skb_trim(skb, skb->len - trimlen); + + if (skb->len < hdrlen) + goto rx_dropped; + } + /* skb: hdr + (possible reassembled) full plaintext payload */ payload = skb->data + hdrlen; @@ -1078,12 +1127,12 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element while (length >= sizeof(*info_element)) { if (sizeof(*info_element) + info_element->len > length) { - IEEE80211_ERROR("Info elem: parse failed: " - "info_element->len + 2 > left : " - "info_element->len+2=%zd left=%d, id=%d.\n", - info_element->len + - sizeof(*info_element), - length, info_element->id); + IEEE80211_DEBUG_MGMT("Info elem: parse failed: " + "info_element->len + 2 > left : " + "info_element->len+2=%zd left=%d, id=%d.\n", + info_element->len + + sizeof(*info_element), + length, info_element->id); /* We stop processing but don't return an error here * because some misbehaviour APs break this rule. ie. * Orinoco AP1000. */ @@ -1255,12 +1304,11 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element case MFIE_TYPE_IBSS_DFS: if (network->ibss_dfs) break; - network->ibss_dfs = - kmalloc(info_element->len, GFP_ATOMIC); + network->ibss_dfs = kmemdup(info_element->data, + info_element->len, + GFP_ATOMIC); if (!network->ibss_dfs) return 1; - memcpy(network->ibss_dfs, info_element->data, - info_element->len); network->flags |= NETWORK_HAS_IBSS_DFS; break; diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c index ae254497ba3..854fc13cd78 100644 --- a/net/ieee80211/ieee80211_tx.c +++ b/net/ieee80211/ieee80211_tx.c @@ -390,7 +390,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) * 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; + bytes_per_frag = frag_size - hdr_len; if (ieee->config & (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS)) bytes_per_frag -= IEEE80211_FCS_LEN; @@ -412,7 +412,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) } else { nr_frags = 1; bytes_per_frag = bytes_last_frag = bytes; - frag_size = bytes + IEEE80211_3ADDR_LEN; + frag_size = bytes + hdr_len; } rts_required = (frag_size > ieee->rts diff --git a/net/ieee80211/softmac/ieee80211softmac_assoc.c b/net/ieee80211/softmac/ieee80211softmac_assoc.c index cf51c87a971..eec1a1dd91d 100644 --- a/net/ieee80211/softmac/ieee80211softmac_assoc.c +++ b/net/ieee80211/softmac/ieee80211softmac_assoc.c @@ -58,9 +58,11 @@ ieee80211softmac_assoc(struct ieee80211softmac_device *mac, struct ieee80211soft } void -ieee80211softmac_assoc_timeout(void *d) +ieee80211softmac_assoc_timeout(struct work_struct *work) { - struct ieee80211softmac_device *mac = (struct ieee80211softmac_device *)d; + struct ieee80211softmac_device *mac = + container_of(work, struct ieee80211softmac_device, + associnfo.timeout.work); struct ieee80211softmac_network *n; mutex_lock(&mac->associnfo.mutex); @@ -186,9 +188,11 @@ ieee80211softmac_assoc_notify_auth(struct net_device *dev, int event_type, void /* This function is called to handle userspace requests (asynchronously) */ void -ieee80211softmac_assoc_work(void *d) +ieee80211softmac_assoc_work(struct work_struct *work) { - struct ieee80211softmac_device *mac = (struct ieee80211softmac_device *)d; + struct ieee80211softmac_device *mac = + container_of(work, struct ieee80211softmac_device, + associnfo.work.work); struct ieee80211softmac_network *found = NULL; struct ieee80211_network *net = NULL, *best = NULL; int bssvalid; @@ -412,7 +416,7 @@ ieee80211softmac_handle_assoc_response(struct net_device * dev, network->authenticated = 0; /* we don't want to do this more than once ... */ network->auth_desynced_once = 1; - schedule_work(&mac->associnfo.work); + schedule_delayed_work(&mac->associnfo.work, 0); break; } default: @@ -427,6 +431,17 @@ ieee80211softmac_handle_assoc_response(struct net_device * dev, return 0; } +void +ieee80211softmac_try_reassoc(struct ieee80211softmac_device *mac) +{ + unsigned long flags; + + spin_lock_irqsave(&mac->lock, flags); + mac->associnfo.associating = 1; + schedule_work(&mac->associnfo.work); + spin_unlock_irqrestore(&mac->lock, flags); +} + int ieee80211softmac_handle_disassoc(struct net_device * dev, struct ieee80211_disassoc *disassoc) @@ -445,8 +460,7 @@ ieee80211softmac_handle_disassoc(struct net_device * dev, dprintk(KERN_INFO PFX "got disassoc frame\n"); ieee80211softmac_disassoc(mac); - /* try to reassociate */ - schedule_work(&mac->associnfo.work); + ieee80211softmac_try_reassoc(mac); return 0; } @@ -466,7 +480,7 @@ ieee80211softmac_handle_reassoc_req(struct net_device * dev, dprintkl(KERN_INFO PFX "reassoc request from unknown network\n"); return 0; } - schedule_work(&mac->associnfo.work); + schedule_delayed_work(&mac->associnfo.work, 0); return 0; } diff --git a/net/ieee80211/softmac/ieee80211softmac_auth.c b/net/ieee80211/softmac/ieee80211softmac_auth.c index 4cef39e171d..8ed3e59b802 100644 --- a/net/ieee80211/softmac/ieee80211softmac_auth.c +++ b/net/ieee80211/softmac/ieee80211softmac_auth.c @@ -26,7 +26,7 @@ #include "ieee80211softmac_priv.h" -static void ieee80211softmac_auth_queue(void *data); +static void ieee80211softmac_auth_queue(struct work_struct *work); /* Queues an auth request to the desired AP */ int @@ -54,14 +54,14 @@ ieee80211softmac_auth_req(struct ieee80211softmac_device *mac, auth->mac = mac; auth->retry = IEEE80211SOFTMAC_AUTH_RETRY_LIMIT; auth->state = IEEE80211SOFTMAC_AUTH_OPEN_REQUEST; - INIT_WORK(&auth->work, &ieee80211softmac_auth_queue, (void *)auth); + INIT_DELAYED_WORK(&auth->work, ieee80211softmac_auth_queue); /* Lock (for list) */ spin_lock_irqsave(&mac->lock, flags); /* add to list */ list_add_tail(&auth->list, &mac->auth_queue); - schedule_work(&auth->work); + schedule_delayed_work(&auth->work, 0); spin_unlock_irqrestore(&mac->lock, flags); return 0; @@ -70,14 +70,15 @@ ieee80211softmac_auth_req(struct ieee80211softmac_device *mac, /* Sends an auth request to the desired AP and handles timeouts */ static void -ieee80211softmac_auth_queue(void *data) +ieee80211softmac_auth_queue(struct work_struct *work) { struct ieee80211softmac_device *mac; struct ieee80211softmac_auth_queue_item *auth; struct ieee80211softmac_network *net; unsigned long flags; - auth = (struct ieee80211softmac_auth_queue_item *)data; + auth = container_of(work, struct ieee80211softmac_auth_queue_item, + work.work); net = auth->net; mac = auth->mac; @@ -118,9 +119,11 @@ ieee80211softmac_auth_queue(void *data) /* Sends a response to an auth challenge (for shared key auth). */ static void -ieee80211softmac_auth_challenge_response(void *_aq) +ieee80211softmac_auth_challenge_response(struct work_struct *work) { - struct ieee80211softmac_auth_queue_item *aq = _aq; + struct ieee80211softmac_auth_queue_item *aq = + container_of(work, struct ieee80211softmac_auth_queue_item, + work.work); /* Send our response */ ieee80211softmac_send_mgt_frame(aq->mac, aq->net, IEEE80211_STYPE_AUTH, aq->state); @@ -158,7 +161,7 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth) /* Make sure that we've got an auth queue item for this request */ if(aq == NULL) { - printkl(KERN_DEBUG PFX "Authentication response received from "MAC_FMT" but no queue item exists.\n", MAC_ARG(auth->header.addr2)); + dprintkl(KERN_DEBUG PFX "Authentication response received from "MAC_FMT" but no queue item exists.\n", MAC_ARG(auth->header.addr2)); /* Error #? */ return -1; } @@ -166,7 +169,7 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth) /* Check for out of order authentication */ if(!net->authenticating) { - printkl(KERN_DEBUG PFX "Authentication response received from "MAC_FMT" but did not request authentication.\n",MAC_ARG(auth->header.addr2)); + dprintkl(KERN_DEBUG PFX "Authentication response received from "MAC_FMT" but did not request authentication.\n",MAC_ARG(auth->header.addr2)); return -1; } @@ -216,10 +219,16 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth) net->challenge_len = *data++; if (net->challenge_len > WLAN_AUTH_CHALLENGE_LEN) net->challenge_len = WLAN_AUTH_CHALLENGE_LEN; - if (net->challenge != NULL) - kfree(net->challenge); - net->challenge = kmalloc(net->challenge_len, GFP_ATOMIC); - memcpy(net->challenge, data, net->challenge_len); + kfree(net->challenge); + net->challenge = kmemdup(data, net->challenge_len, + GFP_ATOMIC); + if (net->challenge == NULL) { + printkl(KERN_NOTICE PFX "Shared Key " + "Authentication failed due to " + "memory shortage.\n"); + spin_unlock_irqrestore(&mac->lock, flags); + break; + } aq->state = IEEE80211SOFTMAC_AUTH_SHARED_RESPONSE; /* We reuse the work struct from the auth request here. @@ -228,8 +237,8 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth) * we have obviously already sent the initial auth * request. */ cancel_delayed_work(&aq->work); - INIT_WORK(&aq->work, &ieee80211softmac_auth_challenge_response, (void *)aq); - schedule_work(&aq->work); + INIT_DELAYED_WORK(&aq->work, &ieee80211softmac_auth_challenge_response); + schedule_delayed_work(&aq->work, 0); spin_unlock_irqrestore(&mac->lock, flags); return 0; case IEEE80211SOFTMAC_AUTH_SHARED_PASS: @@ -328,6 +337,8 @@ ieee80211softmac_deauth_from_net(struct ieee80211softmac_device *mac, /* can't transmit data right now... */ netif_carrier_off(mac->dev); spin_unlock_irqrestore(&mac->lock, flags); + + ieee80211softmac_try_reassoc(mac); } /* @@ -342,7 +353,7 @@ ieee80211softmac_deauth_req(struct ieee80211softmac_device *mac, /* Make sure the network is authenticated */ if (!net->authenticated) { - printkl(KERN_DEBUG PFX "Can't send deauthentication packet, network is not authenticated.\n"); + dprintkl(KERN_DEBUG PFX "Can't send deauthentication packet, network is not authenticated.\n"); /* Error okay? */ return -EPERM; } @@ -376,7 +387,7 @@ ieee80211softmac_deauth_resp(struct net_device *dev, struct ieee80211_deauth *de net = ieee80211softmac_get_network_by_bssid(mac, deauth->header.addr2); if (net == NULL) { - printkl(KERN_DEBUG PFX "Received deauthentication packet from "MAC_FMT", but that network is unknown.\n", + dprintkl(KERN_DEBUG PFX "Received deauthentication packet from "MAC_FMT", but that network is unknown.\n", MAC_ARG(deauth->header.addr2)); return 0; } @@ -384,7 +395,7 @@ ieee80211softmac_deauth_resp(struct net_device *dev, struct ieee80211_deauth *de /* Make sure the network is authenticated */ if(!net->authenticated) { - printkl(KERN_DEBUG PFX "Can't perform deauthentication, network is not authenticated.\n"); + dprintkl(KERN_DEBUG PFX "Can't perform deauthentication, network is not authenticated.\n"); /* Error okay? */ return -EPERM; } @@ -392,6 +403,6 @@ ieee80211softmac_deauth_resp(struct net_device *dev, struct ieee80211_deauth *de ieee80211softmac_deauth_from_net(mac, net); /* let's try to re-associate */ - schedule_work(&mac->associnfo.work); + schedule_delayed_work(&mac->associnfo.work, 0); return 0; } diff --git a/net/ieee80211/softmac/ieee80211softmac_event.c b/net/ieee80211/softmac/ieee80211softmac_event.c index f34fa2ef666..b9015656cfb 100644 --- a/net/ieee80211/softmac/ieee80211softmac_event.c +++ b/net/ieee80211/softmac/ieee80211softmac_event.c @@ -73,10 +73,12 @@ static char *event_descriptions[IEEE80211SOFTMAC_EVENT_LAST+1] = { static void -ieee80211softmac_notify_callback(void *d) +ieee80211softmac_notify_callback(struct work_struct *work) { - struct ieee80211softmac_event event = *(struct ieee80211softmac_event*) d; - kfree(d); + struct ieee80211softmac_event *pevent = + container_of(work, struct ieee80211softmac_event, work.work); + struct ieee80211softmac_event event = *pevent; + kfree(pevent); event.fun(event.mac->dev, event.event_type, event.context); } @@ -99,7 +101,7 @@ ieee80211softmac_notify_internal(struct ieee80211softmac_device *mac, return -ENOMEM; eventptr->event_type = event; - INIT_WORK(&eventptr->work, ieee80211softmac_notify_callback, eventptr); + INIT_DELAYED_WORK(&eventptr->work, ieee80211softmac_notify_callback); eventptr->fun = fun; eventptr->context = context; eventptr->mac = mac; @@ -170,7 +172,7 @@ ieee80211softmac_call_events_locked(struct ieee80211softmac_device *mac, int eve /* User may have subscribed to ANY event, so * we tell them which event triggered it. */ eventptr->event_type = event; - schedule_work(&eventptr->work); + schedule_delayed_work(&eventptr->work, 0); } } } diff --git a/net/ieee80211/softmac/ieee80211softmac_module.c b/net/ieee80211/softmac/ieee80211softmac_module.c index 33aff4f4a47..256207b71dc 100644 --- a/net/ieee80211/softmac/ieee80211softmac_module.c +++ b/net/ieee80211/softmac/ieee80211softmac_module.c @@ -58,8 +58,8 @@ struct net_device *alloc_ieee80211softmac(int sizeof_priv) INIT_LIST_HEAD(&softmac->events); mutex_init(&softmac->associnfo.mutex); - INIT_WORK(&softmac->associnfo.work, ieee80211softmac_assoc_work, softmac); - INIT_WORK(&softmac->associnfo.timeout, ieee80211softmac_assoc_timeout, softmac); + INIT_DELAYED_WORK(&softmac->associnfo.work, ieee80211softmac_assoc_work); + INIT_DELAYED_WORK(&softmac->associnfo.timeout, ieee80211softmac_assoc_timeout); softmac->start_scan = ieee80211softmac_start_scan_implementation; softmac->wait_for_scan = ieee80211softmac_wait_for_scan_implementation; softmac->stop_scan = ieee80211softmac_stop_scan_implementation; diff --git a/net/ieee80211/softmac/ieee80211softmac_priv.h b/net/ieee80211/softmac/ieee80211softmac_priv.h index 0642e090b8a..4c2bba34d32 100644 --- a/net/ieee80211/softmac/ieee80211softmac_priv.h +++ b/net/ieee80211/softmac/ieee80211softmac_priv.h @@ -78,7 +78,7 @@ /* private definitions and prototypes */ /*** prototypes from _scan.c */ -void ieee80211softmac_scan(void *sm); +void ieee80211softmac_scan(struct work_struct *work); /* for internal use if scanning is needed */ int ieee80211softmac_start_scan(struct ieee80211softmac_device *mac); void ieee80211softmac_stop_scan(struct ieee80211softmac_device *mac); @@ -149,7 +149,7 @@ int ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *au int ieee80211softmac_deauth_resp(struct net_device *dev, struct ieee80211_deauth *deauth); /*** prototypes from _assoc.c */ -void ieee80211softmac_assoc_work(void *d); +void ieee80211softmac_assoc_work(struct work_struct *work); int ieee80211softmac_handle_assoc_response(struct net_device * dev, struct ieee80211_assoc_response * resp, struct ieee80211_network * network); @@ -157,7 +157,7 @@ int ieee80211softmac_handle_disassoc(struct net_device * dev, struct ieee80211_disassoc * disassoc); int ieee80211softmac_handle_reassoc_req(struct net_device * dev, struct ieee80211_reassoc_request * reassoc); -void ieee80211softmac_assoc_timeout(void *d); +void ieee80211softmac_assoc_timeout(struct work_struct *work); void ieee80211softmac_send_disassoc_req(struct ieee80211softmac_device *mac, u16 reason); void ieee80211softmac_disassoc(struct ieee80211softmac_device *mac); @@ -207,7 +207,7 @@ struct ieee80211softmac_auth_queue_item { struct ieee80211softmac_device *mac; /* SoftMAC device */ u8 retry; /* Retry limit */ u8 state; /* Auth State */ - struct work_struct work; /* Work queue */ + struct delayed_work work; /* Work queue */ }; /* scanning information */ @@ -219,7 +219,8 @@ struct ieee80211softmac_scaninfo { stop:1; u8 skip_flags; struct completion finished; - struct work_struct softmac_scan; + struct delayed_work softmac_scan; + struct ieee80211softmac_device *mac; }; /* private event struct */ @@ -227,7 +228,7 @@ struct ieee80211softmac_event { struct list_head list; int event_type; void *event_context; - struct work_struct work; + struct delayed_work work; notify_function_ptr fun; void *context; struct ieee80211softmac_device *mac; @@ -238,4 +239,6 @@ void ieee80211softmac_call_events_locked(struct ieee80211softmac_device *mac, in int ieee80211softmac_notify_internal(struct ieee80211softmac_device *mac, int event, void *event_context, notify_function_ptr fun, void *context, gfp_t gfp_mask); +void ieee80211softmac_try_reassoc(struct ieee80211softmac_device *mac); + #endif /* IEEE80211SOFTMAC_PRIV_H_ */ diff --git a/net/ieee80211/softmac/ieee80211softmac_scan.c b/net/ieee80211/softmac/ieee80211softmac_scan.c index d31cf77498c..0c85d6c24cd 100644 --- a/net/ieee80211/softmac/ieee80211softmac_scan.c +++ b/net/ieee80211/softmac/ieee80211softmac_scan.c @@ -47,7 +47,6 @@ ieee80211softmac_start_scan(struct ieee80211softmac_device *sm) sm->scanning = 1; spin_unlock_irqrestore(&sm->lock, flags); - netif_tx_disable(sm->ieee->dev); ret = sm->start_scan(sm->dev); if (ret) { spin_lock_irqsave(&sm->lock, flags); @@ -91,12 +90,14 @@ ieee80211softmac_wait_for_scan(struct ieee80211softmac_device *sm) /* internal scanning implementation follows */ -void ieee80211softmac_scan(void *d) +void ieee80211softmac_scan(struct work_struct *work) { int invalid_channel; u8 current_channel_idx; - struct ieee80211softmac_device *sm = (struct ieee80211softmac_device *)d; - struct ieee80211softmac_scaninfo *si = sm->scaninfo; + struct ieee80211softmac_scaninfo *si = + container_of(work, struct ieee80211softmac_scaninfo, + softmac_scan.work); + struct ieee80211softmac_device *sm = si->mac; unsigned long flags; while (!(si->stop) && (si->current_channel_idx < si->number_channels)) { @@ -135,7 +136,8 @@ void ieee80211softmac_scan(void *d) si->started = 0; spin_unlock_irqrestore(&sm->lock, flags); - dprintk(PFX "Scanning finished\n"); + dprintk(PFX "Scanning finished: scanned %d channels starting with channel %d\n", + sm->scaninfo->number_channels, sm->scaninfo->channels[0].channel); ieee80211softmac_scan_finished(sm); complete_all(&sm->scaninfo->finished); } @@ -146,7 +148,8 @@ static inline struct ieee80211softmac_scaninfo *allocate_scaninfo(struct ieee802 struct ieee80211softmac_scaninfo *info = kmalloc(sizeof(struct ieee80211softmac_scaninfo), GFP_ATOMIC); if (unlikely(!info)) return NULL; - INIT_WORK(&info->softmac_scan, ieee80211softmac_scan, mac); + INIT_DELAYED_WORK(&info->softmac_scan, ieee80211softmac_scan); + info->mac = mac; init_completion(&info->finished); return info; } @@ -183,13 +186,11 @@ int ieee80211softmac_start_scan_implementation(struct net_device *dev) sm->scaninfo->channels = sm->ieee->geo.bg; sm->scaninfo->number_channels = sm->ieee->geo.bg_channels; } - dprintk(PFX "Start scanning with channel: %d\n", sm->scaninfo->channels[0].channel); - dprintk(PFX "Scanning %d channels\n", sm->scaninfo->number_channels); sm->scaninfo->current_channel_idx = 0; sm->scaninfo->started = 1; sm->scaninfo->stop = 0; INIT_COMPLETION(sm->scaninfo->finished); - schedule_work(&sm->scaninfo->softmac_scan); + schedule_delayed_work(&sm->scaninfo->softmac_scan, 0); spin_unlock_irqrestore(&sm->lock, flags); return 0; } @@ -248,7 +249,6 @@ void ieee80211softmac_scan_finished(struct ieee80211softmac_device *sm) if (net) sm->set_channel(sm->dev, net->channel); } - netif_wake_queue(sm->ieee->dev); ieee80211softmac_call_events(sm, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, NULL); } EXPORT_SYMBOL_GPL(ieee80211softmac_scan_finished); diff --git a/net/ieee80211/softmac/ieee80211softmac_wx.c b/net/ieee80211/softmac/ieee80211softmac_wx.c index 23068a830f7..480d72c7a42 100644 --- a/net/ieee80211/softmac/ieee80211softmac_wx.c +++ b/net/ieee80211/softmac/ieee80211softmac_wx.c @@ -122,7 +122,7 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev, sm->associnfo.associating = 1; /* queue lower level code to do work (if necessary) */ - schedule_work(&sm->associnfo.work); + schedule_delayed_work(&sm->associnfo.work, 0); out: mutex_unlock(&sm->associnfo.mutex); @@ -356,7 +356,7 @@ ieee80211softmac_wx_set_wap(struct net_device *net_dev, /* force reassociation */ mac->associnfo.bssvalid = 0; if (mac->associnfo.associated) - schedule_work(&mac->associnfo.work); + schedule_delayed_work(&mac->associnfo.work, 0); } else if (is_zero_ether_addr(data->ap_addr.sa_data)) { /* the bssid we have is no longer fixed */ mac->associnfo.bssfixed = 0; @@ -373,7 +373,7 @@ ieee80211softmac_wx_set_wap(struct net_device *net_dev, /* tell the other code that this bssid should be used no matter what */ mac->associnfo.bssfixed = 1; /* queue associate if new bssid or (old one again and not associated) */ - schedule_work(&mac->associnfo.work); + schedule_delayed_work(&mac->associnfo.work, 0); } out: @@ -495,7 +495,8 @@ ieee80211softmac_wx_set_mlme(struct net_device *dev, printk(KERN_DEBUG PFX "wx_set_mlme: we should know the net here...\n"); goto out; } - return ieee80211softmac_deauth_req(mac, net, reason); + err = ieee80211softmac_deauth_req(mac, net, reason); + goto out; case IW_MLME_DISASSOC: ieee80211softmac_send_disassoc_req(mac, reason); mac->associnfo.associated = 0; |