aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c284
1 files changed, 116 insertions, 168 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index f803f8b72a93..b6c163ac22da 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -478,6 +478,39 @@ static void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
478 } 478 }
479} 479}
480 480
481void ieee80211_enable_dyn_ps(struct ieee80211_vif *vif)
482{
483 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
484 struct ieee80211_local *local = sdata->local;
485 struct ieee80211_conf *conf = &local->hw.conf;
486
487 WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION ||
488 !(local->hw.flags & IEEE80211_HW_SUPPORTS_PS) ||
489 (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS));
490
491 local->disable_dynamic_ps = false;
492 conf->dynamic_ps_timeout = local->dynamic_ps_user_timeout;
493}
494EXPORT_SYMBOL(ieee80211_enable_dyn_ps);
495
496void ieee80211_disable_dyn_ps(struct ieee80211_vif *vif)
497{
498 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
499 struct ieee80211_local *local = sdata->local;
500 struct ieee80211_conf *conf = &local->hw.conf;
501
502 WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION ||
503 !(local->hw.flags & IEEE80211_HW_SUPPORTS_PS) ||
504 (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS));
505
506 local->disable_dynamic_ps = true;
507 conf->dynamic_ps_timeout = 0;
508 del_timer_sync(&local->dynamic_ps_timer);
509 ieee80211_queue_work(&local->hw,
510 &local->dynamic_ps_enable_work);
511}
512EXPORT_SYMBOL(ieee80211_disable_dyn_ps);
513
481/* powersave */ 514/* powersave */
482static void ieee80211_enable_ps(struct ieee80211_local *local, 515static void ieee80211_enable_ps(struct ieee80211_local *local,
483 struct ieee80211_sub_if_data *sdata) 516 struct ieee80211_sub_if_data *sdata)
@@ -553,6 +586,7 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
553 found->u.mgd.associated->beacon_ies && 586 found->u.mgd.associated->beacon_ies &&
554 !(found->u.mgd.flags & (IEEE80211_STA_BEACON_POLL | 587 !(found->u.mgd.flags & (IEEE80211_STA_BEACON_POLL |
555 IEEE80211_STA_CONNECTION_POLL))) { 588 IEEE80211_STA_CONNECTION_POLL))) {
589 struct ieee80211_conf *conf = &local->hw.conf;
556 s32 beaconint_us; 590 s32 beaconint_us;
557 591
558 if (latency < 0) 592 if (latency < 0)
@@ -561,25 +595,24 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
561 beaconint_us = ieee80211_tu_to_usec( 595 beaconint_us = ieee80211_tu_to_usec(
562 found->vif.bss_conf.beacon_int); 596 found->vif.bss_conf.beacon_int);
563 597
564 timeout = local->hw.conf.dynamic_ps_forced_timeout; 598 timeout = local->dynamic_ps_forced_timeout;
565 if (timeout < 0) { 599 if (timeout < 0) {
566 /* 600 /*
601 * Go to full PSM if the user configures a very low
602 * latency requirement.
567 * The 2 second value is there for compatibility until 603 * The 2 second value is there for compatibility until
568 * the PM_QOS_NETWORK_LATENCY is configured with real 604 * the PM_QOS_NETWORK_LATENCY is configured with real
569 * values. 605 * values.
570 */ 606 */
571 if (latency == 2000000000) 607 if (latency > 1900000000 && latency != 2000000000)
572 timeout = 100;
573 else if (latency <= 50000)
574 timeout = 300;
575 else if (latency <= 100000)
576 timeout = 100;
577 else if (latency <= 500000)
578 timeout = 50;
579 else
580 timeout = 0; 608 timeout = 0;
609 else
610 timeout = 100;
581 } 611 }
582 local->hw.conf.dynamic_ps_timeout = timeout; 612 local->dynamic_ps_user_timeout = timeout;
613 if (!local->disable_dynamic_ps)
614 conf->dynamic_ps_timeout =
615 local->dynamic_ps_user_timeout;
583 616
584 if (beaconint_us > latency) { 617 if (beaconint_us > latency) {
585 local->ps_sdata = NULL; 618 local->ps_sdata = NULL;
@@ -665,10 +698,11 @@ void ieee80211_dynamic_ps_timer(unsigned long data)
665 698
666/* MLME */ 699/* MLME */
667static void ieee80211_sta_wmm_params(struct ieee80211_local *local, 700static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
668 struct ieee80211_if_managed *ifmgd, 701 struct ieee80211_sub_if_data *sdata,
669 u8 *wmm_param, size_t wmm_param_len) 702 u8 *wmm_param, size_t wmm_param_len)
670{ 703{
671 struct ieee80211_tx_queue_params params; 704 struct ieee80211_tx_queue_params params;
705 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
672 size_t left; 706 size_t left;
673 int count; 707 int count;
674 u8 *pos, uapsd_queues = 0; 708 u8 *pos, uapsd_queues = 0;
@@ -757,8 +791,8 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
757 } 791 }
758 792
759 /* enable WMM or activate new settings */ 793 /* enable WMM or activate new settings */
760 local->hw.conf.flags |= IEEE80211_CONF_QOS; 794 sdata->vif.bss_conf.qos = true;
761 drv_config(local, IEEE80211_CONF_CHANGE_QOS); 795 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_QOS);
762} 796}
763 797
764static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata, 798static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
@@ -806,11 +840,12 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
806{ 840{
807 struct ieee80211_bss *bss = (void *)cbss->priv; 841 struct ieee80211_bss *bss = (void *)cbss->priv;
808 struct ieee80211_local *local = sdata->local; 842 struct ieee80211_local *local = sdata->local;
843 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
809 844
810 bss_info_changed |= BSS_CHANGED_ASSOC; 845 bss_info_changed |= BSS_CHANGED_ASSOC;
811 /* set timing information */ 846 /* set timing information */
812 sdata->vif.bss_conf.beacon_int = cbss->beacon_interval; 847 bss_conf->beacon_int = cbss->beacon_interval;
813 sdata->vif.bss_conf.timestamp = cbss->tsf; 848 bss_conf->timestamp = cbss->tsf;
814 849
815 bss_info_changed |= BSS_CHANGED_BEACON_INT; 850 bss_info_changed |= BSS_CHANGED_BEACON_INT;
816 bss_info_changed |= ieee80211_handle_bss_capability(sdata, 851 bss_info_changed |= ieee80211_handle_bss_capability(sdata,
@@ -835,7 +870,12 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
835 870
836 ieee80211_led_assoc(local, 1); 871 ieee80211_led_assoc(local, 1);
837 872
838 sdata->vif.bss_conf.assoc = 1; 873 if (local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD)
874 bss_conf->dtim_period = bss->dtim_period;
875 else
876 bss_conf->dtim_period = 0;
877
878 bss_conf->assoc = 1;
839 /* 879 /*
840 * For now just always ask the driver to update the basic rateset 880 * For now just always ask the driver to update the basic rateset
841 * when we have associated, we aren't checking whether it actually 881 * when we have associated, we aren't checking whether it actually
@@ -848,9 +888,15 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
848 888
849 /* Tell the driver to monitor connection quality (if supported) */ 889 /* Tell the driver to monitor connection quality (if supported) */
850 if ((local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI) && 890 if ((local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI) &&
851 sdata->vif.bss_conf.cqm_rssi_thold) 891 bss_conf->cqm_rssi_thold)
852 bss_info_changed |= BSS_CHANGED_CQM; 892 bss_info_changed |= BSS_CHANGED_CQM;
853 893
894 /* Enable ARP filtering */
895 if (bss_conf->arp_filter_enabled != sdata->arp_filter_state) {
896 bss_conf->arp_filter_enabled = sdata->arp_filter_state;
897 bss_info_changed |= BSS_CHANGED_ARP_FILTER;
898 }
899
854 ieee80211_bss_info_change_notify(sdata, bss_info_changed); 900 ieee80211_bss_info_change_notify(sdata, bss_info_changed);
855 901
856 mutex_lock(&local->iflist_mtx); 902 mutex_lock(&local->iflist_mtx);
@@ -898,13 +944,13 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
898 netif_tx_stop_all_queues(sdata->dev); 944 netif_tx_stop_all_queues(sdata->dev);
899 netif_carrier_off(sdata->dev); 945 netif_carrier_off(sdata->dev);
900 946
901 rcu_read_lock(); 947 mutex_lock(&local->sta_mtx);
902 sta = sta_info_get(sdata, bssid); 948 sta = sta_info_get(sdata, bssid);
903 if (sta) { 949 if (sta) {
904 set_sta_flags(sta, WLAN_STA_DISASSOC); 950 set_sta_flags(sta, WLAN_STA_BLOCK_BA);
905 ieee80211_sta_tear_down_BA_sessions(sta); 951 ieee80211_sta_tear_down_BA_sessions(sta);
906 } 952 }
907 rcu_read_unlock(); 953 mutex_unlock(&local->sta_mtx);
908 954
909 changed |= ieee80211_reset_erp_info(sdata); 955 changed |= ieee80211_reset_erp_info(sdata);
910 956
@@ -932,6 +978,12 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
932 978
933 ieee80211_hw_config(local, config_changed); 979 ieee80211_hw_config(local, config_changed);
934 980
981 /* Disable ARP filtering */
982 if (sdata->vif.bss_conf.arp_filter_enabled) {
983 sdata->vif.bss_conf.arp_filter_enabled = false;
984 changed |= BSS_CHANGED_ARP_FILTER;
985 }
986
935 /* The BSSID (not really interesting) and HT changed */ 987 /* The BSSID (not really interesting) and HT changed */
936 changed |= BSS_CHANGED_BSSID | BSS_CHANGED_HT; 988 changed |= BSS_CHANGED_BSSID | BSS_CHANGED_HT;
937 ieee80211_bss_info_change_notify(sdata, changed); 989 ieee80211_bss_info_change_notify(sdata, changed);
@@ -1279,7 +1331,7 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
1279 } 1331 }
1280 1332
1281 if (elems.wmm_param) 1333 if (elems.wmm_param)
1282 ieee80211_sta_wmm_params(local, ifmgd, elems.wmm_param, 1334 ieee80211_sta_wmm_params(local, sdata, elems.wmm_param,
1283 elems.wmm_param_len); 1335 elems.wmm_param_len);
1284 else 1336 else
1285 ieee80211_set_wmm_default(sdata); 1337 ieee80211_set_wmm_default(sdata);
@@ -1551,7 +1603,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1551 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, 1603 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems,
1552 true); 1604 true);
1553 1605
1554 ieee80211_sta_wmm_params(local, ifmgd, elems.wmm_param, 1606 ieee80211_sta_wmm_params(local, sdata, elems.wmm_param,
1555 elems.wmm_param_len); 1607 elems.wmm_param_len);
1556 } 1608 }
1557 1609
@@ -1633,35 +1685,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1633 ieee80211_bss_info_change_notify(sdata, changed); 1685 ieee80211_bss_info_change_notify(sdata, changed);
1634} 1686}
1635 1687
1636ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata, 1688void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
1637 struct sk_buff *skb) 1689 struct sk_buff *skb)
1638{
1639 struct ieee80211_local *local = sdata->local;
1640 struct ieee80211_mgmt *mgmt;
1641 u16 fc;
1642
1643 if (skb->len < 24)
1644 return RX_DROP_MONITOR;
1645
1646 mgmt = (struct ieee80211_mgmt *) skb->data;
1647 fc = le16_to_cpu(mgmt->frame_control);
1648
1649 switch (fc & IEEE80211_FCTL_STYPE) {
1650 case IEEE80211_STYPE_PROBE_RESP:
1651 case IEEE80211_STYPE_BEACON:
1652 case IEEE80211_STYPE_DEAUTH:
1653 case IEEE80211_STYPE_DISASSOC:
1654 case IEEE80211_STYPE_ACTION:
1655 skb_queue_tail(&sdata->u.mgd.skb_queue, skb);
1656 ieee80211_queue_work(&local->hw, &sdata->u.mgd.work);
1657 return RX_QUEUED;
1658 }
1659
1660 return RX_DROP_MONITOR;
1661}
1662
1663static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
1664 struct sk_buff *skb)
1665{ 1690{
1666 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1691 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1667 struct ieee80211_rx_status *rx_status; 1692 struct ieee80211_rx_status *rx_status;
@@ -1693,44 +1718,6 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
1693 break; 1718 break;
1694 case IEEE80211_STYPE_ACTION: 1719 case IEEE80211_STYPE_ACTION:
1695 switch (mgmt->u.action.category) { 1720 switch (mgmt->u.action.category) {
1696 case WLAN_CATEGORY_BACK: {
1697 struct ieee80211_local *local = sdata->local;
1698 int len = skb->len;
1699 struct sta_info *sta;
1700
1701 rcu_read_lock();
1702 sta = sta_info_get(sdata, mgmt->sa);
1703 if (!sta) {
1704 rcu_read_unlock();
1705 break;
1706 }
1707
1708 local_bh_disable();
1709
1710 switch (mgmt->u.action.u.addba_req.action_code) {
1711 case WLAN_ACTION_ADDBA_REQ:
1712 if (len < (IEEE80211_MIN_ACTION_SIZE +
1713 sizeof(mgmt->u.action.u.addba_req)))
1714 break;
1715 ieee80211_process_addba_request(local, sta, mgmt, len);
1716 break;
1717 case WLAN_ACTION_ADDBA_RESP:
1718 if (len < (IEEE80211_MIN_ACTION_SIZE +
1719 sizeof(mgmt->u.action.u.addba_resp)))
1720 break;
1721 ieee80211_process_addba_resp(local, sta, mgmt, len);
1722 break;
1723 case WLAN_ACTION_DELBA:
1724 if (len < (IEEE80211_MIN_ACTION_SIZE +
1725 sizeof(mgmt->u.action.u.delba)))
1726 break;
1727 ieee80211_process_delba(sdata, sta, mgmt, len);
1728 break;
1729 }
1730 local_bh_enable();
1731 rcu_read_unlock();
1732 break;
1733 }
1734 case WLAN_CATEGORY_SPECTRUM_MGMT: 1721 case WLAN_CATEGORY_SPECTRUM_MGMT:
1735 ieee80211_sta_process_chanswitch(sdata, 1722 ieee80211_sta_process_chanswitch(sdata,
1736 &mgmt->u.action.u.chan_switch.sw_elem, 1723 &mgmt->u.action.u.chan_switch.sw_elem,
@@ -1754,7 +1741,7 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
1754 default: 1741 default:
1755 WARN(1, "unexpected: %d", rma); 1742 WARN(1, "unexpected: %d", rma);
1756 } 1743 }
1757 goto out; 1744 return;
1758 } 1745 }
1759 1746
1760 mutex_unlock(&ifmgd->mtx); 1747 mutex_unlock(&ifmgd->mtx);
@@ -1769,7 +1756,8 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
1769 if (wk->sdata != sdata) 1756 if (wk->sdata != sdata)
1770 continue; 1757 continue;
1771 1758
1772 if (wk->type != IEEE80211_WORK_ASSOC) 1759 if (wk->type != IEEE80211_WORK_ASSOC &&
1760 wk->type != IEEE80211_WORK_ASSOC_BEACON_WAIT)
1773 continue; 1761 continue;
1774 1762
1775 if (memcmp(mgmt->bssid, wk->filter_ta, ETH_ALEN)) 1763 if (memcmp(mgmt->bssid, wk->filter_ta, ETH_ALEN))
@@ -1799,8 +1787,6 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
1799 1787
1800 cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len); 1788 cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len);
1801 } 1789 }
1802 out:
1803 kfree_skb(skb);
1804} 1790}
1805 1791
1806static void ieee80211_sta_timer(unsigned long data) 1792static void ieee80211_sta_timer(unsigned long data)
@@ -1815,39 +1801,13 @@ static void ieee80211_sta_timer(unsigned long data)
1815 return; 1801 return;
1816 } 1802 }
1817 1803
1818 ieee80211_queue_work(&local->hw, &ifmgd->work); 1804 ieee80211_queue_work(&local->hw, &sdata->work);
1819} 1805}
1820 1806
1821static void ieee80211_sta_work(struct work_struct *work) 1807void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
1822{ 1808{
1823 struct ieee80211_sub_if_data *sdata =
1824 container_of(work, struct ieee80211_sub_if_data, u.mgd.work);
1825 struct ieee80211_local *local = sdata->local; 1809 struct ieee80211_local *local = sdata->local;
1826 struct ieee80211_if_managed *ifmgd; 1810 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1827 struct sk_buff *skb;
1828
1829 if (!ieee80211_sdata_running(sdata))
1830 return;
1831
1832 if (local->scanning)
1833 return;
1834
1835 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
1836 return;
1837
1838 /*
1839 * ieee80211_queue_work() should have picked up most cases,
1840 * here we'll pick the the rest.
1841 */
1842 if (WARN(local->suspended, "STA MLME work scheduled while "
1843 "going to suspend\n"))
1844 return;
1845
1846 ifmgd = &sdata->u.mgd;
1847
1848 /* first process frames to avoid timing out while a frame is pending */
1849 while ((skb = skb_dequeue(&ifmgd->skb_queue)))
1850 ieee80211_sta_rx_queued_mgmt(sdata, skb);
1851 1811
1852 /* then process the rest of the work */ 1812 /* then process the rest of the work */
1853 mutex_lock(&ifmgd->mtx); 1813 mutex_lock(&ifmgd->mtx);
@@ -1942,8 +1902,7 @@ static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata)
1942 ieee80211_queue_work(&sdata->local->hw, 1902 ieee80211_queue_work(&sdata->local->hw,
1943 &sdata->u.mgd.monitor_work); 1903 &sdata->u.mgd.monitor_work);
1944 /* and do all the other regular work too */ 1904 /* and do all the other regular work too */
1945 ieee80211_queue_work(&sdata->local->hw, 1905 ieee80211_queue_work(&sdata->local->hw, &sdata->work);
1946 &sdata->u.mgd.work);
1947 } 1906 }
1948} 1907}
1949 1908
@@ -1958,7 +1917,6 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata)
1958 * time -- the code here is properly synchronised. 1917 * time -- the code here is properly synchronised.
1959 */ 1918 */
1960 1919
1961 cancel_work_sync(&ifmgd->work);
1962 cancel_work_sync(&ifmgd->beacon_connection_loss_work); 1920 cancel_work_sync(&ifmgd->beacon_connection_loss_work);
1963 if (del_timer_sync(&ifmgd->timer)) 1921 if (del_timer_sync(&ifmgd->timer))
1964 set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running); 1922 set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running);
@@ -1990,7 +1948,6 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
1990 struct ieee80211_if_managed *ifmgd; 1948 struct ieee80211_if_managed *ifmgd;
1991 1949
1992 ifmgd = &sdata->u.mgd; 1950 ifmgd = &sdata->u.mgd;
1993 INIT_WORK(&ifmgd->work, ieee80211_sta_work);
1994 INIT_WORK(&ifmgd->monitor_work, ieee80211_sta_monitor_work); 1951 INIT_WORK(&ifmgd->monitor_work, ieee80211_sta_monitor_work);
1995 INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work); 1952 INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work);
1996 INIT_WORK(&ifmgd->beacon_connection_loss_work, 1953 INIT_WORK(&ifmgd->beacon_connection_loss_work,
@@ -2003,7 +1960,6 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
2003 (unsigned long) sdata); 1960 (unsigned long) sdata);
2004 setup_timer(&ifmgd->chswitch_timer, ieee80211_chswitch_timer, 1961 setup_timer(&ifmgd->chswitch_timer, ieee80211_chswitch_timer,
2005 (unsigned long) sdata); 1962 (unsigned long) sdata);
2006 skb_queue_head_init(&ifmgd->skb_queue);
2007 1963
2008 ifmgd->flags = 0; 1964 ifmgd->flags = 0;
2009 1965
@@ -2081,6 +2037,8 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
2081 auth_alg = WLAN_AUTH_OPEN; 2037 auth_alg = WLAN_AUTH_OPEN;
2082 break; 2038 break;
2083 case NL80211_AUTHTYPE_SHARED_KEY: 2039 case NL80211_AUTHTYPE_SHARED_KEY:
2040 if (IS_ERR(sdata->local->wep_tx_tfm))
2041 return -EOPNOTSUPP;
2084 auth_alg = WLAN_AUTH_SHARED_KEY; 2042 auth_alg = WLAN_AUTH_SHARED_KEY;
2085 break; 2043 break;
2086 case NL80211_AUTHTYPE_FT: 2044 case NL80211_AUTHTYPE_FT:
@@ -2134,6 +2092,8 @@ static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk,
2134 struct sk_buff *skb) 2092 struct sk_buff *skb)
2135{ 2093{
2136 struct ieee80211_mgmt *mgmt; 2094 struct ieee80211_mgmt *mgmt;
2095 struct ieee80211_rx_status *rx_status;
2096 struct ieee802_11_elems elems;
2137 u16 status; 2097 u16 status;
2138 2098
2139 if (!skb) { 2099 if (!skb) {
@@ -2141,6 +2101,19 @@ static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk,
2141 return WORK_DONE_DESTROY; 2101 return WORK_DONE_DESTROY;
2142 } 2102 }
2143 2103
2104 if (wk->type == IEEE80211_WORK_ASSOC_BEACON_WAIT) {
2105 mutex_lock(&wk->sdata->u.mgd.mtx);
2106 rx_status = (void *) skb->cb;
2107 ieee802_11_parse_elems(skb->data + 24 + 12, skb->len - 24 - 12, &elems);
2108 ieee80211_rx_bss_info(wk->sdata, (void *)skb->data, skb->len, rx_status,
2109 &elems, true);
2110 mutex_unlock(&wk->sdata->u.mgd.mtx);
2111
2112 wk->type = IEEE80211_WORK_ASSOC;
2113 /* not really done yet */
2114 return WORK_DONE_REQUEUE;
2115 }
2116
2144 mgmt = (void *)skb->data; 2117 mgmt = (void *)skb->data;
2145 status = le16_to_cpu(mgmt->u.assoc_resp.status_code); 2118 status = le16_to_cpu(mgmt->u.assoc_resp.status_code);
2146 2119
@@ -2153,6 +2126,7 @@ static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk,
2153 wk->filter_ta); 2126 wk->filter_ta);
2154 return WORK_DONE_DESTROY; 2127 return WORK_DONE_DESTROY;
2155 } 2128 }
2129
2156 mutex_unlock(&wk->sdata->u.mgd.mtx); 2130 mutex_unlock(&wk->sdata->u.mgd.mtx);
2157 } 2131 }
2158 2132
@@ -2253,10 +2227,14 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
2253 if (req->prev_bssid) 2227 if (req->prev_bssid)
2254 memcpy(wk->assoc.prev_bssid, req->prev_bssid, ETH_ALEN); 2228 memcpy(wk->assoc.prev_bssid, req->prev_bssid, ETH_ALEN);
2255 2229
2256 wk->type = IEEE80211_WORK_ASSOC;
2257 wk->chan = req->bss->channel; 2230 wk->chan = req->bss->channel;
2258 wk->sdata = sdata; 2231 wk->sdata = sdata;
2259 wk->done = ieee80211_assoc_done; 2232 wk->done = ieee80211_assoc_done;
2233 if (!bss->dtim_period &&
2234 sdata->local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD)
2235 wk->type = IEEE80211_WORK_ASSOC_BEACON_WAIT;
2236 else
2237 wk->type = IEEE80211_WORK_ASSOC;
2260 2238
2261 if (req->use_mfp) { 2239 if (req->use_mfp) {
2262 ifmgd->mfp = IEEE80211_MFP_REQUIRED; 2240 ifmgd->mfp = IEEE80211_MFP_REQUIRED;
@@ -2282,14 +2260,16 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
2282 struct ieee80211_local *local = sdata->local; 2260 struct ieee80211_local *local = sdata->local;
2283 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2261 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2284 struct ieee80211_work *wk; 2262 struct ieee80211_work *wk;
2285 const u8 *bssid = req->bss->bssid; 2263 u8 bssid[ETH_ALEN];
2264 bool assoc_bss = false;
2286 2265
2287 mutex_lock(&ifmgd->mtx); 2266 mutex_lock(&ifmgd->mtx);
2288 2267
2268 memcpy(bssid, req->bss->bssid, ETH_ALEN);
2289 if (ifmgd->associated == req->bss) { 2269 if (ifmgd->associated == req->bss) {
2290 bssid = req->bss->bssid; 2270 ieee80211_set_disassoc(sdata, false);
2291 ieee80211_set_disassoc(sdata, true);
2292 mutex_unlock(&ifmgd->mtx); 2271 mutex_unlock(&ifmgd->mtx);
2272 assoc_bss = true;
2293 } else { 2273 } else {
2294 bool not_auth_yet = false; 2274 bool not_auth_yet = false;
2295 2275
@@ -2302,7 +2282,8 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
2302 2282
2303 if (wk->type != IEEE80211_WORK_DIRECT_PROBE && 2283 if (wk->type != IEEE80211_WORK_DIRECT_PROBE &&
2304 wk->type != IEEE80211_WORK_AUTH && 2284 wk->type != IEEE80211_WORK_AUTH &&
2305 wk->type != IEEE80211_WORK_ASSOC) 2285 wk->type != IEEE80211_WORK_ASSOC &&
2286 wk->type != IEEE80211_WORK_ASSOC_BEACON_WAIT)
2306 continue; 2287 continue;
2307 2288
2308 if (memcmp(req->bss->bssid, wk->filter_ta, ETH_ALEN)) 2289 if (memcmp(req->bss->bssid, wk->filter_ta, ETH_ALEN))
@@ -2335,6 +2316,8 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
2335 ieee80211_send_deauth_disassoc(sdata, bssid, IEEE80211_STYPE_DEAUTH, 2316 ieee80211_send_deauth_disassoc(sdata, bssid, IEEE80211_STYPE_DEAUTH,
2336 req->reason_code, cookie, 2317 req->reason_code, cookie,
2337 !req->local_state_change); 2318 !req->local_state_change);
2319 if (assoc_bss)
2320 sta_info_destroy_addr(sdata, bssid);
2338 2321
2339 ieee80211_recalc_idle(sdata->local); 2322 ieee80211_recalc_idle(sdata->local);
2340 2323
@@ -2379,41 +2362,6 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
2379 return 0; 2362 return 0;
2380} 2363}
2381 2364
2382int ieee80211_mgd_action(struct ieee80211_sub_if_data *sdata,
2383 struct ieee80211_channel *chan,
2384 enum nl80211_channel_type channel_type,
2385 const u8 *buf, size_t len, u64 *cookie)
2386{
2387 struct ieee80211_local *local = sdata->local;
2388 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2389 struct sk_buff *skb;
2390
2391 /* Check that we are on the requested channel for transmission */
2392 if ((chan != local->tmp_channel ||
2393 channel_type != local->tmp_channel_type) &&
2394 (chan != local->oper_channel ||
2395 channel_type != local->_oper_channel_type))
2396 return -EBUSY;
2397
2398 skb = dev_alloc_skb(local->hw.extra_tx_headroom + len);
2399 if (!skb)
2400 return -ENOMEM;
2401 skb_reserve(skb, local->hw.extra_tx_headroom);
2402
2403 memcpy(skb_put(skb, len), buf, len);
2404
2405 if (!(ifmgd->flags & IEEE80211_STA_MFP_ENABLED))
2406 IEEE80211_SKB_CB(skb)->flags |=
2407 IEEE80211_TX_INTFL_DONT_ENCRYPT;
2408 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_NL80211_FRAME_TX |
2409 IEEE80211_TX_CTL_REQ_TX_STATUS;
2410 skb->dev = sdata->dev;
2411 ieee80211_tx_skb(sdata, skb);
2412
2413 *cookie = (unsigned long) skb;
2414 return 0;
2415}
2416
2417void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif, 2365void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif,
2418 enum nl80211_cqm_rssi_threshold_event rssi_event, 2366 enum nl80211_cqm_rssi_threshold_event rssi_event,
2419 gfp_t gfp) 2367 gfp_t gfp)