diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/ieee80211_i.h | 4 | ||||
-rw-r--r-- | net/mac80211/iface.c | 2 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 64 |
3 files changed, 60 insertions, 10 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index b84126491ab1..ab369e2a5282 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -327,7 +327,7 @@ struct ieee80211_if_managed { | |||
327 | struct work_struct work; | 327 | struct work_struct work; |
328 | struct work_struct monitor_work; | 328 | struct work_struct monitor_work; |
329 | struct work_struct chswitch_work; | 329 | struct work_struct chswitch_work; |
330 | struct work_struct beacon_loss_work; | 330 | struct work_struct beacon_connection_loss_work; |
331 | 331 | ||
332 | unsigned long probe_timeout; | 332 | unsigned long probe_timeout; |
333 | int probe_send_count; | 333 | int probe_send_count; |
@@ -1156,7 +1156,7 @@ void ieee80211_send_nullfunc(struct ieee80211_local *local, | |||
1156 | int powersave); | 1156 | int powersave); |
1157 | void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, | 1157 | void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, |
1158 | struct ieee80211_hdr *hdr); | 1158 | struct ieee80211_hdr *hdr); |
1159 | void ieee80211_beacon_loss_work(struct work_struct *work); | 1159 | void ieee80211_beacon_connection_loss_work(struct work_struct *work); |
1160 | 1160 | ||
1161 | void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, | 1161 | void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, |
1162 | enum queue_stop_reason reason); | 1162 | enum queue_stop_reason reason); |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index d5571b9420cd..b4ec59a8dc03 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -486,7 +486,7 @@ static int ieee80211_stop(struct net_device *dev) | |||
486 | cancel_work_sync(&sdata->u.mgd.work); | 486 | cancel_work_sync(&sdata->u.mgd.work); |
487 | cancel_work_sync(&sdata->u.mgd.chswitch_work); | 487 | cancel_work_sync(&sdata->u.mgd.chswitch_work); |
488 | cancel_work_sync(&sdata->u.mgd.monitor_work); | 488 | cancel_work_sync(&sdata->u.mgd.monitor_work); |
489 | cancel_work_sync(&sdata->u.mgd.beacon_loss_work); | 489 | cancel_work_sync(&sdata->u.mgd.beacon_connection_loss_work); |
490 | 490 | ||
491 | /* | 491 | /* |
492 | * When we get here, the interface is marked down. | 492 | * When we get here, the interface is marked down. |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 0ab284c32135..865ea1cfb7bb 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -851,6 +851,9 @@ void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, | |||
851 | if (is_multicast_ether_addr(hdr->addr1)) | 851 | if (is_multicast_ether_addr(hdr->addr1)) |
852 | return; | 852 | return; |
853 | 853 | ||
854 | if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) | ||
855 | return; | ||
856 | |||
854 | mod_timer(&sdata->u.mgd.conn_mon_timer, | 857 | mod_timer(&sdata->u.mgd.conn_mon_timer, |
855 | round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME)); | 858 | round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME)); |
856 | } | 859 | } |
@@ -928,23 +931,68 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, | |||
928 | mutex_unlock(&ifmgd->mtx); | 931 | mutex_unlock(&ifmgd->mtx); |
929 | } | 932 | } |
930 | 933 | ||
931 | void ieee80211_beacon_loss_work(struct work_struct *work) | 934 | static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata) |
935 | { | ||
936 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | ||
937 | struct ieee80211_local *local = sdata->local; | ||
938 | u8 bssid[ETH_ALEN]; | ||
939 | |||
940 | mutex_lock(&ifmgd->mtx); | ||
941 | if (!ifmgd->associated) { | ||
942 | mutex_unlock(&ifmgd->mtx); | ||
943 | return; | ||
944 | } | ||
945 | |||
946 | memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN); | ||
947 | |||
948 | printk(KERN_DEBUG "Connection to AP %pM lost.\n", bssid); | ||
949 | |||
950 | ieee80211_set_disassoc(sdata); | ||
951 | ieee80211_recalc_idle(local); | ||
952 | mutex_unlock(&ifmgd->mtx); | ||
953 | /* | ||
954 | * must be outside lock due to cfg80211, | ||
955 | * but that's not a problem. | ||
956 | */ | ||
957 | ieee80211_send_deauth_disassoc(sdata, bssid, | ||
958 | IEEE80211_STYPE_DEAUTH, | ||
959 | WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, | ||
960 | NULL); | ||
961 | } | ||
962 | |||
963 | void ieee80211_beacon_connection_loss_work(struct work_struct *work) | ||
932 | { | 964 | { |
933 | struct ieee80211_sub_if_data *sdata = | 965 | struct ieee80211_sub_if_data *sdata = |
934 | container_of(work, struct ieee80211_sub_if_data, | 966 | container_of(work, struct ieee80211_sub_if_data, |
935 | u.mgd.beacon_loss_work); | 967 | u.mgd.beacon_connection_loss_work); |
936 | 968 | ||
937 | ieee80211_mgd_probe_ap(sdata, true); | 969 | if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) |
970 | __ieee80211_connection_loss(sdata); | ||
971 | else | ||
972 | ieee80211_mgd_probe_ap(sdata, true); | ||
938 | } | 973 | } |
939 | 974 | ||
940 | void ieee80211_beacon_loss(struct ieee80211_vif *vif) | 975 | void ieee80211_beacon_loss(struct ieee80211_vif *vif) |
941 | { | 976 | { |
942 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | 977 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
978 | struct ieee80211_hw *hw = &sdata->local->hw; | ||
943 | 979 | ||
944 | ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.beacon_loss_work); | 980 | WARN_ON(hw->flags & IEEE80211_HW_CONNECTION_MONITOR); |
981 | ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work); | ||
945 | } | 982 | } |
946 | EXPORT_SYMBOL(ieee80211_beacon_loss); | 983 | EXPORT_SYMBOL(ieee80211_beacon_loss); |
947 | 984 | ||
985 | void ieee80211_connection_loss(struct ieee80211_vif *vif) | ||
986 | { | ||
987 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | ||
988 | struct ieee80211_hw *hw = &sdata->local->hw; | ||
989 | |||
990 | WARN_ON(!(hw->flags & IEEE80211_HW_CONNECTION_MONITOR)); | ||
991 | ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work); | ||
992 | } | ||
993 | EXPORT_SYMBOL(ieee80211_connection_loss); | ||
994 | |||
995 | |||
948 | static enum rx_mgmt_action __must_check | 996 | static enum rx_mgmt_action __must_check |
949 | ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, | 997 | ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, |
950 | struct ieee80211_mgmt *mgmt, size_t len) | 998 | struct ieee80211_mgmt *mgmt, size_t len) |
@@ -1634,7 +1682,8 @@ static void ieee80211_sta_bcn_mon_timer(unsigned long data) | |||
1634 | if (local->quiescing) | 1682 | if (local->quiescing) |
1635 | return; | 1683 | return; |
1636 | 1684 | ||
1637 | ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.beacon_loss_work); | 1685 | ieee80211_queue_work(&sdata->local->hw, |
1686 | &sdata->u.mgd.beacon_connection_loss_work); | ||
1638 | } | 1687 | } |
1639 | 1688 | ||
1640 | static void ieee80211_sta_conn_mon_timer(unsigned long data) | 1689 | static void ieee80211_sta_conn_mon_timer(unsigned long data) |
@@ -1686,7 +1735,7 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata) | |||
1686 | */ | 1735 | */ |
1687 | 1736 | ||
1688 | cancel_work_sync(&ifmgd->work); | 1737 | cancel_work_sync(&ifmgd->work); |
1689 | cancel_work_sync(&ifmgd->beacon_loss_work); | 1738 | cancel_work_sync(&ifmgd->beacon_connection_loss_work); |
1690 | if (del_timer_sync(&ifmgd->timer)) | 1739 | if (del_timer_sync(&ifmgd->timer)) |
1691 | set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running); | 1740 | set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running); |
1692 | 1741 | ||
@@ -1720,7 +1769,8 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) | |||
1720 | INIT_WORK(&ifmgd->work, ieee80211_sta_work); | 1769 | INIT_WORK(&ifmgd->work, ieee80211_sta_work); |
1721 | INIT_WORK(&ifmgd->monitor_work, ieee80211_sta_monitor_work); | 1770 | INIT_WORK(&ifmgd->monitor_work, ieee80211_sta_monitor_work); |
1722 | INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work); | 1771 | INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work); |
1723 | INIT_WORK(&ifmgd->beacon_loss_work, ieee80211_beacon_loss_work); | 1772 | INIT_WORK(&ifmgd->beacon_connection_loss_work, |
1773 | ieee80211_beacon_connection_loss_work); | ||
1724 | setup_timer(&ifmgd->timer, ieee80211_sta_timer, | 1774 | setup_timer(&ifmgd->timer, ieee80211_sta_timer, |
1725 | (unsigned long) sdata); | 1775 | (unsigned long) sdata); |
1726 | setup_timer(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer, | 1776 | setup_timer(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer, |