diff options
author | David S. Miller <davem@davemloft.net> | 2010-03-29 16:50:10 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-03-29 16:50:10 -0400 |
commit | 7905e357ebe67a26d9dc8caa1a0b8346431b5f0d (patch) | |
tree | 134442df2f062caa6cebda1b352948b8209efcec /net/mac80211/mlme.c | |
parent | 083ba279d52bcad20f1dfa3cefd4255cbe82d521 (diff) | |
parent | 76232ebf898c4d5e657f2b663fbf7108bca80ded (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r-- | net/mac80211/mlme.c | 79 |
1 files changed, 72 insertions, 7 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index be5f723d643a..34e0650e9ef8 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -753,6 +753,11 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
753 | /* And the BSSID changed - we're associated now */ | 753 | /* And the BSSID changed - we're associated now */ |
754 | bss_info_changed |= BSS_CHANGED_BSSID; | 754 | bss_info_changed |= BSS_CHANGED_BSSID; |
755 | 755 | ||
756 | /* Tell the driver to monitor connection quality (if supported) */ | ||
757 | if ((local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI) && | ||
758 | sdata->vif.bss_conf.cqm_rssi_thold) | ||
759 | bss_info_changed |= BSS_CHANGED_CQM; | ||
760 | |||
756 | ieee80211_bss_info_change_notify(sdata, bss_info_changed); | 761 | ieee80211_bss_info_change_notify(sdata, bss_info_changed); |
757 | 762 | ||
758 | mutex_lock(&local->iflist_mtx); | 763 | mutex_lock(&local->iflist_mtx); |
@@ -854,6 +859,9 @@ void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, | |||
854 | if (is_multicast_ether_addr(hdr->addr1)) | 859 | if (is_multicast_ether_addr(hdr->addr1)) |
855 | return; | 860 | return; |
856 | 861 | ||
862 | if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) | ||
863 | return; | ||
864 | |||
857 | mod_timer(&sdata->u.mgd.conn_mon_timer, | 865 | mod_timer(&sdata->u.mgd.conn_mon_timer, |
858 | round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME)); | 866 | round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME)); |
859 | } | 867 | } |
@@ -931,23 +939,68 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, | |||
931 | mutex_unlock(&ifmgd->mtx); | 939 | mutex_unlock(&ifmgd->mtx); |
932 | } | 940 | } |
933 | 941 | ||
934 | void ieee80211_beacon_loss_work(struct work_struct *work) | 942 | static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata) |
943 | { | ||
944 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | ||
945 | struct ieee80211_local *local = sdata->local; | ||
946 | u8 bssid[ETH_ALEN]; | ||
947 | |||
948 | mutex_lock(&ifmgd->mtx); | ||
949 | if (!ifmgd->associated) { | ||
950 | mutex_unlock(&ifmgd->mtx); | ||
951 | return; | ||
952 | } | ||
953 | |||
954 | memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN); | ||
955 | |||
956 | printk(KERN_DEBUG "Connection to AP %pM lost.\n", bssid); | ||
957 | |||
958 | ieee80211_set_disassoc(sdata); | ||
959 | ieee80211_recalc_idle(local); | ||
960 | mutex_unlock(&ifmgd->mtx); | ||
961 | /* | ||
962 | * must be outside lock due to cfg80211, | ||
963 | * but that's not a problem. | ||
964 | */ | ||
965 | ieee80211_send_deauth_disassoc(sdata, bssid, | ||
966 | IEEE80211_STYPE_DEAUTH, | ||
967 | WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, | ||
968 | NULL); | ||
969 | } | ||
970 | |||
971 | void ieee80211_beacon_connection_loss_work(struct work_struct *work) | ||
935 | { | 972 | { |
936 | struct ieee80211_sub_if_data *sdata = | 973 | struct ieee80211_sub_if_data *sdata = |
937 | container_of(work, struct ieee80211_sub_if_data, | 974 | container_of(work, struct ieee80211_sub_if_data, |
938 | u.mgd.beacon_loss_work); | 975 | u.mgd.beacon_connection_loss_work); |
939 | 976 | ||
940 | ieee80211_mgd_probe_ap(sdata, true); | 977 | if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) |
978 | __ieee80211_connection_loss(sdata); | ||
979 | else | ||
980 | ieee80211_mgd_probe_ap(sdata, true); | ||
941 | } | 981 | } |
942 | 982 | ||
943 | void ieee80211_beacon_loss(struct ieee80211_vif *vif) | 983 | void ieee80211_beacon_loss(struct ieee80211_vif *vif) |
944 | { | 984 | { |
945 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | 985 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
986 | struct ieee80211_hw *hw = &sdata->local->hw; | ||
946 | 987 | ||
947 | ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.beacon_loss_work); | 988 | WARN_ON(hw->flags & IEEE80211_HW_CONNECTION_MONITOR); |
989 | ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work); | ||
948 | } | 990 | } |
949 | EXPORT_SYMBOL(ieee80211_beacon_loss); | 991 | EXPORT_SYMBOL(ieee80211_beacon_loss); |
950 | 992 | ||
993 | void ieee80211_connection_loss(struct ieee80211_vif *vif) | ||
994 | { | ||
995 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | ||
996 | struct ieee80211_hw *hw = &sdata->local->hw; | ||
997 | |||
998 | WARN_ON(!(hw->flags & IEEE80211_HW_CONNECTION_MONITOR)); | ||
999 | ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work); | ||
1000 | } | ||
1001 | EXPORT_SYMBOL(ieee80211_connection_loss); | ||
1002 | |||
1003 | |||
951 | static enum rx_mgmt_action __must_check | 1004 | static enum rx_mgmt_action __must_check |
952 | ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, | 1005 | ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, |
953 | struct ieee80211_mgmt *mgmt, size_t len) | 1006 | struct ieee80211_mgmt *mgmt, size_t len) |
@@ -1637,7 +1690,8 @@ static void ieee80211_sta_bcn_mon_timer(unsigned long data) | |||
1637 | if (local->quiescing) | 1690 | if (local->quiescing) |
1638 | return; | 1691 | return; |
1639 | 1692 | ||
1640 | ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.beacon_loss_work); | 1693 | ieee80211_queue_work(&sdata->local->hw, |
1694 | &sdata->u.mgd.beacon_connection_loss_work); | ||
1641 | } | 1695 | } |
1642 | 1696 | ||
1643 | static void ieee80211_sta_conn_mon_timer(unsigned long data) | 1697 | static void ieee80211_sta_conn_mon_timer(unsigned long data) |
@@ -1689,7 +1743,7 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata) | |||
1689 | */ | 1743 | */ |
1690 | 1744 | ||
1691 | cancel_work_sync(&ifmgd->work); | 1745 | cancel_work_sync(&ifmgd->work); |
1692 | cancel_work_sync(&ifmgd->beacon_loss_work); | 1746 | cancel_work_sync(&ifmgd->beacon_connection_loss_work); |
1693 | if (del_timer_sync(&ifmgd->timer)) | 1747 | if (del_timer_sync(&ifmgd->timer)) |
1694 | set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running); | 1748 | set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running); |
1695 | 1749 | ||
@@ -1723,7 +1777,8 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) | |||
1723 | INIT_WORK(&ifmgd->work, ieee80211_sta_work); | 1777 | INIT_WORK(&ifmgd->work, ieee80211_sta_work); |
1724 | INIT_WORK(&ifmgd->monitor_work, ieee80211_sta_monitor_work); | 1778 | INIT_WORK(&ifmgd->monitor_work, ieee80211_sta_monitor_work); |
1725 | INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work); | 1779 | INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work); |
1726 | INIT_WORK(&ifmgd->beacon_loss_work, ieee80211_beacon_loss_work); | 1780 | INIT_WORK(&ifmgd->beacon_connection_loss_work, |
1781 | ieee80211_beacon_connection_loss_work); | ||
1727 | setup_timer(&ifmgd->timer, ieee80211_sta_timer, | 1782 | setup_timer(&ifmgd->timer, ieee80211_sta_timer, |
1728 | (unsigned long) sdata); | 1783 | (unsigned long) sdata); |
1729 | setup_timer(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer, | 1784 | setup_timer(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer, |
@@ -2135,3 +2190,13 @@ int ieee80211_mgd_action(struct ieee80211_sub_if_data *sdata, | |||
2135 | *cookie = (unsigned long) skb; | 2190 | *cookie = (unsigned long) skb; |
2136 | return 0; | 2191 | return 0; |
2137 | } | 2192 | } |
2193 | |||
2194 | void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif, | ||
2195 | enum nl80211_cqm_rssi_threshold_event rssi_event, | ||
2196 | gfp_t gfp) | ||
2197 | { | ||
2198 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | ||
2199 | |||
2200 | cfg80211_cqm_rssi_notify(sdata->dev, rssi_event, gfp); | ||
2201 | } | ||
2202 | EXPORT_SYMBOL(ieee80211_cqm_rssi_notify); | ||