diff options
author | John W. Linville <linville@tuxdriver.com> | 2012-06-22 14:39:53 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-06-22 14:39:53 -0400 |
commit | 133189a46c2c522eb4ef26b1ede63dd0a9fdc920 (patch) | |
tree | 04ab3567c3bea31503c4dfa94909f99dc4b3789f /net/mac80211 | |
parent | f761b6947dde42890beea59b020e1be87491809e (diff) | |
parent | 0f6b3f597daab2254614e2773e322e73fb1b6f4b (diff) |
Merge branch 'for-john' of git://git.sipsolutions.net/mac80211-next
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/cfg.c | 75 | ||||
-rw-r--r-- | net/mac80211/debugfs_netdev.c | 43 | ||||
-rw-r--r-- | net/mac80211/ibss.c | 2 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 19 | ||||
-rw-r--r-- | net/mac80211/iface.c | 2 | ||||
-rw-r--r-- | net/mac80211/main.c | 11 | ||||
-rw-r--r-- | net/mac80211/mesh.c | 12 | ||||
-rw-r--r-- | net/mac80211/mesh.h | 4 | ||||
-rw-r--r-- | net/mac80211/mesh_hwmp.c | 126 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 16 | ||||
-rw-r--r-- | net/mac80211/offchannel.c | 20 | ||||
-rw-r--r-- | net/mac80211/pm.c | 10 | ||||
-rw-r--r-- | net/mac80211/rx.c | 6 | ||||
-rw-r--r-- | net/mac80211/util.c | 3 | ||||
-rw-r--r-- | net/mac80211/wme.c | 11 | ||||
-rw-r--r-- | net/mac80211/wme.h | 2 |
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 | ||
2504 | static int ieee80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant) | 2549 | static 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); | |||
468 | IEEE80211_IF_FILE(fwded_frames, u.mesh.mshstats.fwded_frames, DEC); | 468 | IEEE80211_IF_FILE(fwded_frames, u.mesh.mshstats.fwded_frames, DEC); |
469 | IEEE80211_IF_FILE(dropped_frames_ttl, u.mesh.mshstats.dropped_frames_ttl, DEC); | 469 | IEEE80211_IF_FILE(dropped_frames_ttl, u.mesh.mshstats.dropped_frames_ttl, DEC); |
470 | IEEE80211_IF_FILE(dropped_frames_congestion, | 470 | IEEE80211_IF_FILE(dropped_frames_congestion, |
471 | u.mesh.mshstats.dropped_frames_congestion, DEC); | 471 | u.mesh.mshstats.dropped_frames_congestion, DEC); |
472 | IEEE80211_IF_FILE(dropped_frames_no_route, | 472 | IEEE80211_IF_FILE(dropped_frames_no_route, |
473 | u.mesh.mshstats.dropped_frames_no_route, DEC); | 473 | u.mesh.mshstats.dropped_frames_no_route, DEC); |
474 | IEEE80211_IF_FILE(estab_plinks, u.mesh.mshstats.estab_plinks, ATOMIC); | 474 | IEEE80211_IF_FILE(estab_plinks, u.mesh.mshstats.estab_plinks, ATOMIC); |
475 | 475 | ||
476 | /* Mesh parameters */ | 476 | /* Mesh parameters */ |
477 | IEEE80211_IF_FILE(dot11MeshMaxRetries, | 477 | IEEE80211_IF_FILE(dot11MeshMaxRetries, |
478 | u.mesh.mshcfg.dot11MeshMaxRetries, DEC); | 478 | u.mesh.mshcfg.dot11MeshMaxRetries, DEC); |
479 | IEEE80211_IF_FILE(dot11MeshRetryTimeout, | 479 | IEEE80211_IF_FILE(dot11MeshRetryTimeout, |
480 | u.mesh.mshcfg.dot11MeshRetryTimeout, DEC); | 480 | u.mesh.mshcfg.dot11MeshRetryTimeout, DEC); |
481 | IEEE80211_IF_FILE(dot11MeshConfirmTimeout, | 481 | IEEE80211_IF_FILE(dot11MeshConfirmTimeout, |
482 | u.mesh.mshcfg.dot11MeshConfirmTimeout, DEC); | 482 | u.mesh.mshcfg.dot11MeshConfirmTimeout, DEC); |
483 | IEEE80211_IF_FILE(dot11MeshHoldingTimeout, | 483 | IEEE80211_IF_FILE(dot11MeshHoldingTimeout, |
484 | u.mesh.mshcfg.dot11MeshHoldingTimeout, DEC); | 484 | u.mesh.mshcfg.dot11MeshHoldingTimeout, DEC); |
485 | IEEE80211_IF_FILE(dot11MeshTTL, u.mesh.mshcfg.dot11MeshTTL, DEC); | 485 | IEEE80211_IF_FILE(dot11MeshTTL, u.mesh.mshcfg.dot11MeshTTL, DEC); |
486 | IEEE80211_IF_FILE(element_ttl, u.mesh.mshcfg.element_ttl, DEC); | 486 | IEEE80211_IF_FILE(element_ttl, u.mesh.mshcfg.element_ttl, DEC); |
487 | IEEE80211_IF_FILE(auto_open_plinks, u.mesh.mshcfg.auto_open_plinks, DEC); | 487 | IEEE80211_IF_FILE(auto_open_plinks, u.mesh.mshcfg.auto_open_plinks, DEC); |
488 | IEEE80211_IF_FILE(dot11MeshMaxPeerLinks, | 488 | IEEE80211_IF_FILE(dot11MeshMaxPeerLinks, |
489 | u.mesh.mshcfg.dot11MeshMaxPeerLinks, DEC); | 489 | u.mesh.mshcfg.dot11MeshMaxPeerLinks, DEC); |
490 | IEEE80211_IF_FILE(dot11MeshHWMPactivePathTimeout, | 490 | IEEE80211_IF_FILE(dot11MeshHWMPactivePathTimeout, |
491 | u.mesh.mshcfg.dot11MeshHWMPactivePathTimeout, DEC); | 491 | u.mesh.mshcfg.dot11MeshHWMPactivePathTimeout, DEC); |
492 | IEEE80211_IF_FILE(dot11MeshHWMPpreqMinInterval, | 492 | IEEE80211_IF_FILE(dot11MeshHWMPpreqMinInterval, |
493 | u.mesh.mshcfg.dot11MeshHWMPpreqMinInterval, DEC); | 493 | u.mesh.mshcfg.dot11MeshHWMPpreqMinInterval, DEC); |
494 | IEEE80211_IF_FILE(dot11MeshHWMPperrMinInterval, | 494 | IEEE80211_IF_FILE(dot11MeshHWMPperrMinInterval, |
495 | u.mesh.mshcfg.dot11MeshHWMPperrMinInterval, DEC); | 495 | u.mesh.mshcfg.dot11MeshHWMPperrMinInterval, DEC); |
496 | IEEE80211_IF_FILE(dot11MeshHWMPnetDiameterTraversalTime, | 496 | IEEE80211_IF_FILE(dot11MeshHWMPnetDiameterTraversalTime, |
497 | u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime, DEC); | 497 | u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime, DEC); |
498 | IEEE80211_IF_FILE(dot11MeshHWMPmaxPREQretries, | 498 | IEEE80211_IF_FILE(dot11MeshHWMPmaxPREQretries, |
499 | u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries, DEC); | 499 | u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries, DEC); |
500 | IEEE80211_IF_FILE(path_refresh_time, | 500 | IEEE80211_IF_FILE(path_refresh_time, |
501 | u.mesh.mshcfg.path_refresh_time, DEC); | 501 | u.mesh.mshcfg.path_refresh_time, DEC); |
502 | IEEE80211_IF_FILE(min_discovery_timeout, | 502 | IEEE80211_IF_FILE(min_discovery_timeout, |
503 | u.mesh.mshcfg.min_discovery_timeout, DEC); | 503 | u.mesh.mshcfg.min_discovery_timeout, DEC); |
504 | IEEE80211_IF_FILE(dot11MeshHWMPRootMode, | 504 | IEEE80211_IF_FILE(dot11MeshHWMPRootMode, |
505 | u.mesh.mshcfg.dot11MeshHWMPRootMode, DEC); | 505 | u.mesh.mshcfg.dot11MeshHWMPRootMode, DEC); |
506 | IEEE80211_IF_FILE(dot11MeshGateAnnouncementProtocol, | 506 | IEEE80211_IF_FILE(dot11MeshGateAnnouncementProtocol, |
507 | u.mesh.mshcfg.dot11MeshGateAnnouncementProtocol, DEC); | 507 | u.mesh.mshcfg.dot11MeshGateAnnouncementProtocol, DEC); |
508 | IEEE80211_IF_FILE(dot11MeshHWMPRannInterval, | 508 | IEEE80211_IF_FILE(dot11MeshHWMPRannInterval, |
509 | u.mesh.mshcfg.dot11MeshHWMPRannInterval, DEC); | 509 | u.mesh.mshcfg.dot11MeshHWMPRannInterval, DEC); |
510 | IEEE80211_IF_FILE(dot11MeshForwarding, u.mesh.mshcfg.dot11MeshForwarding, DEC); | 510 | IEEE80211_IF_FILE(dot11MeshForwarding, u.mesh.mshcfg.dot11MeshForwarding, DEC); |
511 | IEEE80211_IF_FILE(rssi_threshold, u.mesh.mshcfg.rssi_threshold, DEC); | 511 | IEEE80211_IF_FILE(rssi_threshold, u.mesh.mshcfg.rssi_threshold, DEC); |
512 | IEEE80211_IF_FILE(ht_opmode, u.mesh.mshcfg.ht_opmode, DEC); | 512 | IEEE80211_IF_FILE(ht_opmode, u.mesh.mshcfg.ht_opmode, DEC); |
513 | IEEE80211_IF_FILE(dot11MeshHWMPactivePathToRootTimeout, | ||
514 | u.mesh.mshcfg.dot11MeshHWMPactivePathToRootTimeout, DEC); | ||
515 | IEEE80211_IF_FILE(dot11MeshHWMProotInterval, | ||
516 | u.mesh.mshcfg.dot11MeshHWMProotInterval, DEC); | ||
517 | IEEE80211_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 | ||
814 | static const struct net_device_ops ieee80211_monitorif_ops = { | 814 | static 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 | } |
350 | EXPORT_SYMBOL(ieee80211_restart_hw); | 357 | EXPORT_SYMBOL(ieee80211_restart_hw); |
@@ -455,7 +462,9 @@ static const struct ieee80211_txrx_stypes | |||
455 | ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { | 462 | ieee80211_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 | ||
444 | void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh) | 444 | void 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, | |||
541 | static void ieee80211_mesh_rootpath(struct ieee80211_sub_if_data *sdata) | 541 | static 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); | |||
245 | int mesh_rmc_init(struct ieee80211_sub_if_data *sdata); | 247 | int mesh_rmc_init(struct ieee80211_sub_if_data *sdata); |
246 | void ieee80211s_init(void); | 248 | void ieee80211s_init(void); |
247 | void ieee80211s_update_metric(struct ieee80211_local *local, | 249 | void 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); |
249 | void ieee80211s_stop(void); | 251 | void ieee80211s_stop(void); |
250 | void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata); | 252 | void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata); |
251 | void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata); | 253 | void 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 | ||
102 | enum mpath_frame_type { | 104 | enum 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 | ||
305 | void ieee80211s_update_metric(struct ieee80211_local *local, | 307 | void 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 | ||
323 | static u32 airtime_link_metric_get(struct ieee80211_local *local, | 325 | static 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(¶ms, 0, sizeof(params)); | 1142 | memset(¶ms, 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 | */ |
28 | static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata, | 28 | static 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 | ||
55 | static u16 ieee80211_downgrade_queue(struct ieee80211_local *local, | 55 | static 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 */ |
76 | u16 ieee80211_select_queue_80211(struct ieee80211_local *local, | 76 | u16 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 | ||
162 | void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata, | 163 | void 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 | ||
16 | extern const int ieee802_1d_to_ac[8]; | 16 | extern const int ieee802_1d_to_ac[8]; |
17 | 17 | ||
18 | u16 ieee80211_select_queue_80211(struct ieee80211_local *local, | 18 | u16 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); |
21 | u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, | 21 | u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, |