diff options
-rw-r--r-- | MAINTAINERS | 10 | ||||
-rw-r--r-- | drivers/net/wireless/hostap/hostap_cs.c | 15 | ||||
-rw-r--r-- | drivers/net/wireless/hostap/hostap_hw.c | 13 | ||||
-rw-r--r-- | drivers/net/wireless/hostap/hostap_wlan.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 7 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-scan.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-sta.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl3945-base.c | 9 | ||||
-rw-r--r-- | drivers/net/wireless/libertas_tf/main.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/p54/p54pci.c | 2 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 39 | ||||
-rw-r--r-- | net/mac80211/work.c | 2 |
13 files changed, 96 insertions, 18 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 83be538d26c4..837a7547786b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -2966,20 +2966,14 @@ F: drivers/net/ixgb/ | |||
2966 | F: drivers/net/ixgbe/ | 2966 | F: drivers/net/ixgbe/ |
2967 | 2967 | ||
2968 | INTEL PRO/WIRELESS 2100 NETWORK CONNECTION SUPPORT | 2968 | INTEL PRO/WIRELESS 2100 NETWORK CONNECTION SUPPORT |
2969 | M: Reinette Chatre <reinette.chatre@intel.com> | ||
2970 | M: Intel Linux Wireless <ilw@linux.intel.com> | ||
2971 | L: linux-wireless@vger.kernel.org | 2969 | L: linux-wireless@vger.kernel.org |
2972 | W: http://ipw2100.sourceforge.net | 2970 | S: Orphan |
2973 | S: Odd Fixes | ||
2974 | F: Documentation/networking/README.ipw2100 | 2971 | F: Documentation/networking/README.ipw2100 |
2975 | F: drivers/net/wireless/ipw2x00/ipw2100.* | 2972 | F: drivers/net/wireless/ipw2x00/ipw2100.* |
2976 | 2973 | ||
2977 | INTEL PRO/WIRELESS 2915ABG NETWORK CONNECTION SUPPORT | 2974 | INTEL PRO/WIRELESS 2915ABG NETWORK CONNECTION SUPPORT |
2978 | M: Reinette Chatre <reinette.chatre@intel.com> | ||
2979 | M: Intel Linux Wireless <ilw@linux.intel.com> | ||
2980 | L: linux-wireless@vger.kernel.org | 2975 | L: linux-wireless@vger.kernel.org |
2981 | W: http://ipw2200.sourceforge.net | 2976 | S: Orphan |
2982 | S: Odd Fixes | ||
2983 | F: Documentation/networking/README.ipw2200 | 2977 | F: Documentation/networking/README.ipw2200 |
2984 | F: drivers/net/wireless/ipw2x00/ipw2200.* | 2978 | F: drivers/net/wireless/ipw2x00/ipw2200.* |
2985 | 2979 | ||
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index db72461c486b..29b31a694b59 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c | |||
@@ -594,6 +594,7 @@ static int prism2_config(struct pcmcia_device *link) | |||
594 | local_info_t *local; | 594 | local_info_t *local; |
595 | int ret = 1; | 595 | int ret = 1; |
596 | struct hostap_cs_priv *hw_priv; | 596 | struct hostap_cs_priv *hw_priv; |
597 | unsigned long flags; | ||
597 | 598 | ||
598 | PDEBUG(DEBUG_FLOW, "prism2_config()\n"); | 599 | PDEBUG(DEBUG_FLOW, "prism2_config()\n"); |
599 | 600 | ||
@@ -625,9 +626,15 @@ static int prism2_config(struct pcmcia_device *link) | |||
625 | local->hw_priv = hw_priv; | 626 | local->hw_priv = hw_priv; |
626 | hw_priv->link = link; | 627 | hw_priv->link = link; |
627 | 628 | ||
629 | /* | ||
630 | * Make sure the IRQ handler cannot proceed until at least | ||
631 | * dev->base_addr is initialized. | ||
632 | */ | ||
633 | spin_lock_irqsave(&local->irq_init_lock, flags); | ||
634 | |||
628 | ret = pcmcia_request_irq(link, prism2_interrupt); | 635 | ret = pcmcia_request_irq(link, prism2_interrupt); |
629 | if (ret) | 636 | if (ret) |
630 | goto failed; | 637 | goto failed_unlock; |
631 | 638 | ||
632 | /* | 639 | /* |
633 | * This actually configures the PCMCIA socket -- setting up | 640 | * This actually configures the PCMCIA socket -- setting up |
@@ -636,11 +643,13 @@ static int prism2_config(struct pcmcia_device *link) | |||
636 | */ | 643 | */ |
637 | ret = pcmcia_request_configuration(link, &link->conf); | 644 | ret = pcmcia_request_configuration(link, &link->conf); |
638 | if (ret) | 645 | if (ret) |
639 | goto failed; | 646 | goto failed_unlock; |
640 | 647 | ||
641 | dev->irq = link->irq; | 648 | dev->irq = link->irq; |
642 | dev->base_addr = link->io.BasePort1; | 649 | dev->base_addr = link->io.BasePort1; |
643 | 650 | ||
651 | spin_unlock_irqrestore(&local->irq_init_lock, flags); | ||
652 | |||
644 | /* Finally, report what we've done */ | 653 | /* Finally, report what we've done */ |
645 | printk(KERN_INFO "%s: index 0x%02x: ", | 654 | printk(KERN_INFO "%s: index 0x%02x: ", |
646 | dev_info, link->conf.ConfigIndex); | 655 | dev_info, link->conf.ConfigIndex); |
@@ -667,6 +676,8 @@ static int prism2_config(struct pcmcia_device *link) | |||
667 | 676 | ||
668 | return ret; | 677 | return ret; |
669 | 678 | ||
679 | failed_unlock: | ||
680 | spin_unlock_irqrestore(&local->irq_init_lock, flags); | ||
670 | failed: | 681 | failed: |
671 | kfree(hw_priv); | 682 | kfree(hw_priv); |
672 | prism2_release((u_long)link); | 683 | prism2_release((u_long)link); |
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c index ff9b5c882184..2f999fc94f60 100644 --- a/drivers/net/wireless/hostap/hostap_hw.c +++ b/drivers/net/wireless/hostap/hostap_hw.c | |||
@@ -2621,6 +2621,18 @@ static irqreturn_t prism2_interrupt(int irq, void *dev_id) | |||
2621 | iface = netdev_priv(dev); | 2621 | iface = netdev_priv(dev); |
2622 | local = iface->local; | 2622 | local = iface->local; |
2623 | 2623 | ||
2624 | /* Detect early interrupt before driver is fully configued */ | ||
2625 | spin_lock(&local->irq_init_lock); | ||
2626 | if (!dev->base_addr) { | ||
2627 | if (net_ratelimit()) { | ||
2628 | printk(KERN_DEBUG "%s: Interrupt, but dev not configured\n", | ||
2629 | dev->name); | ||
2630 | } | ||
2631 | spin_unlock(&local->irq_init_lock); | ||
2632 | return IRQ_HANDLED; | ||
2633 | } | ||
2634 | spin_unlock(&local->irq_init_lock); | ||
2635 | |||
2624 | prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INTERRUPT, 0, 0); | 2636 | prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INTERRUPT, 0, 0); |
2625 | 2637 | ||
2626 | if (local->func->card_present && !local->func->card_present(local)) { | 2638 | if (local->func->card_present && !local->func->card_present(local)) { |
@@ -3138,6 +3150,7 @@ prism2_init_local_data(struct prism2_helper_functions *funcs, int card_idx, | |||
3138 | spin_lock_init(&local->cmdlock); | 3150 | spin_lock_init(&local->cmdlock); |
3139 | spin_lock_init(&local->baplock); | 3151 | spin_lock_init(&local->baplock); |
3140 | spin_lock_init(&local->lock); | 3152 | spin_lock_init(&local->lock); |
3153 | spin_lock_init(&local->irq_init_lock); | ||
3141 | mutex_init(&local->rid_bap_mtx); | 3154 | mutex_init(&local->rid_bap_mtx); |
3142 | 3155 | ||
3143 | if (card_idx < 0 || card_idx >= MAX_PARM_DEVICES) | 3156 | if (card_idx < 0 || card_idx >= MAX_PARM_DEVICES) |
diff --git a/drivers/net/wireless/hostap/hostap_wlan.h b/drivers/net/wireless/hostap/hostap_wlan.h index 3d238917af07..1ba33be98b25 100644 --- a/drivers/net/wireless/hostap/hostap_wlan.h +++ b/drivers/net/wireless/hostap/hostap_wlan.h | |||
@@ -654,7 +654,7 @@ struct local_info { | |||
654 | rwlock_t iface_lock; /* hostap_interfaces read lock; use write lock | 654 | rwlock_t iface_lock; /* hostap_interfaces read lock; use write lock |
655 | * when removing entries from the list. | 655 | * when removing entries from the list. |
656 | * TX and RX paths can use read lock. */ | 656 | * TX and RX paths can use read lock. */ |
657 | spinlock_t cmdlock, baplock, lock; | 657 | spinlock_t cmdlock, baplock, lock, irq_init_lock; |
658 | struct mutex rid_bap_mtx; | 658 | struct mutex rid_bap_mtx; |
659 | u16 infofid; /* MAC buffer id for info frame */ | 659 | u16 infofid; /* MAC buffer id for info frame */ |
660 | /* txfid, intransmitfid, next_txtid, and next_alloc are protected by | 660 | /* txfid, intransmitfid, next_txtid, and next_alloc are protected by |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 10a0acdb9dd4..84df7fca750d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c | |||
@@ -1147,6 +1147,7 @@ static void iwlagn_tx_status(struct iwl_priv *priv, struct sk_buff *skb) | |||
1147 | struct ieee80211_sta *sta; | 1147 | struct ieee80211_sta *sta; |
1148 | struct iwl_station_priv *sta_priv; | 1148 | struct iwl_station_priv *sta_priv; |
1149 | 1149 | ||
1150 | rcu_read_lock(); | ||
1150 | sta = ieee80211_find_sta(priv->vif, hdr->addr1); | 1151 | sta = ieee80211_find_sta(priv->vif, hdr->addr1); |
1151 | if (sta) { | 1152 | if (sta) { |
1152 | sta_priv = (void *)sta->drv_priv; | 1153 | sta_priv = (void *)sta->drv_priv; |
@@ -1155,6 +1156,7 @@ static void iwlagn_tx_status(struct iwl_priv *priv, struct sk_buff *skb) | |||
1155 | atomic_dec_return(&sta_priv->pending_frames) == 0) | 1156 | atomic_dec_return(&sta_priv->pending_frames) == 0) |
1156 | ieee80211_sta_block_awake(priv->hw, sta, false); | 1157 | ieee80211_sta_block_awake(priv->hw, sta, false); |
1157 | } | 1158 | } |
1159 | rcu_read_unlock(); | ||
1158 | 1160 | ||
1159 | ieee80211_tx_status_irqsafe(priv->hw, skb); | 1161 | ieee80211_tx_status_irqsafe(priv->hw, skb); |
1160 | } | 1162 | } |
@@ -1322,6 +1324,11 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
1322 | sta_id = ba_resp->sta_id; | 1324 | sta_id = ba_resp->sta_id; |
1323 | tid = ba_resp->tid; | 1325 | tid = ba_resp->tid; |
1324 | agg = &priv->stations[sta_id].tid[tid].agg; | 1326 | agg = &priv->stations[sta_id].tid[tid].agg; |
1327 | if (unlikely(agg->txq_id != scd_flow)) { | ||
1328 | IWL_ERR(priv, "BA scd_flow %d does not match txq_id %d\n", | ||
1329 | scd_flow, agg->txq_id); | ||
1330 | return; | ||
1331 | } | ||
1325 | 1332 | ||
1326 | /* Find index just before block-ack window */ | 1333 | /* Find index just before block-ack window */ |
1327 | index = iwl_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd); | 1334 | index = iwl_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 4ade9a68278a..d857f8496f69 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -3465,10 +3465,12 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw, | |||
3465 | int ret; | 3465 | int ret; |
3466 | u8 sta_id; | 3466 | u8 sta_id; |
3467 | 3467 | ||
3468 | sta_priv->common.sta_id = IWL_INVALID_STATION; | ||
3469 | |||
3470 | IWL_DEBUG_INFO(priv, "received request to add station %pM\n", | 3468 | IWL_DEBUG_INFO(priv, "received request to add station %pM\n", |
3471 | sta->addr); | 3469 | sta->addr); |
3470 | mutex_lock(&priv->mutex); | ||
3471 | IWL_DEBUG_INFO(priv, "proceeding to add station %pM\n", | ||
3472 | sta->addr); | ||
3473 | sta_priv->common.sta_id = IWL_INVALID_STATION; | ||
3472 | 3474 | ||
3473 | atomic_set(&sta_priv->pending_frames, 0); | 3475 | atomic_set(&sta_priv->pending_frames, 0); |
3474 | if (vif->type == NL80211_IFTYPE_AP) | 3476 | if (vif->type == NL80211_IFTYPE_AP) |
@@ -3480,6 +3482,7 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw, | |||
3480 | IWL_ERR(priv, "Unable to add station %pM (%d)\n", | 3482 | IWL_ERR(priv, "Unable to add station %pM (%d)\n", |
3481 | sta->addr, ret); | 3483 | sta->addr, ret); |
3482 | /* Should we return success if return code is EEXIST ? */ | 3484 | /* Should we return success if return code is EEXIST ? */ |
3485 | mutex_unlock(&priv->mutex); | ||
3483 | return ret; | 3486 | return ret; |
3484 | } | 3487 | } |
3485 | 3488 | ||
@@ -3489,6 +3492,7 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw, | |||
3489 | IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n", | 3492 | IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n", |
3490 | sta->addr); | 3493 | sta->addr); |
3491 | iwl_rs_rate_init(priv, sta, sta_id); | 3494 | iwl_rs_rate_init(priv, sta, sta_id); |
3495 | mutex_unlock(&priv->mutex); | ||
3492 | 3496 | ||
3493 | return 0; | 3497 | return 0; |
3494 | } | 3498 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index b8bcd48eb8fa..798f93e0ff50 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c | |||
@@ -500,6 +500,7 @@ void iwl_bg_abort_scan(struct work_struct *work) | |||
500 | 500 | ||
501 | mutex_lock(&priv->mutex); | 501 | mutex_lock(&priv->mutex); |
502 | 502 | ||
503 | cancel_delayed_work_sync(&priv->scan_check); | ||
503 | set_bit(STATUS_SCAN_ABORTING, &priv->status); | 504 | set_bit(STATUS_SCAN_ABORTING, &priv->status); |
504 | iwl_send_scan_abort(priv); | 505 | iwl_send_scan_abort(priv); |
505 | 506 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index c7127132c298..d57df6c02db3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c | |||
@@ -1373,10 +1373,14 @@ int iwl_mac_sta_remove(struct ieee80211_hw *hw, | |||
1373 | 1373 | ||
1374 | IWL_DEBUG_INFO(priv, "received request to remove station %pM\n", | 1374 | IWL_DEBUG_INFO(priv, "received request to remove station %pM\n", |
1375 | sta->addr); | 1375 | sta->addr); |
1376 | mutex_lock(&priv->mutex); | ||
1377 | IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n", | ||
1378 | sta->addr); | ||
1376 | ret = iwl_remove_station(priv, sta_common->sta_id, sta->addr); | 1379 | ret = iwl_remove_station(priv, sta_common->sta_id, sta->addr); |
1377 | if (ret) | 1380 | if (ret) |
1378 | IWL_ERR(priv, "Error removing station %pM\n", | 1381 | IWL_ERR(priv, "Error removing station %pM\n", |
1379 | sta->addr); | 1382 | sta->addr); |
1383 | mutex_unlock(&priv->mutex); | ||
1380 | return ret; | 1384 | return ret; |
1381 | } | 1385 | } |
1382 | EXPORT_SYMBOL(iwl_mac_sta_remove); | 1386 | EXPORT_SYMBOL(iwl_mac_sta_remove); |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index eb71a8c021ac..697fa6caaceb 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -3363,10 +3363,13 @@ static int iwl3945_mac_sta_add(struct ieee80211_hw *hw, | |||
3363 | bool is_ap = vif->type == NL80211_IFTYPE_STATION; | 3363 | bool is_ap = vif->type == NL80211_IFTYPE_STATION; |
3364 | u8 sta_id; | 3364 | u8 sta_id; |
3365 | 3365 | ||
3366 | sta_priv->common.sta_id = IWL_INVALID_STATION; | ||
3367 | |||
3368 | IWL_DEBUG_INFO(priv, "received request to add station %pM\n", | 3366 | IWL_DEBUG_INFO(priv, "received request to add station %pM\n", |
3369 | sta->addr); | 3367 | sta->addr); |
3368 | mutex_lock(&priv->mutex); | ||
3369 | IWL_DEBUG_INFO(priv, "proceeding to add station %pM\n", | ||
3370 | sta->addr); | ||
3371 | sta_priv->common.sta_id = IWL_INVALID_STATION; | ||
3372 | |||
3370 | 3373 | ||
3371 | ret = iwl_add_station_common(priv, sta->addr, is_ap, &sta->ht_cap, | 3374 | ret = iwl_add_station_common(priv, sta->addr, is_ap, &sta->ht_cap, |
3372 | &sta_id); | 3375 | &sta_id); |
@@ -3374,6 +3377,7 @@ static int iwl3945_mac_sta_add(struct ieee80211_hw *hw, | |||
3374 | IWL_ERR(priv, "Unable to add station %pM (%d)\n", | 3377 | IWL_ERR(priv, "Unable to add station %pM (%d)\n", |
3375 | sta->addr, ret); | 3378 | sta->addr, ret); |
3376 | /* Should we return success if return code is EEXIST ? */ | 3379 | /* Should we return success if return code is EEXIST ? */ |
3380 | mutex_unlock(&priv->mutex); | ||
3377 | return ret; | 3381 | return ret; |
3378 | } | 3382 | } |
3379 | 3383 | ||
@@ -3383,6 +3387,7 @@ static int iwl3945_mac_sta_add(struct ieee80211_hw *hw, | |||
3383 | IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n", | 3387 | IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n", |
3384 | sta->addr); | 3388 | sta->addr); |
3385 | iwl3945_rs_rate_init(priv, sta, sta_id); | 3389 | iwl3945_rs_rate_init(priv, sta, sta_id); |
3390 | mutex_unlock(&priv->mutex); | ||
3386 | 3391 | ||
3387 | return 0; | 3392 | return 0; |
3388 | } | 3393 | } |
diff --git a/drivers/net/wireless/libertas_tf/main.c b/drivers/net/wireless/libertas_tf/main.c index 6a04c2157f73..817fffc0de4b 100644 --- a/drivers/net/wireless/libertas_tf/main.c +++ b/drivers/net/wireless/libertas_tf/main.c | |||
@@ -549,7 +549,7 @@ int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb) | |||
549 | 549 | ||
550 | prxpd = (struct rxpd *) skb->data; | 550 | prxpd = (struct rxpd *) skb->data; |
551 | 551 | ||
552 | stats.flag = 0; | 552 | memset(&stats, 0, sizeof(stats)); |
553 | if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK))) | 553 | if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK))) |
554 | stats.flag |= RX_FLAG_FAILED_FCS_CRC; | 554 | stats.flag |= RX_FLAG_FAILED_FCS_CRC; |
555 | stats.freq = priv->cur_freq; | 555 | stats.freq = priv->cur_freq; |
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c index 07c4528f6e6b..a5ea89cde8c4 100644 --- a/drivers/net/wireless/p54/p54pci.c +++ b/drivers/net/wireless/p54/p54pci.c | |||
@@ -41,6 +41,8 @@ static DEFINE_PCI_DEVICE_TABLE(p54p_table) = { | |||
41 | { PCI_DEVICE(0x1260, 0x3877) }, | 41 | { PCI_DEVICE(0x1260, 0x3877) }, |
42 | /* Intersil PRISM Javelin/Xbow Wireless LAN adapter */ | 42 | /* Intersil PRISM Javelin/Xbow Wireless LAN adapter */ |
43 | { PCI_DEVICE(0x1260, 0x3886) }, | 43 | { PCI_DEVICE(0x1260, 0x3886) }, |
44 | /* Intersil PRISM Xbow Wireless LAN adapter (Symbol AP-300) */ | ||
45 | { PCI_DEVICE(0x1260, 0xffff) }, | ||
44 | { }, | 46 | { }, |
45 | }; | 47 | }; |
46 | 48 | ||
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 637b22411d41..85c3ca33333e 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -1704,8 +1704,45 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | |||
1704 | mutex_unlock(&ifmgd->mtx); | 1704 | mutex_unlock(&ifmgd->mtx); |
1705 | 1705 | ||
1706 | if (skb->len >= 24 + 2 /* mgmt + deauth reason */ && | 1706 | if (skb->len >= 24 + 2 /* mgmt + deauth reason */ && |
1707 | (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_DEAUTH) | 1707 | (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_DEAUTH) { |
1708 | struct ieee80211_local *local = sdata->local; | ||
1709 | struct ieee80211_work *wk; | ||
1710 | |||
1711 | mutex_lock(&local->work_mtx); | ||
1712 | list_for_each_entry(wk, &local->work_list, list) { | ||
1713 | if (wk->sdata != sdata) | ||
1714 | continue; | ||
1715 | |||
1716 | if (wk->type != IEEE80211_WORK_ASSOC) | ||
1717 | continue; | ||
1718 | |||
1719 | if (memcmp(mgmt->bssid, wk->filter_ta, ETH_ALEN)) | ||
1720 | continue; | ||
1721 | if (memcmp(mgmt->sa, wk->filter_ta, ETH_ALEN)) | ||
1722 | continue; | ||
1723 | |||
1724 | /* | ||
1725 | * Printing the message only here means we can't | ||
1726 | * spuriously print it, but it also means that it | ||
1727 | * won't be printed when the frame comes in before | ||
1728 | * we even tried to associate or in similar cases. | ||
1729 | * | ||
1730 | * Ultimately, I suspect cfg80211 should print the | ||
1731 | * messages instead. | ||
1732 | */ | ||
1733 | printk(KERN_DEBUG | ||
1734 | "%s: deauthenticated from %pM (Reason: %u)\n", | ||
1735 | sdata->name, mgmt->bssid, | ||
1736 | le16_to_cpu(mgmt->u.deauth.reason_code)); | ||
1737 | |||
1738 | list_del_rcu(&wk->list); | ||
1739 | free_work(wk); | ||
1740 | break; | ||
1741 | } | ||
1742 | mutex_unlock(&local->work_mtx); | ||
1743 | |||
1708 | cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len); | 1744 | cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len); |
1745 | } | ||
1709 | } | 1746 | } |
1710 | 1747 | ||
1711 | static void ieee80211_sta_timer(unsigned long data) | 1748 | static void ieee80211_sta_timer(unsigned long data) |
diff --git a/net/mac80211/work.c b/net/mac80211/work.c index 4157717ed786..c22a71c5cb45 100644 --- a/net/mac80211/work.c +++ b/net/mac80211/work.c | |||
@@ -715,7 +715,7 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local, | |||
715 | struct ieee80211_rx_status *rx_status; | 715 | struct ieee80211_rx_status *rx_status; |
716 | struct ieee80211_mgmt *mgmt; | 716 | struct ieee80211_mgmt *mgmt; |
717 | struct ieee80211_work *wk; | 717 | struct ieee80211_work *wk; |
718 | enum work_action rma; | 718 | enum work_action rma = WORK_ACT_NONE; |
719 | u16 fc; | 719 | u16 fc; |
720 | 720 | ||
721 | rx_status = (struct ieee80211_rx_status *) skb->cb; | 721 | rx_status = (struct ieee80211_rx_status *) skb->cb; |