aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/ieee80211_i.h4
-rw-r--r--net/mac80211/iface.c2
-rw-r--r--net/mac80211/mlme.c64
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);
1157void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, 1157void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
1158 struct ieee80211_hdr *hdr); 1158 struct ieee80211_hdr *hdr);
1159void ieee80211_beacon_loss_work(struct work_struct *work); 1159void ieee80211_beacon_connection_loss_work(struct work_struct *work);
1160 1160
1161void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, 1161void 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
931void ieee80211_beacon_loss_work(struct work_struct *work) 934static 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
963void 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
940void ieee80211_beacon_loss(struct ieee80211_vif *vif) 975void 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}
946EXPORT_SYMBOL(ieee80211_beacon_loss); 983EXPORT_SYMBOL(ieee80211_beacon_loss);
947 984
985void 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}
993EXPORT_SYMBOL(ieee80211_connection_loss);
994
995
948static enum rx_mgmt_action __must_check 996static enum rx_mgmt_action __must_check
949ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, 997ieee80211_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
1640static void ieee80211_sta_conn_mon_timer(unsigned long data) 1689static 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,