aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-03-29 16:50:10 -0400
committerDavid S. Miller <davem@davemloft.net>2010-03-29 16:50:10 -0400
commit7905e357ebe67a26d9dc8caa1a0b8346431b5f0d (patch)
tree134442df2f062caa6cebda1b352948b8209efcec /net/mac80211
parent083ba279d52bcad20f1dfa3cefd4255cbe82d521 (diff)
parent76232ebf898c4d5e657f2b663fbf7108bca80ded (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/cfg.c27
-rw-r--r--net/mac80211/ieee80211_i.h4
-rw-r--r--net/mac80211/iface.c2
-rw-r--r--net/mac80211/mlme.c79
-rw-r--r--net/mac80211/tx.c2
5 files changed, 102 insertions, 12 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index b7116ef84a3b..c8f520529eec 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1402,6 +1402,32 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1402 return 0; 1402 return 0;
1403} 1403}
1404 1404
1405static int ieee80211_set_cqm_rssi_config(struct wiphy *wiphy,
1406 struct net_device *dev,
1407 s32 rssi_thold, u32 rssi_hyst)
1408{
1409 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1410 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1411 struct ieee80211_vif *vif = &sdata->vif;
1412 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
1413
1414 if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI))
1415 return -EOPNOTSUPP;
1416
1417 if (rssi_thold == bss_conf->cqm_rssi_thold &&
1418 rssi_hyst == bss_conf->cqm_rssi_hyst)
1419 return 0;
1420
1421 bss_conf->cqm_rssi_thold = rssi_thold;
1422 bss_conf->cqm_rssi_hyst = rssi_hyst;
1423
1424 /* tell the driver upon association, unless already associated */
1425 if (sdata->u.mgd.associated)
1426 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_CQM);
1427
1428 return 0;
1429}
1430
1405static int ieee80211_set_bitrate_mask(struct wiphy *wiphy, 1431static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
1406 struct net_device *dev, 1432 struct net_device *dev,
1407 const u8 *addr, 1433 const u8 *addr,
@@ -1506,4 +1532,5 @@ struct cfg80211_ops mac80211_config_ops = {
1506 .remain_on_channel = ieee80211_remain_on_channel, 1532 .remain_on_channel = ieee80211_remain_on_channel,
1507 .cancel_remain_on_channel = ieee80211_cancel_remain_on_channel, 1533 .cancel_remain_on_channel = ieee80211_cancel_remain_on_channel,
1508 .action = ieee80211_action, 1534 .action = ieee80211_action,
1535 .set_cqm_rssi_config = ieee80211_set_cqm_rssi_config,
1509}; 1536};
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 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
934void ieee80211_beacon_loss_work(struct work_struct *work) 942static 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
971void 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
943void ieee80211_beacon_loss(struct ieee80211_vif *vif) 983void 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}
949EXPORT_SYMBOL(ieee80211_beacon_loss); 991EXPORT_SYMBOL(ieee80211_beacon_loss);
950 992
993void 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}
1001EXPORT_SYMBOL(ieee80211_connection_loss);
1002
1003
951static enum rx_mgmt_action __must_check 1004static enum rx_mgmt_action __must_check
952ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, 1005ieee80211_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
1643static void ieee80211_sta_conn_mon_timer(unsigned long data) 1697static 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
2194void 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}
2202EXPORT_SYMBOL(ieee80211_cqm_rssi_notify);
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index cbe53ed4fb0b..08e1f17a4226 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -2010,14 +2010,12 @@ void ieee80211_tx_pending(unsigned long data)
2010 while (!skb_queue_empty(&local->pending[i])) { 2010 while (!skb_queue_empty(&local->pending[i])) {
2011 struct sk_buff *skb = __skb_dequeue(&local->pending[i]); 2011 struct sk_buff *skb = __skb_dequeue(&local->pending[i]);
2012 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 2012 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
2013 struct ieee80211_sub_if_data *sdata;
2014 2013
2015 if (WARN_ON(!info->control.vif)) { 2014 if (WARN_ON(!info->control.vif)) {
2016 kfree_skb(skb); 2015 kfree_skb(skb);
2017 continue; 2016 continue;
2018 } 2017 }
2019 2018
2020 sdata = vif_to_sdata(info->control.vif);
2021 spin_unlock_irqrestore(&local->queue_stop_reason_lock, 2019 spin_unlock_irqrestore(&local->queue_stop_reason_lock,
2022 flags); 2020 flags);
2023 2021