aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/cfg.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r--net/mac80211/cfg.c105
1 files changed, 76 insertions, 29 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 85ac364f4636..c2a2dcbfdf01 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -353,6 +353,7 @@ void sta_set_rate_info_tx(struct sta_info *sta,
353static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) 353static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
354{ 354{
355 struct ieee80211_sub_if_data *sdata = sta->sdata; 355 struct ieee80211_sub_if_data *sdata = sta->sdata;
356 struct ieee80211_local *local = sdata->local;
356 struct timespec uptime; 357 struct timespec uptime;
357 358
358 sinfo->generation = sdata->local->sta_generation; 359 sinfo->generation = sdata->local->sta_generation;
@@ -388,7 +389,9 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
388 if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) || 389 if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) ||
389 (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) { 390 (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) {
390 sinfo->filled |= STATION_INFO_SIGNAL | STATION_INFO_SIGNAL_AVG; 391 sinfo->filled |= STATION_INFO_SIGNAL | STATION_INFO_SIGNAL_AVG;
391 sinfo->signal = (s8)sta->last_signal; 392 if (!local->ops->get_rssi ||
393 drv_get_rssi(local, sdata, &sta->sta, &sinfo->signal))
394 sinfo->signal = (s8)sta->last_signal;
392 sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal); 395 sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal);
393 } 396 }
394 397
@@ -517,7 +520,7 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy,
517 * network device. 520 * network device.
518 */ 521 */
519 522
520 rcu_read_lock(); 523 mutex_lock(&local->sta_mtx);
521 524
522 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 525 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
523 sta = sta_info_get_bss(sdata, sdata->u.mgd.bssid); 526 sta = sta_info_get_bss(sdata, sdata->u.mgd.bssid);
@@ -546,7 +549,7 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy,
546 data[i] = (u8)sinfo.signal_avg; 549 data[i] = (u8)sinfo.signal_avg;
547 i++; 550 i++;
548 } else { 551 } else {
549 list_for_each_entry_rcu(sta, &local->sta_list, list) { 552 list_for_each_entry(sta, &local->sta_list, list) {
550 /* Make sure this station belongs to the proper dev */ 553 /* Make sure this station belongs to the proper dev */
551 if (sta->sdata->dev != dev) 554 if (sta->sdata->dev != dev)
552 continue; 555 continue;
@@ -603,7 +606,7 @@ do_survey:
603 else 606 else
604 data[i++] = -1LL; 607 data[i++] = -1LL;
605 608
606 rcu_read_unlock(); 609 mutex_unlock(&local->sta_mtx);
607 610
608 if (WARN_ON(i != STA_STATS_LEN)) 611 if (WARN_ON(i != STA_STATS_LEN))
609 return; 612 return;
@@ -629,10 +632,11 @@ static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
629 int idx, u8 *mac, struct station_info *sinfo) 632 int idx, u8 *mac, struct station_info *sinfo)
630{ 633{
631 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 634 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
635 struct ieee80211_local *local = sdata->local;
632 struct sta_info *sta; 636 struct sta_info *sta;
633 int ret = -ENOENT; 637 int ret = -ENOENT;
634 638
635 rcu_read_lock(); 639 mutex_lock(&local->sta_mtx);
636 640
637 sta = sta_info_get_by_idx(sdata, idx); 641 sta = sta_info_get_by_idx(sdata, idx);
638 if (sta) { 642 if (sta) {
@@ -641,7 +645,7 @@ static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
641 sta_set_sinfo(sta, sinfo); 645 sta_set_sinfo(sta, sinfo);
642 } 646 }
643 647
644 rcu_read_unlock(); 648 mutex_unlock(&local->sta_mtx);
645 649
646 return ret; 650 return ret;
647} 651}
@@ -658,10 +662,11 @@ static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
658 u8 *mac, struct station_info *sinfo) 662 u8 *mac, struct station_info *sinfo)
659{ 663{
660 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 664 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
665 struct ieee80211_local *local = sdata->local;
661 struct sta_info *sta; 666 struct sta_info *sta;
662 int ret = -ENOENT; 667 int ret = -ENOENT;
663 668
664 rcu_read_lock(); 669 mutex_lock(&local->sta_mtx);
665 670
666 sta = sta_info_get_bss(sdata, mac); 671 sta = sta_info_get_bss(sdata, mac);
667 if (sta) { 672 if (sta) {
@@ -669,7 +674,7 @@ static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
669 sta_set_sinfo(sta, sinfo); 674 sta_set_sinfo(sta, sinfo);
670 } 675 }
671 676
672 rcu_read_unlock(); 677 mutex_unlock(&local->sta_mtx);
673 678
674 return ret; 679 return ret;
675} 680}
@@ -689,7 +694,8 @@ static int ieee80211_set_channel(struct wiphy *wiphy,
689 case CHAN_MODE_HOPPING: 694 case CHAN_MODE_HOPPING:
690 return -EBUSY; 695 return -EBUSY;
691 case CHAN_MODE_FIXED: 696 case CHAN_MODE_FIXED:
692 if (local->oper_channel != chan) 697 if (local->oper_channel != chan ||
698 (!sdata && local->_oper_channel_type != channel_type))
693 return -EBUSY; 699 return -EBUSY;
694 if (!sdata && local->_oper_channel_type == channel_type) 700 if (!sdata && local->_oper_channel_type == channel_type)
695 return 0; 701 return 0;
@@ -1529,7 +1535,7 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy,
1529 if (_chg_mesh_attr(NL80211_MESHCONF_TTL, mask)) 1535 if (_chg_mesh_attr(NL80211_MESHCONF_TTL, mask))
1530 conf->dot11MeshTTL = nconf->dot11MeshTTL; 1536 conf->dot11MeshTTL = nconf->dot11MeshTTL;
1531 if (_chg_mesh_attr(NL80211_MESHCONF_ELEMENT_TTL, mask)) 1537 if (_chg_mesh_attr(NL80211_MESHCONF_ELEMENT_TTL, mask))
1532 conf->dot11MeshTTL = nconf->element_ttl; 1538 conf->element_ttl = nconf->element_ttl;
1533 if (_chg_mesh_attr(NL80211_MESHCONF_AUTO_OPEN_PLINKS, mask)) 1539 if (_chg_mesh_attr(NL80211_MESHCONF_AUTO_OPEN_PLINKS, mask))
1534 conf->auto_open_plinks = nconf->auto_open_plinks; 1540 conf->auto_open_plinks = nconf->auto_open_plinks;
1535 if (_chg_mesh_attr(NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR, mask)) 1541 if (_chg_mesh_attr(NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR, mask))
@@ -1564,17 +1570,16 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy,
1564 * announcements, so require this ifmsh to also be a root node 1570 * announcements, so require this ifmsh to also be a root node
1565 * */ 1571 * */
1566 if (nconf->dot11MeshGateAnnouncementProtocol && 1572 if (nconf->dot11MeshGateAnnouncementProtocol &&
1567 !conf->dot11MeshHWMPRootMode) { 1573 !(conf->dot11MeshHWMPRootMode > IEEE80211_ROOTMODE_ROOT)) {
1568 conf->dot11MeshHWMPRootMode = 1; 1574 conf->dot11MeshHWMPRootMode = IEEE80211_PROACTIVE_RANN;
1569 ieee80211_mesh_root_setup(ifmsh); 1575 ieee80211_mesh_root_setup(ifmsh);
1570 } 1576 }
1571 conf->dot11MeshGateAnnouncementProtocol = 1577 conf->dot11MeshGateAnnouncementProtocol =
1572 nconf->dot11MeshGateAnnouncementProtocol; 1578 nconf->dot11MeshGateAnnouncementProtocol;
1573 } 1579 }
1574 if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_RANN_INTERVAL, mask)) { 1580 if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_RANN_INTERVAL, mask))
1575 conf->dot11MeshHWMPRannInterval = 1581 conf->dot11MeshHWMPRannInterval =
1576 nconf->dot11MeshHWMPRannInterval; 1582 nconf->dot11MeshHWMPRannInterval;
1577 }
1578 if (_chg_mesh_attr(NL80211_MESHCONF_FORWARDING, mask)) 1583 if (_chg_mesh_attr(NL80211_MESHCONF_FORWARDING, mask))
1579 conf->dot11MeshForwarding = nconf->dot11MeshForwarding; 1584 conf->dot11MeshForwarding = nconf->dot11MeshForwarding;
1580 if (_chg_mesh_attr(NL80211_MESHCONF_RSSI_THRESHOLD, mask)) { 1585 if (_chg_mesh_attr(NL80211_MESHCONF_RSSI_THRESHOLD, mask)) {
@@ -1590,6 +1595,15 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy,
1590 sdata->vif.bss_conf.ht_operation_mode = nconf->ht_opmode; 1595 sdata->vif.bss_conf.ht_operation_mode = nconf->ht_opmode;
1591 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_HT); 1596 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_HT);
1592 } 1597 }
1598 if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT, mask))
1599 conf->dot11MeshHWMPactivePathToRootTimeout =
1600 nconf->dot11MeshHWMPactivePathToRootTimeout;
1601 if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_ROOT_INTERVAL, mask))
1602 conf->dot11MeshHWMProotInterval =
1603 nconf->dot11MeshHWMProotInterval;
1604 if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL, mask))
1605 conf->dot11MeshHWMPconfirmationInterval =
1606 nconf->dot11MeshHWMPconfirmationInterval;
1593 return 0; 1607 return 0;
1594} 1608}
1595 1609
@@ -2309,6 +2323,21 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local,
2309 2323
2310 mutex_lock(&local->mtx); 2324 mutex_lock(&local->mtx);
2311 list_for_each_entry_safe(roc, tmp, &local->roc_list, list) { 2325 list_for_each_entry_safe(roc, tmp, &local->roc_list, list) {
2326 struct ieee80211_roc_work *dep, *tmp2;
2327
2328 list_for_each_entry_safe(dep, tmp2, &roc->dependents, list) {
2329 if (!mgmt_tx && (unsigned long)dep != cookie)
2330 continue;
2331 else if (mgmt_tx && dep->mgmt_tx_cookie != cookie)
2332 continue;
2333 /* found dependent item -- just remove it */
2334 list_del(&dep->list);
2335 mutex_unlock(&local->mtx);
2336
2337 ieee80211_roc_notify_destroy(dep);
2338 return 0;
2339 }
2340
2312 if (!mgmt_tx && (unsigned long)roc != cookie) 2341 if (!mgmt_tx && (unsigned long)roc != cookie)
2313 continue; 2342 continue;
2314 else if (mgmt_tx && roc->mgmt_tx_cookie != cookie) 2343 else if (mgmt_tx && roc->mgmt_tx_cookie != cookie)
@@ -2323,6 +2352,13 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local,
2323 return -ENOENT; 2352 return -ENOENT;
2324 } 2353 }
2325 2354
2355 /*
2356 * We found the item to cancel, so do that. Note that it
2357 * may have dependents, which we also cancel (and send
2358 * the expired signal for.) Not doing so would be quite
2359 * tricky here, but we may need to fix it later.
2360 */
2361
2326 if (local->ops->remain_on_channel) { 2362 if (local->ops->remain_on_channel) {
2327 if (found->started) { 2363 if (found->started) {
2328 ret = drv_cancel_remain_on_channel(local); 2364 ret = drv_cancel_remain_on_channel(local);
@@ -2334,8 +2370,8 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local,
2334 2370
2335 list_del(&found->list); 2371 list_del(&found->list);
2336 2372
2337 ieee80211_run_deferred_scan(local); 2373 if (found->started)
2338 ieee80211_start_next_roc(local); 2374 ieee80211_start_next_roc(local);
2339 mutex_unlock(&local->mtx); 2375 mutex_unlock(&local->mtx);
2340 2376
2341 ieee80211_roc_notify_destroy(found); 2377 ieee80211_roc_notify_destroy(found);
@@ -2489,16 +2525,30 @@ static void ieee80211_mgmt_frame_register(struct wiphy *wiphy,
2489 u16 frame_type, bool reg) 2525 u16 frame_type, bool reg)
2490{ 2526{
2491 struct ieee80211_local *local = wiphy_priv(wiphy); 2527 struct ieee80211_local *local = wiphy_priv(wiphy);
2528 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2492 2529
2493 if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ)) 2530 switch (frame_type) {
2494 return; 2531 case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH:
2532 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
2533 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
2495 2534
2496 if (reg) 2535 if (reg)
2497 local->probe_req_reg++; 2536 ifibss->auth_frame_registrations++;
2498 else 2537 else
2499 local->probe_req_reg--; 2538 ifibss->auth_frame_registrations--;
2539 }
2540 break;
2541 case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ:
2542 if (reg)
2543 local->probe_req_reg++;
2544 else
2545 local->probe_req_reg--;
2500 2546
2501 ieee80211_queue_work(&local->hw, &local->reconfig_filter); 2547 ieee80211_queue_work(&local->hw, &local->reconfig_filter);
2548 break;
2549 default:
2550 break;
2551 }
2502} 2552}
2503 2553
2504static int ieee80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant) 2554static int ieee80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant)
@@ -2724,9 +2774,8 @@ static int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
2724 !sdata->u.mgd.associated) 2774 !sdata->u.mgd.associated)
2725 return -EINVAL; 2775 return -EINVAL;
2726 2776
2727#ifdef CONFIG_MAC80211_VERBOSE_TDLS_DEBUG 2777 tdls_dbg(sdata, "TDLS mgmt action %d peer %pM\n",
2728 pr_debug("TDLS mgmt action %d peer %pM\n", action_code, peer); 2778 action_code, peer);
2729#endif
2730 2779
2731 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 2780 skb = dev_alloc_skb(local->hw.extra_tx_headroom +
2732 max(sizeof(struct ieee80211_mgmt), 2781 max(sizeof(struct ieee80211_mgmt),
@@ -2835,9 +2884,7 @@ static int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
2835 if (sdata->vif.type != NL80211_IFTYPE_STATION) 2884 if (sdata->vif.type != NL80211_IFTYPE_STATION)
2836 return -EINVAL; 2885 return -EINVAL;
2837 2886
2838#ifdef CONFIG_MAC80211_VERBOSE_TDLS_DEBUG 2887 tdls_dbg(sdata, "TDLS oper %d peer %pM\n", oper, peer);
2839 pr_debug("TDLS oper %d peer %pM\n", oper, peer);
2840#endif
2841 2888
2842 switch (oper) { 2889 switch (oper) {
2843 case NL80211_TDLS_ENABLE_LINK: 2890 case NL80211_TDLS_ENABLE_LINK: