aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2012-06-22 14:39:53 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-06-22 14:39:53 -0400
commit133189a46c2c522eb4ef26b1ede63dd0a9fdc920 (patch)
tree04ab3567c3bea31503c4dfa94909f99dc4b3789f /net/mac80211
parentf761b6947dde42890beea59b020e1be87491809e (diff)
parent0f6b3f597daab2254614e2773e322e73fb1b6f4b (diff)
Merge branch 'for-john' of git://git.sipsolutions.net/mac80211-next
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/cfg.c75
-rw-r--r--net/mac80211/debugfs_netdev.c43
-rw-r--r--net/mac80211/ibss.c2
-rw-r--r--net/mac80211/ieee80211_i.h19
-rw-r--r--net/mac80211/iface.c2
-rw-r--r--net/mac80211/main.c11
-rw-r--r--net/mac80211/mesh.c12
-rw-r--r--net/mac80211/mesh.h4
-rw-r--r--net/mac80211/mesh_hwmp.c126
-rw-r--r--net/mac80211/mlme.c16
-rw-r--r--net/mac80211/offchannel.c20
-rw-r--r--net/mac80211/pm.c10
-rw-r--r--net/mac80211/rx.c6
-rw-r--r--net/mac80211/util.c3
-rw-r--r--net/mac80211/wme.c11
-rw-r--r--net/mac80211/wme.h2
16 files changed, 258 insertions, 104 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 85ac364f4636..d197dbeef9ce 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -689,7 +689,8 @@ static int ieee80211_set_channel(struct wiphy *wiphy,
689 case CHAN_MODE_HOPPING: 689 case CHAN_MODE_HOPPING:
690 return -EBUSY; 690 return -EBUSY;
691 case CHAN_MODE_FIXED: 691 case CHAN_MODE_FIXED:
692 if (local->oper_channel != chan) 692 if (local->oper_channel != chan ||
693 (!sdata && local->_oper_channel_type != channel_type))
693 return -EBUSY; 694 return -EBUSY;
694 if (!sdata && local->_oper_channel_type == channel_type) 695 if (!sdata && local->_oper_channel_type == channel_type)
695 return 0; 696 return 0;
@@ -1529,7 +1530,7 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy,
1529 if (_chg_mesh_attr(NL80211_MESHCONF_TTL, mask)) 1530 if (_chg_mesh_attr(NL80211_MESHCONF_TTL, mask))
1530 conf->dot11MeshTTL = nconf->dot11MeshTTL; 1531 conf->dot11MeshTTL = nconf->dot11MeshTTL;
1531 if (_chg_mesh_attr(NL80211_MESHCONF_ELEMENT_TTL, mask)) 1532 if (_chg_mesh_attr(NL80211_MESHCONF_ELEMENT_TTL, mask))
1532 conf->dot11MeshTTL = nconf->element_ttl; 1533 conf->element_ttl = nconf->element_ttl;
1533 if (_chg_mesh_attr(NL80211_MESHCONF_AUTO_OPEN_PLINKS, mask)) 1534 if (_chg_mesh_attr(NL80211_MESHCONF_AUTO_OPEN_PLINKS, mask))
1534 conf->auto_open_plinks = nconf->auto_open_plinks; 1535 conf->auto_open_plinks = nconf->auto_open_plinks;
1535 if (_chg_mesh_attr(NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR, mask)) 1536 if (_chg_mesh_attr(NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR, mask))
@@ -1564,17 +1565,16 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy,
1564 * announcements, so require this ifmsh to also be a root node 1565 * announcements, so require this ifmsh to also be a root node
1565 * */ 1566 * */
1566 if (nconf->dot11MeshGateAnnouncementProtocol && 1567 if (nconf->dot11MeshGateAnnouncementProtocol &&
1567 !conf->dot11MeshHWMPRootMode) { 1568 !(conf->dot11MeshHWMPRootMode > IEEE80211_ROOTMODE_ROOT)) {
1568 conf->dot11MeshHWMPRootMode = 1; 1569 conf->dot11MeshHWMPRootMode = IEEE80211_PROACTIVE_RANN;
1569 ieee80211_mesh_root_setup(ifmsh); 1570 ieee80211_mesh_root_setup(ifmsh);
1570 } 1571 }
1571 conf->dot11MeshGateAnnouncementProtocol = 1572 conf->dot11MeshGateAnnouncementProtocol =
1572 nconf->dot11MeshGateAnnouncementProtocol; 1573 nconf->dot11MeshGateAnnouncementProtocol;
1573 } 1574 }
1574 if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_RANN_INTERVAL, mask)) { 1575 if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_RANN_INTERVAL, mask))
1575 conf->dot11MeshHWMPRannInterval = 1576 conf->dot11MeshHWMPRannInterval =
1576 nconf->dot11MeshHWMPRannInterval; 1577 nconf->dot11MeshHWMPRannInterval;
1577 }
1578 if (_chg_mesh_attr(NL80211_MESHCONF_FORWARDING, mask)) 1578 if (_chg_mesh_attr(NL80211_MESHCONF_FORWARDING, mask))
1579 conf->dot11MeshForwarding = nconf->dot11MeshForwarding; 1579 conf->dot11MeshForwarding = nconf->dot11MeshForwarding;
1580 if (_chg_mesh_attr(NL80211_MESHCONF_RSSI_THRESHOLD, mask)) { 1580 if (_chg_mesh_attr(NL80211_MESHCONF_RSSI_THRESHOLD, mask)) {
@@ -1590,6 +1590,15 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy,
1590 sdata->vif.bss_conf.ht_operation_mode = nconf->ht_opmode; 1590 sdata->vif.bss_conf.ht_operation_mode = nconf->ht_opmode;
1591 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_HT); 1591 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_HT);
1592 } 1592 }
1593 if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT, mask))
1594 conf->dot11MeshHWMPactivePathToRootTimeout =
1595 nconf->dot11MeshHWMPactivePathToRootTimeout;
1596 if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_ROOT_INTERVAL, mask))
1597 conf->dot11MeshHWMProotInterval =
1598 nconf->dot11MeshHWMProotInterval;
1599 if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL, mask))
1600 conf->dot11MeshHWMPconfirmationInterval =
1601 nconf->dot11MeshHWMPconfirmationInterval;
1593 return 0; 1602 return 0;
1594} 1603}
1595 1604
@@ -2309,6 +2318,21 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local,
2309 2318
2310 mutex_lock(&local->mtx); 2319 mutex_lock(&local->mtx);
2311 list_for_each_entry_safe(roc, tmp, &local->roc_list, list) { 2320 list_for_each_entry_safe(roc, tmp, &local->roc_list, list) {
2321 struct ieee80211_roc_work *dep, *tmp2;
2322
2323 list_for_each_entry_safe(dep, tmp2, &roc->dependents, list) {
2324 if (!mgmt_tx && (unsigned long)dep != cookie)
2325 continue;
2326 else if (mgmt_tx && dep->mgmt_tx_cookie != cookie)
2327 continue;
2328 /* found dependent item -- just remove it */
2329 list_del(&dep->list);
2330 mutex_unlock(&local->mtx);
2331
2332 ieee80211_roc_notify_destroy(dep);
2333 return 0;
2334 }
2335
2312 if (!mgmt_tx && (unsigned long)roc != cookie) 2336 if (!mgmt_tx && (unsigned long)roc != cookie)
2313 continue; 2337 continue;
2314 else if (mgmt_tx && roc->mgmt_tx_cookie != cookie) 2338 else if (mgmt_tx && roc->mgmt_tx_cookie != cookie)
@@ -2323,6 +2347,13 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local,
2323 return -ENOENT; 2347 return -ENOENT;
2324 } 2348 }
2325 2349
2350 /*
2351 * We found the item to cancel, so do that. Note that it
2352 * may have dependents, which we also cancel (and send
2353 * the expired signal for.) Not doing so would be quite
2354 * tricky here, but we may need to fix it later.
2355 */
2356
2326 if (local->ops->remain_on_channel) { 2357 if (local->ops->remain_on_channel) {
2327 if (found->started) { 2358 if (found->started) {
2328 ret = drv_cancel_remain_on_channel(local); 2359 ret = drv_cancel_remain_on_channel(local);
@@ -2334,8 +2365,8 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local,
2334 2365
2335 list_del(&found->list); 2366 list_del(&found->list);
2336 2367
2337 ieee80211_run_deferred_scan(local); 2368 if (found->started)
2338 ieee80211_start_next_roc(local); 2369 ieee80211_start_next_roc(local);
2339 mutex_unlock(&local->mtx); 2370 mutex_unlock(&local->mtx);
2340 2371
2341 ieee80211_roc_notify_destroy(found); 2372 ieee80211_roc_notify_destroy(found);
@@ -2489,16 +2520,30 @@ static void ieee80211_mgmt_frame_register(struct wiphy *wiphy,
2489 u16 frame_type, bool reg) 2520 u16 frame_type, bool reg)
2490{ 2521{
2491 struct ieee80211_local *local = wiphy_priv(wiphy); 2522 struct ieee80211_local *local = wiphy_priv(wiphy);
2523 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2492 2524
2493 if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ)) 2525 switch (frame_type) {
2494 return; 2526 case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH:
2527 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
2528 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
2495 2529
2496 if (reg) 2530 if (reg)
2497 local->probe_req_reg++; 2531 ifibss->auth_frame_registrations++;
2498 else 2532 else
2499 local->probe_req_reg--; 2533 ifibss->auth_frame_registrations--;
2534 }
2535 break;
2536 case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ:
2537 if (reg)
2538 local->probe_req_reg++;
2539 else
2540 local->probe_req_reg--;
2500 2541
2501 ieee80211_queue_work(&local->hw, &local->reconfig_filter); 2542 ieee80211_queue_work(&local->hw, &local->reconfig_filter);
2543 break;
2544 default:
2545 break;
2546 }
2502} 2547}
2503 2548
2504static int ieee80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant) 2549static int ieee80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant)
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index d4272ff43f71..512c894893d6 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -468,48 +468,54 @@ IEEE80211_IF_FILE(fwded_unicast, u.mesh.mshstats.fwded_unicast, DEC);
468IEEE80211_IF_FILE(fwded_frames, u.mesh.mshstats.fwded_frames, DEC); 468IEEE80211_IF_FILE(fwded_frames, u.mesh.mshstats.fwded_frames, DEC);
469IEEE80211_IF_FILE(dropped_frames_ttl, u.mesh.mshstats.dropped_frames_ttl, DEC); 469IEEE80211_IF_FILE(dropped_frames_ttl, u.mesh.mshstats.dropped_frames_ttl, DEC);
470IEEE80211_IF_FILE(dropped_frames_congestion, 470IEEE80211_IF_FILE(dropped_frames_congestion,
471 u.mesh.mshstats.dropped_frames_congestion, DEC); 471 u.mesh.mshstats.dropped_frames_congestion, DEC);
472IEEE80211_IF_FILE(dropped_frames_no_route, 472IEEE80211_IF_FILE(dropped_frames_no_route,
473 u.mesh.mshstats.dropped_frames_no_route, DEC); 473 u.mesh.mshstats.dropped_frames_no_route, DEC);
474IEEE80211_IF_FILE(estab_plinks, u.mesh.mshstats.estab_plinks, ATOMIC); 474IEEE80211_IF_FILE(estab_plinks, u.mesh.mshstats.estab_plinks, ATOMIC);
475 475
476/* Mesh parameters */ 476/* Mesh parameters */
477IEEE80211_IF_FILE(dot11MeshMaxRetries, 477IEEE80211_IF_FILE(dot11MeshMaxRetries,
478 u.mesh.mshcfg.dot11MeshMaxRetries, DEC); 478 u.mesh.mshcfg.dot11MeshMaxRetries, DEC);
479IEEE80211_IF_FILE(dot11MeshRetryTimeout, 479IEEE80211_IF_FILE(dot11MeshRetryTimeout,
480 u.mesh.mshcfg.dot11MeshRetryTimeout, DEC); 480 u.mesh.mshcfg.dot11MeshRetryTimeout, DEC);
481IEEE80211_IF_FILE(dot11MeshConfirmTimeout, 481IEEE80211_IF_FILE(dot11MeshConfirmTimeout,
482 u.mesh.mshcfg.dot11MeshConfirmTimeout, DEC); 482 u.mesh.mshcfg.dot11MeshConfirmTimeout, DEC);
483IEEE80211_IF_FILE(dot11MeshHoldingTimeout, 483IEEE80211_IF_FILE(dot11MeshHoldingTimeout,
484 u.mesh.mshcfg.dot11MeshHoldingTimeout, DEC); 484 u.mesh.mshcfg.dot11MeshHoldingTimeout, DEC);
485IEEE80211_IF_FILE(dot11MeshTTL, u.mesh.mshcfg.dot11MeshTTL, DEC); 485IEEE80211_IF_FILE(dot11MeshTTL, u.mesh.mshcfg.dot11MeshTTL, DEC);
486IEEE80211_IF_FILE(element_ttl, u.mesh.mshcfg.element_ttl, DEC); 486IEEE80211_IF_FILE(element_ttl, u.mesh.mshcfg.element_ttl, DEC);
487IEEE80211_IF_FILE(auto_open_plinks, u.mesh.mshcfg.auto_open_plinks, DEC); 487IEEE80211_IF_FILE(auto_open_plinks, u.mesh.mshcfg.auto_open_plinks, DEC);
488IEEE80211_IF_FILE(dot11MeshMaxPeerLinks, 488IEEE80211_IF_FILE(dot11MeshMaxPeerLinks,
489 u.mesh.mshcfg.dot11MeshMaxPeerLinks, DEC); 489 u.mesh.mshcfg.dot11MeshMaxPeerLinks, DEC);
490IEEE80211_IF_FILE(dot11MeshHWMPactivePathTimeout, 490IEEE80211_IF_FILE(dot11MeshHWMPactivePathTimeout,
491 u.mesh.mshcfg.dot11MeshHWMPactivePathTimeout, DEC); 491 u.mesh.mshcfg.dot11MeshHWMPactivePathTimeout, DEC);
492IEEE80211_IF_FILE(dot11MeshHWMPpreqMinInterval, 492IEEE80211_IF_FILE(dot11MeshHWMPpreqMinInterval,
493 u.mesh.mshcfg.dot11MeshHWMPpreqMinInterval, DEC); 493 u.mesh.mshcfg.dot11MeshHWMPpreqMinInterval, DEC);
494IEEE80211_IF_FILE(dot11MeshHWMPperrMinInterval, 494IEEE80211_IF_FILE(dot11MeshHWMPperrMinInterval,
495 u.mesh.mshcfg.dot11MeshHWMPperrMinInterval, DEC); 495 u.mesh.mshcfg.dot11MeshHWMPperrMinInterval, DEC);
496IEEE80211_IF_FILE(dot11MeshHWMPnetDiameterTraversalTime, 496IEEE80211_IF_FILE(dot11MeshHWMPnetDiameterTraversalTime,
497 u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime, DEC); 497 u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime, DEC);
498IEEE80211_IF_FILE(dot11MeshHWMPmaxPREQretries, 498IEEE80211_IF_FILE(dot11MeshHWMPmaxPREQretries,
499 u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries, DEC); 499 u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries, DEC);
500IEEE80211_IF_FILE(path_refresh_time, 500IEEE80211_IF_FILE(path_refresh_time,
501 u.mesh.mshcfg.path_refresh_time, DEC); 501 u.mesh.mshcfg.path_refresh_time, DEC);
502IEEE80211_IF_FILE(min_discovery_timeout, 502IEEE80211_IF_FILE(min_discovery_timeout,
503 u.mesh.mshcfg.min_discovery_timeout, DEC); 503 u.mesh.mshcfg.min_discovery_timeout, DEC);
504IEEE80211_IF_FILE(dot11MeshHWMPRootMode, 504IEEE80211_IF_FILE(dot11MeshHWMPRootMode,
505 u.mesh.mshcfg.dot11MeshHWMPRootMode, DEC); 505 u.mesh.mshcfg.dot11MeshHWMPRootMode, DEC);
506IEEE80211_IF_FILE(dot11MeshGateAnnouncementProtocol, 506IEEE80211_IF_FILE(dot11MeshGateAnnouncementProtocol,
507 u.mesh.mshcfg.dot11MeshGateAnnouncementProtocol, DEC); 507 u.mesh.mshcfg.dot11MeshGateAnnouncementProtocol, DEC);
508IEEE80211_IF_FILE(dot11MeshHWMPRannInterval, 508IEEE80211_IF_FILE(dot11MeshHWMPRannInterval,
509 u.mesh.mshcfg.dot11MeshHWMPRannInterval, DEC); 509 u.mesh.mshcfg.dot11MeshHWMPRannInterval, DEC);
510IEEE80211_IF_FILE(dot11MeshForwarding, u.mesh.mshcfg.dot11MeshForwarding, DEC); 510IEEE80211_IF_FILE(dot11MeshForwarding, u.mesh.mshcfg.dot11MeshForwarding, DEC);
511IEEE80211_IF_FILE(rssi_threshold, u.mesh.mshcfg.rssi_threshold, DEC); 511IEEE80211_IF_FILE(rssi_threshold, u.mesh.mshcfg.rssi_threshold, DEC);
512IEEE80211_IF_FILE(ht_opmode, u.mesh.mshcfg.ht_opmode, DEC); 512IEEE80211_IF_FILE(ht_opmode, u.mesh.mshcfg.ht_opmode, DEC);
513IEEE80211_IF_FILE(dot11MeshHWMPactivePathToRootTimeout,
514 u.mesh.mshcfg.dot11MeshHWMPactivePathToRootTimeout, DEC);
515IEEE80211_IF_FILE(dot11MeshHWMProotInterval,
516 u.mesh.mshcfg.dot11MeshHWMProotInterval, DEC);
517IEEE80211_IF_FILE(dot11MeshHWMPconfirmationInterval,
518 u.mesh.mshcfg.dot11MeshHWMPconfirmationInterval, DEC);
513#endif 519#endif
514 520
515#define DEBUGFS_ADD_MODE(name, mode) \ 521#define DEBUGFS_ADD_MODE(name, mode) \
@@ -611,6 +617,9 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata)
611 MESHPARAMS_ADD(dot11MeshGateAnnouncementProtocol); 617 MESHPARAMS_ADD(dot11MeshGateAnnouncementProtocol);
612 MESHPARAMS_ADD(rssi_threshold); 618 MESHPARAMS_ADD(rssi_threshold);
613 MESHPARAMS_ADD(ht_opmode); 619 MESHPARAMS_ADD(ht_opmode);
620 MESHPARAMS_ADD(dot11MeshHWMPactivePathToRootTimeout);
621 MESHPARAMS_ADD(dot11MeshHWMProotInterval);
622 MESHPARAMS_ADD(dot11MeshHWMPconfirmationInterval);
614#undef MESHPARAMS_ADD 623#undef MESHPARAMS_ADD
615} 624}
616#endif 625#endif
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 725cb4be229d..ff46ff424941 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -279,7 +279,7 @@ static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta,
279 /* If it fails, maybe we raced another insertion? */ 279 /* If it fails, maybe we raced another insertion? */
280 if (sta_info_insert_rcu(sta)) 280 if (sta_info_insert_rcu(sta))
281 return sta_info_get(sdata, addr); 281 return sta_info_get(sdata, addr);
282 if (auth) { 282 if (auth && !sdata->u.ibss.auth_frame_registrations) {
283 ibss_vdbg("TX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=1)\n", 283 ibss_vdbg("TX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=1)\n",
284 sdata->vif.addr, sdata->u.ibss.bssid, addr); 284 sdata->vif.addr, sdata->u.ibss.bssid, addr);
285 ieee80211_send_auth(sdata, 1, WLAN_AUTH_OPEN, NULL, 0, 285 ieee80211_send_auth(sdata, 1, WLAN_AUTH_OPEN, NULL, 0,
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index e6cbf5b68c89..36ce2bb066bf 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -55,11 +55,14 @@ struct ieee80211_local;
55#define TU_TO_JIFFIES(x) (usecs_to_jiffies((x) * 1024)) 55#define TU_TO_JIFFIES(x) (usecs_to_jiffies((x) * 1024))
56#define TU_TO_EXP_TIME(x) (jiffies + TU_TO_JIFFIES(x)) 56#define TU_TO_EXP_TIME(x) (jiffies + TU_TO_JIFFIES(x))
57 57
58/*
59 * Some APs experience problems when working with U-APSD. Decrease the
60 * probability of that happening by using legacy mode for all ACs but VO.
61 * The AP that caused us trouble was a Cisco 4410N. It ignores our
62 * setting, and always treats non-VO ACs as legacy.
63 */
58#define IEEE80211_DEFAULT_UAPSD_QUEUES \ 64#define IEEE80211_DEFAULT_UAPSD_QUEUES \
59 (IEEE80211_WMM_IE_STA_QOSINFO_AC_BK | \ 65 IEEE80211_WMM_IE_STA_QOSINFO_AC_VO
60 IEEE80211_WMM_IE_STA_QOSINFO_AC_BE | \
61 IEEE80211_WMM_IE_STA_QOSINFO_AC_VI | \
62 IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
63 66
64#define IEEE80211_DEFAULT_MAX_SP_LEN \ 67#define IEEE80211_DEFAULT_MAX_SP_LEN \
65 IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL 68 IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL
@@ -508,6 +511,7 @@ struct ieee80211_if_ibss {
508 bool privacy; 511 bool privacy;
509 512
510 bool control_port; 513 bool control_port;
514 unsigned int auth_frame_registrations;
511 515
512 u8 bssid[ETH_ALEN] __aligned(2); 516 u8 bssid[ETH_ALEN] __aligned(2);
513 u8 ssid[IEEE80211_MAX_SSID_LEN]; 517 u8 ssid[IEEE80211_MAX_SSID_LEN];
@@ -677,6 +681,9 @@ struct ieee80211_sub_if_data {
677 /* TID bitmap for NoAck policy */ 681 /* TID bitmap for NoAck policy */
678 u16 noack_map; 682 u16 noack_map;
679 683
684 /* bit field of ACM bits (BIT(802.1D tag)) */
685 u8 wmm_acm;
686
680 struct ieee80211_key __rcu *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS]; 687 struct ieee80211_key __rcu *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS];
681 struct ieee80211_key __rcu *default_unicast_key; 688 struct ieee80211_key __rcu *default_unicast_key;
682 struct ieee80211_key __rcu *default_multicast_key; 689 struct ieee80211_key __rcu *default_multicast_key;
@@ -881,6 +888,9 @@ struct ieee80211_local {
881 /* device is started */ 888 /* device is started */
882 bool started; 889 bool started;
883 890
891 /* device is during a HW reconfig */
892 bool in_reconfig;
893
884 /* wowlan is enabled -- don't reconfig on resume */ 894 /* wowlan is enabled -- don't reconfig on resume */
885 bool wowlan; 895 bool wowlan;
886 896
@@ -1019,7 +1029,6 @@ struct ieee80211_local {
1019 int total_ps_buffered; /* total number of all buffered unicast and 1029 int total_ps_buffered; /* total number of all buffered unicast and
1020 * multicast packets for power saving stations 1030 * multicast packets for power saving stations
1021 */ 1031 */
1022 unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */
1023 1032
1024 bool pspolling; 1033 bool pspolling;
1025 bool offchannel_ps_enabled; 1034 bool offchannel_ps_enabled;
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 87aeb4f21ffd..728d3eac1f59 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -808,7 +808,7 @@ static u16 ieee80211_monitor_select_queue(struct net_device *dev,
808 808
809 hdr = (void *)((u8 *)skb->data + le16_to_cpu(rtap->it_len)); 809 hdr = (void *)((u8 *)skb->data + le16_to_cpu(rtap->it_len));
810 810
811 return ieee80211_select_queue_80211(local, skb, hdr); 811 return ieee80211_select_queue_80211(sdata, skb, hdr);
812} 812}
813 813
814static const struct net_device_ops ieee80211_monitorif_ops = { 814static const struct net_device_ops ieee80211_monitorif_ops = {
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index d81c178c7712..0b040fb73673 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -345,6 +345,13 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw)
345 ieee80211_stop_queues_by_reason(hw, 345 ieee80211_stop_queues_by_reason(hw,
346 IEEE80211_QUEUE_STOP_REASON_SUSPEND); 346 IEEE80211_QUEUE_STOP_REASON_SUSPEND);
347 347
348 /*
349 * Stop all Rx during the reconfig. We don't want state changes
350 * or driver callbacks while this is in progress.
351 */
352 local->in_reconfig = true;
353 barrier();
354
348 schedule_work(&local->restart_work); 355 schedule_work(&local->restart_work);
349} 356}
350EXPORT_SYMBOL(ieee80211_restart_hw); 357EXPORT_SYMBOL(ieee80211_restart_hw);
@@ -455,7 +462,9 @@ static const struct ieee80211_txrx_stypes
455ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { 462ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
456 [NL80211_IFTYPE_ADHOC] = { 463 [NL80211_IFTYPE_ADHOC] = {
457 .tx = 0xffff, 464 .tx = 0xffff,
458 .rx = BIT(IEEE80211_STYPE_ACTION >> 4), 465 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
466 BIT(IEEE80211_STYPE_AUTH >> 4) |
467 BIT(IEEE80211_STYPE_DEAUTH >> 4),
459 }, 468 },
460 [NL80211_IFTYPE_STATION] = { 469 [NL80211_IFTYPE_STATION] = {
461 .tx = 0xffff, 470 .tx = 0xffff,
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 7cf19509fb68..ae40a83675e9 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -443,7 +443,7 @@ static void ieee80211_mesh_path_root_timer(unsigned long data)
443 443
444void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh) 444void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh)
445{ 445{
446 if (ifmsh->mshcfg.dot11MeshHWMPRootMode) 446 if (ifmsh->mshcfg.dot11MeshHWMPRootMode > IEEE80211_ROOTMODE_ROOT)
447 set_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags); 447 set_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags);
448 else { 448 else {
449 clear_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags); 449 clear_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags);
@@ -541,11 +541,17 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata,
541static void ieee80211_mesh_rootpath(struct ieee80211_sub_if_data *sdata) 541static void ieee80211_mesh_rootpath(struct ieee80211_sub_if_data *sdata)
542{ 542{
543 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 543 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
544 u32 interval;
544 545
545 mesh_path_tx_root_frame(sdata); 546 mesh_path_tx_root_frame(sdata);
547
548 if (ifmsh->mshcfg.dot11MeshHWMPRootMode == IEEE80211_PROACTIVE_RANN)
549 interval = ifmsh->mshcfg.dot11MeshHWMPRannInterval;
550 else
551 interval = ifmsh->mshcfg.dot11MeshHWMProotInterval;
552
546 mod_timer(&ifmsh->mesh_path_root_timer, 553 mod_timer(&ifmsh->mesh_path_root_timer,
547 round_jiffies(TU_TO_EXP_TIME( 554 round_jiffies(TU_TO_EXP_TIME(interval)));
548 ifmsh->mshcfg.dot11MeshHWMPRannInterval)));
549} 555}
550 556
551#ifdef CONFIG_PM 557#ifdef CONFIG_PM
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index e3642756f8f4..faaa39bcfd10 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -104,6 +104,7 @@ enum mesh_deferred_task_flags {
104 * an mpath to a hash bucket on a path table. 104 * an mpath to a hash bucket on a path table.
105 * @rann_snd_addr: the RANN sender address 105 * @rann_snd_addr: the RANN sender address
106 * @rann_metric: the aggregated path metric towards the root node 106 * @rann_metric: the aggregated path metric towards the root node
107 * @last_preq_to_root: Timestamp of last PREQ sent to root
107 * @is_root: the destination station of this path is a root node 108 * @is_root: the destination station of this path is a root node
108 * @is_gate: the destination station of this path is a mesh gate 109 * @is_gate: the destination station of this path is a mesh gate
109 * 110 *
@@ -131,6 +132,7 @@ struct mesh_path {
131 spinlock_t state_lock; 132 spinlock_t state_lock;
132 u8 rann_snd_addr[ETH_ALEN]; 133 u8 rann_snd_addr[ETH_ALEN];
133 u32 rann_metric; 134 u32 rann_metric;
135 unsigned long last_preq_to_root;
134 bool is_root; 136 bool is_root;
135 bool is_gate; 137 bool is_gate;
136}; 138};
@@ -245,7 +247,7 @@ void mesh_rmc_free(struct ieee80211_sub_if_data *sdata);
245int mesh_rmc_init(struct ieee80211_sub_if_data *sdata); 247int mesh_rmc_init(struct ieee80211_sub_if_data *sdata);
246void ieee80211s_init(void); 248void ieee80211s_init(void);
247void ieee80211s_update_metric(struct ieee80211_local *local, 249void ieee80211s_update_metric(struct ieee80211_local *local,
248 struct sta_info *stainfo, struct sk_buff *skb); 250 struct sta_info *sta, struct sk_buff *skb);
249void ieee80211s_stop(void); 251void ieee80211s_stop(void);
250void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata); 252void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata);
251void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata); 253void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata);
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index fa7c58035246..aed1821bd6f1 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -98,6 +98,8 @@ static inline u32 u16_field_get(u8 *preq_elem, int offset, bool ae)
98#define max_preq_retries(s) (s->u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries) 98#define max_preq_retries(s) (s->u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries)
99#define disc_timeout_jiff(s) \ 99#define disc_timeout_jiff(s) \
100 msecs_to_jiffies(sdata->u.mesh.mshcfg.min_discovery_timeout) 100 msecs_to_jiffies(sdata->u.mesh.mshcfg.min_discovery_timeout)
101#define root_path_confirmation_jiffies(s) \
102 msecs_to_jiffies(sdata->u.mesh.mshcfg.dot11MeshHWMPconfirmationInterval)
101 103
102enum mpath_frame_type { 104enum mpath_frame_type {
103 MPATH_PREQ = 0, 105 MPATH_PREQ = 0,
@@ -303,7 +305,7 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn,
303} 305}
304 306
305void ieee80211s_update_metric(struct ieee80211_local *local, 307void ieee80211s_update_metric(struct ieee80211_local *local,
306 struct sta_info *stainfo, struct sk_buff *skb) 308 struct sta_info *sta, struct sk_buff *skb)
307{ 309{
308 struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb); 310 struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
309 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 311 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
@@ -315,15 +317,14 @@ void ieee80211s_update_metric(struct ieee80211_local *local,
315 failed = !(txinfo->flags & IEEE80211_TX_STAT_ACK); 317 failed = !(txinfo->flags & IEEE80211_TX_STAT_ACK);
316 318
317 /* moving average, scaled to 100 */ 319 /* moving average, scaled to 100 */
318 stainfo->fail_avg = ((80 * stainfo->fail_avg + 5) / 100 + 20 * failed); 320 sta->fail_avg = ((80 * sta->fail_avg + 5) / 100 + 20 * failed);
319 if (stainfo->fail_avg > 95) 321 if (sta->fail_avg > 95)
320 mesh_plink_broken(stainfo); 322 mesh_plink_broken(sta);
321} 323}
322 324
323static u32 airtime_link_metric_get(struct ieee80211_local *local, 325static u32 airtime_link_metric_get(struct ieee80211_local *local,
324 struct sta_info *sta) 326 struct sta_info *sta)
325{ 327{
326 struct ieee80211_supported_band *sband;
327 struct rate_info rinfo; 328 struct rate_info rinfo;
328 /* This should be adjusted for each device */ 329 /* This should be adjusted for each device */
329 int device_constant = 1 << ARITH_SHIFT; 330 int device_constant = 1 << ARITH_SHIFT;
@@ -333,8 +334,6 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local,
333 u32 tx_time, estimated_retx; 334 u32 tx_time, estimated_retx;
334 u64 result; 335 u64 result;
335 336
336 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
337
338 if (sta->fail_avg >= 100) 337 if (sta->fail_avg >= 100)
339 return MAX_METRIC; 338 return MAX_METRIC;
340 339
@@ -519,10 +518,11 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
519 struct mesh_path *mpath = NULL; 518 struct mesh_path *mpath = NULL;
520 u8 *target_addr, *orig_addr; 519 u8 *target_addr, *orig_addr;
521 const u8 *da; 520 const u8 *da;
522 u8 target_flags, ttl; 521 u8 target_flags, ttl, flags;
523 u32 orig_sn, target_sn, lifetime; 522 u32 orig_sn, target_sn, lifetime, orig_metric;
524 bool reply = false; 523 bool reply = false;
525 bool forward = true; 524 bool forward = true;
525 bool root_is_gate;
526 526
527 /* Update target SN, if present */ 527 /* Update target SN, if present */
528 target_addr = PREQ_IE_TARGET_ADDR(preq_elem); 528 target_addr = PREQ_IE_TARGET_ADDR(preq_elem);
@@ -530,6 +530,10 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
530 target_sn = PREQ_IE_TARGET_SN(preq_elem); 530 target_sn = PREQ_IE_TARGET_SN(preq_elem);
531 orig_sn = PREQ_IE_ORIG_SN(preq_elem); 531 orig_sn = PREQ_IE_ORIG_SN(preq_elem);
532 target_flags = PREQ_IE_TARGET_F(preq_elem); 532 target_flags = PREQ_IE_TARGET_F(preq_elem);
533 orig_metric = metric;
534 /* Proactive PREQ gate announcements */
535 flags = PREQ_IE_FLAGS(preq_elem);
536 root_is_gate = !!(flags & RANN_FLAG_IS_GATE);
533 537
534 mhwmp_dbg("received PREQ from %pM", orig_addr); 538 mhwmp_dbg("received PREQ from %pM", orig_addr);
535 539
@@ -544,6 +548,22 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
544 target_sn = ++ifmsh->sn; 548 target_sn = ++ifmsh->sn;
545 ifmsh->last_sn_update = jiffies; 549 ifmsh->last_sn_update = jiffies;
546 } 550 }
551 } else if (is_broadcast_ether_addr(target_addr) &&
552 (target_flags & IEEE80211_PREQ_TO_FLAG)) {
553 rcu_read_lock();
554 mpath = mesh_path_lookup(orig_addr, sdata);
555 if (mpath) {
556 if (flags & IEEE80211_PREQ_PROACTIVE_PREP_FLAG) {
557 reply = true;
558 target_addr = sdata->vif.addr;
559 target_sn = ++ifmsh->sn;
560 metric = 0;
561 ifmsh->last_sn_update = jiffies;
562 }
563 if (root_is_gate)
564 mesh_path_add_gate(mpath);
565 }
566 rcu_read_unlock();
547 } else { 567 } else {
548 rcu_read_lock(); 568 rcu_read_lock();
549 mpath = mesh_path_lookup(target_addr, sdata); 569 mpath = mesh_path_lookup(target_addr, sdata);
@@ -576,13 +596,14 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
576 cpu_to_le32(target_sn), mgmt->sa, 0, ttl, 596 cpu_to_le32(target_sn), mgmt->sa, 0, ttl,
577 cpu_to_le32(lifetime), cpu_to_le32(metric), 597 cpu_to_le32(lifetime), cpu_to_le32(metric),
578 0, sdata); 598 0, sdata);
579 } else 599 } else {
580 ifmsh->mshstats.dropped_frames_ttl++; 600 ifmsh->mshstats.dropped_frames_ttl++;
601 }
581 } 602 }
582 603
583 if (forward && ifmsh->mshcfg.dot11MeshForwarding) { 604 if (forward && ifmsh->mshcfg.dot11MeshForwarding) {
584 u32 preq_id; 605 u32 preq_id;
585 u8 hopcount, flags; 606 u8 hopcount;
586 607
587 ttl = PREQ_IE_TTL(preq_elem); 608 ttl = PREQ_IE_TTL(preq_elem);
588 lifetime = PREQ_IE_LIFETIME(preq_elem); 609 lifetime = PREQ_IE_LIFETIME(preq_elem);
@@ -592,11 +613,17 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
592 } 613 }
593 mhwmp_dbg("forwarding the PREQ from %pM", orig_addr); 614 mhwmp_dbg("forwarding the PREQ from %pM", orig_addr);
594 --ttl; 615 --ttl;
595 flags = PREQ_IE_FLAGS(preq_elem);
596 preq_id = PREQ_IE_PREQ_ID(preq_elem); 616 preq_id = PREQ_IE_PREQ_ID(preq_elem);
597 hopcount = PREQ_IE_HOPCOUNT(preq_elem) + 1; 617 hopcount = PREQ_IE_HOPCOUNT(preq_elem) + 1;
598 da = (mpath && mpath->is_root) ? 618 da = (mpath && mpath->is_root) ?
599 mpath->rann_snd_addr : broadcast_addr; 619 mpath->rann_snd_addr : broadcast_addr;
620
621 if (flags & IEEE80211_PREQ_PROACTIVE_PREP_FLAG) {
622 target_addr = PREQ_IE_TARGET_ADDR(preq_elem);
623 target_sn = PREQ_IE_TARGET_SN(preq_elem);
624 metric = orig_metric;
625 }
626
600 mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr, 627 mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr,
601 cpu_to_le32(orig_sn), target_flags, target_addr, 628 cpu_to_le32(orig_sn), target_flags, target_addr,
602 cpu_to_le32(target_sn), da, 629 cpu_to_le32(target_sn), da,
@@ -744,11 +771,6 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
744 bool root_is_gate; 771 bool root_is_gate;
745 772
746 ttl = rann->rann_ttl; 773 ttl = rann->rann_ttl;
747 if (ttl <= 1) {
748 ifmsh->mshstats.dropped_frames_ttl++;
749 return;
750 }
751 ttl--;
752 flags = rann->rann_flags; 774 flags = rann->rann_flags;
753 root_is_gate = !!(flags & RANN_FLAG_IS_GATE); 775 root_is_gate = !!(flags & RANN_FLAG_IS_GATE);
754 orig_addr = rann->rann_addr; 776 orig_addr = rann->rann_addr;
@@ -785,34 +807,49 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
785 } 807 }
786 } 808 }
787 809
810 if (!(SN_LT(mpath->sn, orig_sn)) &&
811 !(mpath->sn == orig_sn && metric < mpath->rann_metric)) {
812 rcu_read_unlock();
813 return;
814 }
815
788 if ((!(mpath->flags & (MESH_PATH_ACTIVE | MESH_PATH_RESOLVING)) || 816 if ((!(mpath->flags & (MESH_PATH_ACTIVE | MESH_PATH_RESOLVING)) ||
789 time_after(jiffies, mpath->exp_time - 1*HZ)) && 817 (time_after(jiffies, mpath->last_preq_to_root +
790 !(mpath->flags & MESH_PATH_FIXED)) { 818 root_path_confirmation_jiffies(sdata)) ||
819 time_before(jiffies, mpath->last_preq_to_root))) &&
820 !(mpath->flags & MESH_PATH_FIXED) && (ttl != 0)) {
791 mhwmp_dbg("%s time to refresh root mpath %pM", sdata->name, 821 mhwmp_dbg("%s time to refresh root mpath %pM", sdata->name,
792 orig_addr); 822 orig_addr);
793 mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH); 823 mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH);
824 mpath->last_preq_to_root = jiffies;
825 }
826
827 mpath->sn = orig_sn;
828 mpath->rann_metric = metric + metric_txsta;
829 mpath->is_root = true;
830 /* Recording RANNs sender address to send individually
831 * addressed PREQs destined for root mesh STA */
832 memcpy(mpath->rann_snd_addr, mgmt->sa, ETH_ALEN);
833
834 if (root_is_gate)
835 mesh_path_add_gate(mpath);
836
837 if (ttl <= 1) {
838 ifmsh->mshstats.dropped_frames_ttl++;
839 rcu_read_unlock();
840 return;
794 } 841 }
842 ttl--;
795 843
796 if ((SN_LT(mpath->sn, orig_sn) || (mpath->sn == orig_sn && 844 if (ifmsh->mshcfg.dot11MeshForwarding) {
797 metric < mpath->rann_metric)) && ifmsh->mshcfg.dot11MeshForwarding) {
798 mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr, 845 mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr,
799 cpu_to_le32(orig_sn), 846 cpu_to_le32(orig_sn),
800 0, NULL, 0, broadcast_addr, 847 0, NULL, 0, broadcast_addr,
801 hopcount, ttl, cpu_to_le32(interval), 848 hopcount, ttl, cpu_to_le32(interval),
802 cpu_to_le32(metric + metric_txsta), 849 cpu_to_le32(metric + metric_txsta),
803 0, sdata); 850 0, sdata);
804 mpath->sn = orig_sn;
805 mpath->rann_metric = metric + metric_txsta;
806 /* Recording RANNs sender address to send individually
807 * addressed PREQs destined for root mesh STA */
808 memcpy(mpath->rann_snd_addr, mgmt->sa, ETH_ALEN);
809 } 851 }
810 852
811 mpath->is_root = true;
812
813 if (root_is_gate)
814 mesh_path_add_gate(mpath);
815
816 rcu_read_unlock(); 853 rcu_read_unlock();
817} 854}
818 855
@@ -1157,13 +1194,34 @@ mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata)
1157{ 1194{
1158 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 1195 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
1159 u32 interval = ifmsh->mshcfg.dot11MeshHWMPRannInterval; 1196 u32 interval = ifmsh->mshcfg.dot11MeshHWMPRannInterval;
1160 u8 flags; 1197 u8 flags, target_flags = 0;
1161 1198
1162 flags = (ifmsh->mshcfg.dot11MeshGateAnnouncementProtocol) 1199 flags = (ifmsh->mshcfg.dot11MeshGateAnnouncementProtocol)
1163 ? RANN_FLAG_IS_GATE : 0; 1200 ? RANN_FLAG_IS_GATE : 0;
1164 mesh_path_sel_frame_tx(MPATH_RANN, flags, sdata->vif.addr, 1201
1202 switch (ifmsh->mshcfg.dot11MeshHWMPRootMode) {
1203 case IEEE80211_PROACTIVE_RANN:
1204 mesh_path_sel_frame_tx(MPATH_RANN, flags, sdata->vif.addr,
1165 cpu_to_le32(++ifmsh->sn), 1205 cpu_to_le32(++ifmsh->sn),
1166 0, NULL, 0, broadcast_addr, 1206 0, NULL, 0, broadcast_addr,
1167 0, sdata->u.mesh.mshcfg.element_ttl, 1207 0, ifmsh->mshcfg.element_ttl,
1168 cpu_to_le32(interval), 0, 0, sdata); 1208 cpu_to_le32(interval), 0, 0, sdata);
1209 break;
1210 case IEEE80211_PROACTIVE_PREQ_WITH_PREP:
1211 flags |= IEEE80211_PREQ_PROACTIVE_PREP_FLAG;
1212 case IEEE80211_PROACTIVE_PREQ_NO_PREP:
1213 interval = ifmsh->mshcfg.dot11MeshHWMPactivePathToRootTimeout;
1214 target_flags |= IEEE80211_PREQ_TO_FLAG |
1215 IEEE80211_PREQ_USN_FLAG;
1216 mesh_path_sel_frame_tx(MPATH_PREQ, flags, sdata->vif.addr,
1217 cpu_to_le32(++ifmsh->sn), target_flags,
1218 (u8 *) broadcast_addr, 0, broadcast_addr,
1219 0, ifmsh->mshcfg.element_ttl,
1220 cpu_to_le32(interval),
1221 0, cpu_to_le32(ifmsh->preq_id++), sdata);
1222 break;
1223 default:
1224 mhwmp_dbg("Proactive mechanism not supported");
1225 return;
1226 }
1169} 1227}
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 079038d26a14..8149a37c93ee 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1141,7 +1141,7 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
1141 1141
1142 memset(&params, 0, sizeof(params)); 1142 memset(&params, 0, sizeof(params));
1143 1143
1144 local->wmm_acm = 0; 1144 sdata->wmm_acm = 0;
1145 for (; left >= 4; left -= 4, pos += 4) { 1145 for (; left >= 4; left -= 4, pos += 4) {
1146 int aci = (pos[0] >> 5) & 0x03; 1146 int aci = (pos[0] >> 5) & 0x03;
1147 int acm = (pos[0] >> 4) & 0x01; 1147 int acm = (pos[0] >> 4) & 0x01;
@@ -1152,21 +1152,21 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
1152 case 1: /* AC_BK */ 1152 case 1: /* AC_BK */
1153 queue = 3; 1153 queue = 3;
1154 if (acm) 1154 if (acm)
1155 local->wmm_acm |= BIT(1) | BIT(2); /* BK/- */ 1155 sdata->wmm_acm |= BIT(1) | BIT(2); /* BK/- */
1156 if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK) 1156 if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
1157 uapsd = true; 1157 uapsd = true;
1158 break; 1158 break;
1159 case 2: /* AC_VI */ 1159 case 2: /* AC_VI */
1160 queue = 1; 1160 queue = 1;
1161 if (acm) 1161 if (acm)
1162 local->wmm_acm |= BIT(4) | BIT(5); /* CL/VI */ 1162 sdata->wmm_acm |= BIT(4) | BIT(5); /* CL/VI */
1163 if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI) 1163 if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)
1164 uapsd = true; 1164 uapsd = true;
1165 break; 1165 break;
1166 case 3: /* AC_VO */ 1166 case 3: /* AC_VO */
1167 queue = 0; 1167 queue = 0;
1168 if (acm) 1168 if (acm)
1169 local->wmm_acm |= BIT(6) | BIT(7); /* VO/NC */ 1169 sdata->wmm_acm |= BIT(6) | BIT(7); /* VO/NC */
1170 if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO) 1170 if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
1171 uapsd = true; 1171 uapsd = true;
1172 break; 1172 break;
@@ -1174,7 +1174,7 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
1174 default: 1174 default:
1175 queue = 2; 1175 queue = 2;
1176 if (acm) 1176 if (acm)
1177 local->wmm_acm |= BIT(0) | BIT(3); /* BE/EE */ 1177 sdata->wmm_acm |= BIT(0) | BIT(3); /* BE/EE */
1178 if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE) 1178 if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
1179 uapsd = true; 1179 uapsd = true;
1180 break; 1180 break;
@@ -1275,7 +1275,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
1275 1275
1276 bss_info_changed |= BSS_CHANGED_BEACON_INT; 1276 bss_info_changed |= BSS_CHANGED_BEACON_INT;
1277 bss_info_changed |= ieee80211_handle_bss_capability(sdata, 1277 bss_info_changed |= ieee80211_handle_bss_capability(sdata,
1278 cbss->capability, bss->has_erp_value, bss->erp_value); 1278 bss_conf->assoc_capability, bss->has_erp_value, bss->erp_value);
1279 1279
1280 sdata->u.mgd.beacon_timeout = usecs_to_jiffies(ieee80211_tu_to_usec( 1280 sdata->u.mgd.beacon_timeout = usecs_to_jiffies(ieee80211_tu_to_usec(
1281 IEEE80211_BEACON_LOSS_COUNT * bss_conf->beacon_int)); 1281 IEEE80211_BEACON_LOSS_COUNT * bss_conf->beacon_int));
@@ -3012,7 +3012,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
3012 struct ieee80211_local *local = sdata->local; 3012 struct ieee80211_local *local = sdata->local;
3013 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 3013 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3014 struct ieee80211_bss *bss = (void *)cbss->priv; 3014 struct ieee80211_bss *bss = (void *)cbss->priv;
3015 struct sta_info *sta; 3015 struct sta_info *sta = NULL;
3016 bool have_sta = false; 3016 bool have_sta = false;
3017 int err; 3017 int err;
3018 int ht_cfreq; 3018 int ht_cfreq;
@@ -3102,7 +3102,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
3102 local->oper_channel = cbss->channel; 3102 local->oper_channel = cbss->channel;
3103 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); 3103 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
3104 3104
3105 if (!have_sta) { 3105 if (sta) {
3106 u32 rates = 0, basic_rates = 0; 3106 u32 rates = 0, basic_rates = 0;
3107 bool have_higher_than_11mbit; 3107 bool have_higher_than_11mbit;
3108 int min_rate = INT_MAX, min_rate_index = -1; 3108 int min_rate = INT_MAX, min_rate_index = -1;
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index abb226dc4753..7f93626ddc61 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -25,8 +25,7 @@
25 * because we *may* be doing work on-operating channel, and want our 25 * because we *may* be doing work on-operating channel, and want our
26 * hardware unconditionally awake, but still let the AP send us normal frames. 26 * hardware unconditionally awake, but still let the AP send us normal frames.
27 */ 27 */
28static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata, 28static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata)
29 bool tell_ap)
30{ 29{
31 struct ieee80211_local *local = sdata->local; 30 struct ieee80211_local *local = sdata->local;
32 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 31 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
@@ -47,8 +46,8 @@ static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata,
47 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 46 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
48 } 47 }
49 48
50 if (tell_ap && (!local->offchannel_ps_enabled || 49 if (!local->offchannel_ps_enabled ||
51 !(local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK))) 50 !(local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK))
52 /* 51 /*
53 * If power save was enabled, no need to send a nullfunc 52 * If power save was enabled, no need to send a nullfunc
54 * frame because AP knows that we are sleeping. But if the 53 * frame because AP knows that we are sleeping. But if the
@@ -133,7 +132,7 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local,
133 if (offchannel_ps_enable && 132 if (offchannel_ps_enable &&
134 (sdata->vif.type == NL80211_IFTYPE_STATION) && 133 (sdata->vif.type == NL80211_IFTYPE_STATION) &&
135 sdata->u.mgd.associated) 134 sdata->u.mgd.associated)
136 ieee80211_offchannel_ps_enable(sdata, true); 135 ieee80211_offchannel_ps_enable(sdata);
137 } 136 }
138 } 137 }
139 mutex_unlock(&local->iflist_mtx); 138 mutex_unlock(&local->iflist_mtx);
@@ -263,6 +262,9 @@ void ieee80211_start_next_roc(struct ieee80211_local *local)
263 roc = list_first_entry(&local->roc_list, struct ieee80211_roc_work, 262 roc = list_first_entry(&local->roc_list, struct ieee80211_roc_work,
264 list); 263 list);
265 264
265 if (WARN_ON_ONCE(roc->started))
266 return;
267
266 if (local->ops->remain_on_channel) { 268 if (local->ops->remain_on_channel) {
267 int ret, duration = roc->duration; 269 int ret, duration = roc->duration;
268 270
@@ -378,8 +380,8 @@ void ieee80211_sw_roc_work(struct work_struct *work)
378 380
379 ieee80211_recalc_idle(local); 381 ieee80211_recalc_idle(local);
380 382
381 ieee80211_start_next_roc(local); 383 if (roc->started)
382 ieee80211_run_deferred_scan(local); 384 ieee80211_start_next_roc(local);
383 } 385 }
384 386
385 out_unlock: 387 out_unlock:
@@ -410,9 +412,6 @@ static void ieee80211_hw_roc_done(struct work_struct *work)
410 /* if there's another roc, start it now */ 412 /* if there's another roc, start it now */
411 ieee80211_start_next_roc(local); 413 ieee80211_start_next_roc(local);
412 414
413 /* or scan maybe */
414 ieee80211_run_deferred_scan(local);
415
416 out_unlock: 415 out_unlock:
417 mutex_unlock(&local->mtx); 416 mutex_unlock(&local->mtx);
418} 417}
@@ -455,7 +454,6 @@ void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata)
455 } 454 }
456 455
457 ieee80211_start_next_roc(local); 456 ieee80211_start_next_roc(local);
458 ieee80211_run_deferred_scan(local);
459 mutex_unlock(&local->mtx); 457 mutex_unlock(&local->mtx);
460 458
461 list_for_each_entry_safe(roc, tmp, &tmp_list, list) { 459 list_for_each_entry_safe(roc, tmp, &tmp_list, list) {
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index 98c128be3827..5c572e7a1a71 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -78,6 +78,16 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
78 if (err < 0) { 78 if (err < 0) {
79 local->quiescing = false; 79 local->quiescing = false;
80 local->wowlan = false; 80 local->wowlan = false;
81 if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) {
82 mutex_lock(&local->sta_mtx);
83 list_for_each_entry(sta,
84 &local->sta_list, list) {
85 clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
86 }
87 mutex_unlock(&local->sta_mtx);
88 }
89 ieee80211_wake_queues_by_reason(hw,
90 IEEE80211_QUEUE_STOP_REASON_SUSPEND);
81 return err; 91 return err;
82 } else if (err > 0) { 92 } else if (err > 0) {
83 WARN_ON(err != 1); 93 WARN_ON(err != 1);
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 6fd2cb0838c4..446a327b3de0 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1935,7 +1935,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
1935 ether_addr_equal(sdata->vif.addr, hdr->addr3)) 1935 ether_addr_equal(sdata->vif.addr, hdr->addr3))
1936 return RX_CONTINUE; 1936 return RX_CONTINUE;
1937 1937
1938 q = ieee80211_select_queue_80211(local, skb, hdr); 1938 q = ieee80211_select_queue_80211(sdata, skb, hdr);
1939 if (ieee80211_queue_stopped(&local->hw, q)) { 1939 if (ieee80211_queue_stopped(&local->hw, q)) {
1940 IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_congestion); 1940 IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_congestion);
1941 return RX_DROP_MONITOR; 1941 return RX_DROP_MONITOR;
@@ -3027,6 +3027,10 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
3027 if (unlikely(local->quiescing || local->suspended)) 3027 if (unlikely(local->quiescing || local->suspended))
3028 goto drop; 3028 goto drop;
3029 3029
3030 /* We might be during a HW reconfig, prevent Rx for the same reason */
3031 if (unlikely(local->in_reconfig))
3032 goto drop;
3033
3030 /* 3034 /*
3031 * The same happens when we're not even started, 3035 * The same happens when we're not even started,
3032 * but that's worth a warning. 3036 * but that's worth a warning.
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 1df4019f294b..242ecde381f6 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1411,6 +1411,9 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1411 if (ieee80211_sdata_running(sdata)) 1411 if (ieee80211_sdata_running(sdata))
1412 ieee80211_enable_keys(sdata); 1412 ieee80211_enable_keys(sdata);
1413 1413
1414 local->in_reconfig = false;
1415 barrier();
1416
1414 wake_up: 1417 wake_up:
1415 /* 1418 /*
1416 * Clear the WLAN_STA_BLOCK_BA flag so new aggregation 1419 * Clear the WLAN_STA_BLOCK_BA flag so new aggregation
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index c3d643a6536c..cea06e9f26f4 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -52,11 +52,11 @@ static int wme_downgrade_ac(struct sk_buff *skb)
52 } 52 }
53} 53}
54 54
55static u16 ieee80211_downgrade_queue(struct ieee80211_local *local, 55static u16 ieee80211_downgrade_queue(struct ieee80211_sub_if_data *sdata,
56 struct sk_buff *skb) 56 struct sk_buff *skb)
57{ 57{
58 /* in case we are a client verify acm is not set for this ac */ 58 /* in case we are a client verify acm is not set for this ac */
59 while (unlikely(local->wmm_acm & BIT(skb->priority))) { 59 while (unlikely(sdata->wmm_acm & BIT(skb->priority))) {
60 if (wme_downgrade_ac(skb)) { 60 if (wme_downgrade_ac(skb)) {
61 /* 61 /*
62 * This should not really happen. The AP has marked all 62 * This should not really happen. The AP has marked all
@@ -73,10 +73,11 @@ static u16 ieee80211_downgrade_queue(struct ieee80211_local *local,
73} 73}
74 74
75/* Indicate which queue to use for this fully formed 802.11 frame */ 75/* Indicate which queue to use for this fully formed 802.11 frame */
76u16 ieee80211_select_queue_80211(struct ieee80211_local *local, 76u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata,
77 struct sk_buff *skb, 77 struct sk_buff *skb,
78 struct ieee80211_hdr *hdr) 78 struct ieee80211_hdr *hdr)
79{ 79{
80 struct ieee80211_local *local = sdata->local;
80 u8 *p; 81 u8 *p;
81 82
82 if (local->hw.queues < IEEE80211_NUM_ACS) 83 if (local->hw.queues < IEEE80211_NUM_ACS)
@@ -94,7 +95,7 @@ u16 ieee80211_select_queue_80211(struct ieee80211_local *local,
94 p = ieee80211_get_qos_ctl(hdr); 95 p = ieee80211_get_qos_ctl(hdr);
95 skb->priority = *p & IEEE80211_QOS_CTL_TAG1D_MASK; 96 skb->priority = *p & IEEE80211_QOS_CTL_TAG1D_MASK;
96 97
97 return ieee80211_downgrade_queue(local, skb); 98 return ieee80211_downgrade_queue(sdata, skb);
98} 99}
99 100
100/* Indicate which queue to use. */ 101/* Indicate which queue to use. */
@@ -156,7 +157,7 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
156 * data frame has */ 157 * data frame has */
157 skb->priority = cfg80211_classify8021d(skb); 158 skb->priority = cfg80211_classify8021d(skb);
158 159
159 return ieee80211_downgrade_queue(local, skb); 160 return ieee80211_downgrade_queue(sdata, skb);
160} 161}
161 162
162void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata, 163void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/wme.h b/net/mac80211/wme.h
index ca80818b7b66..7fea4bb8acbc 100644
--- a/net/mac80211/wme.h
+++ b/net/mac80211/wme.h
@@ -15,7 +15,7 @@
15 15
16extern const int ieee802_1d_to_ac[8]; 16extern const int ieee802_1d_to_ac[8];
17 17
18u16 ieee80211_select_queue_80211(struct ieee80211_local *local, 18u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata,
19 struct sk_buff *skb, 19 struct sk_buff *skb,
20 struct ieee80211_hdr *hdr); 20 struct ieee80211_hdr *hdr);
21u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, 21u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,