diff options
Diffstat (limited to 'net/mac80211')
| -rw-r--r-- | net/mac80211/ieee80211_i.h | 1 | ||||
| -rw-r--r-- | net/mac80211/iface.c | 16 | ||||
| -rw-r--r-- | net/mac80211/mlme.c | 38 | ||||
| -rw-r--r-- | net/mac80211/scan.c | 12 | ||||
| -rw-r--r-- | net/mac80211/wme.c | 9 |
5 files changed, 53 insertions, 23 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index ecbc8e0cb3e7..fbb91f1aebb2 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
| @@ -972,6 +972,7 @@ int ieee80211_sta_set_extra_ie(struct ieee80211_sub_if_data *sdata, | |||
| 972 | char *ie, size_t len); | 972 | char *ie, size_t len); |
| 973 | 973 | ||
| 974 | void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local); | 974 | void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local); |
| 975 | void ieee80211_scan_failed(struct ieee80211_local *local); | ||
| 975 | int ieee80211_start_scan(struct ieee80211_sub_if_data *scan_sdata, | 976 | int ieee80211_start_scan(struct ieee80211_sub_if_data *scan_sdata, |
| 976 | struct cfg80211_scan_request *req); | 977 | struct cfg80211_scan_request *req); |
| 977 | struct ieee80211_bss * | 978 | struct ieee80211_bss * |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 2acc416e77e1..f9f27b9cadbe 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
| @@ -370,6 +370,18 @@ static int ieee80211_stop(struct net_device *dev) | |||
| 370 | rcu_read_unlock(); | 370 | rcu_read_unlock(); |
| 371 | 371 | ||
| 372 | /* | 372 | /* |
| 373 | * Announce that we are leaving the network, in case we are a | ||
| 374 | * station interface type. This must be done before removing | ||
| 375 | * all stations associated with sta_info_flush, otherwise STA | ||
| 376 | * information will be gone and no announce being done. | ||
| 377 | */ | ||
| 378 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { | ||
| 379 | if (sdata->u.mgd.state != IEEE80211_STA_MLME_DISABLED) | ||
| 380 | ieee80211_sta_deauthenticate(sdata, | ||
| 381 | WLAN_REASON_DEAUTH_LEAVING); | ||
| 382 | } | ||
| 383 | |||
| 384 | /* | ||
| 373 | * Remove all stations associated with this interface. | 385 | * Remove all stations associated with this interface. |
| 374 | * | 386 | * |
| 375 | * This must be done before calling ops->remove_interface() | 387 | * This must be done before calling ops->remove_interface() |
| @@ -454,10 +466,6 @@ static int ieee80211_stop(struct net_device *dev) | |||
| 454 | netif_addr_unlock_bh(local->mdev); | 466 | netif_addr_unlock_bh(local->mdev); |
| 455 | break; | 467 | break; |
| 456 | case NL80211_IFTYPE_STATION: | 468 | case NL80211_IFTYPE_STATION: |
| 457 | /* Announce that we are leaving the network. */ | ||
| 458 | if (sdata->u.mgd.state != IEEE80211_STA_MLME_DISABLED) | ||
| 459 | ieee80211_sta_deauthenticate(sdata, | ||
| 460 | WLAN_REASON_DEAUTH_LEAVING); | ||
| 461 | memset(sdata->u.mgd.bssid, 0, ETH_ALEN); | 469 | memset(sdata->u.mgd.bssid, 0, ETH_ALEN); |
| 462 | del_timer_sync(&sdata->u.mgd.chswitch_timer); | 470 | del_timer_sync(&sdata->u.mgd.chswitch_timer); |
| 463 | del_timer_sync(&sdata->u.mgd.timer); | 471 | del_timer_sync(&sdata->u.mgd.timer); |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 391445c6b892..841b8450b3de 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
| @@ -417,9 +417,6 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, | |||
| 417 | 417 | ||
| 418 | memset(¶ms, 0, sizeof(params)); | 418 | memset(¶ms, 0, sizeof(params)); |
| 419 | 419 | ||
| 420 | if (!local->ops->conf_tx) | ||
| 421 | return; | ||
| 422 | |||
| 423 | local->wmm_acm = 0; | 420 | local->wmm_acm = 0; |
| 424 | for (; left >= 4; left -= 4, pos += 4) { | 421 | for (; left >= 4; left -= 4, pos += 4) { |
| 425 | int aci = (pos[0] >> 5) & 0x03; | 422 | int aci = (pos[0] >> 5) & 0x03; |
| @@ -427,26 +424,26 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, | |||
| 427 | int queue; | 424 | int queue; |
| 428 | 425 | ||
| 429 | switch (aci) { | 426 | switch (aci) { |
| 430 | case 1: | 427 | case 1: /* AC_BK */ |
| 431 | queue = 3; | 428 | queue = 3; |
| 432 | if (acm) | 429 | if (acm) |
| 433 | local->wmm_acm |= BIT(0) | BIT(3); | 430 | local->wmm_acm |= BIT(1) | BIT(2); /* BK/- */ |
| 434 | break; | 431 | break; |
| 435 | case 2: | 432 | case 2: /* AC_VI */ |
| 436 | queue = 1; | 433 | queue = 1; |
| 437 | if (acm) | 434 | if (acm) |
| 438 | local->wmm_acm |= BIT(4) | BIT(5); | 435 | local->wmm_acm |= BIT(4) | BIT(5); /* CL/VI */ |
| 439 | break; | 436 | break; |
| 440 | case 3: | 437 | case 3: /* AC_VO */ |
| 441 | queue = 0; | 438 | queue = 0; |
| 442 | if (acm) | 439 | if (acm) |
| 443 | local->wmm_acm |= BIT(6) | BIT(7); | 440 | local->wmm_acm |= BIT(6) | BIT(7); /* VO/NC */ |
| 444 | break; | 441 | break; |
| 445 | case 0: | 442 | case 0: /* AC_BE */ |
| 446 | default: | 443 | default: |
| 447 | queue = 2; | 444 | queue = 2; |
| 448 | if (acm) | 445 | if (acm) |
| 449 | local->wmm_acm |= BIT(1) | BIT(2); | 446 | local->wmm_acm |= BIT(0) | BIT(3); /* BE/EE */ |
| 450 | break; | 447 | break; |
| 451 | } | 448 | } |
| 452 | 449 | ||
| @@ -460,9 +457,8 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, | |||
| 460 | local->mdev->name, queue, aci, acm, params.aifs, params.cw_min, | 457 | local->mdev->name, queue, aci, acm, params.aifs, params.cw_min, |
| 461 | params.cw_max, params.txop); | 458 | params.cw_max, params.txop); |
| 462 | #endif | 459 | #endif |
| 463 | /* TODO: handle ACM (block TX, fallback to next lowest allowed | 460 | if (local->ops->conf_tx && |
| 464 | * AC for now) */ | 461 | local->ops->conf_tx(local_to_hw(local), queue, ¶ms)) { |
| 465 | if (local->ops->conf_tx(local_to_hw(local), queue, ¶ms)) { | ||
| 466 | printk(KERN_DEBUG "%s: failed to set TX queue " | 462 | printk(KERN_DEBUG "%s: failed to set TX queue " |
| 467 | "parameters for queue %d\n", local->mdev->name, queue); | 463 | "parameters for queue %d\n", local->mdev->name, queue); |
| 468 | } | 464 | } |
| @@ -1724,7 +1720,10 @@ static int ieee80211_sta_config_auth(struct ieee80211_sub_if_data *sdata) | |||
| 1724 | local->int_scan_req.ssids[0].ssid_len = 0; | 1720 | local->int_scan_req.ssids[0].ssid_len = 0; |
| 1725 | else | 1721 | else |
| 1726 | local->int_scan_req.ssids[0].ssid_len = ifmgd->ssid_len; | 1722 | local->int_scan_req.ssids[0].ssid_len = ifmgd->ssid_len; |
| 1727 | ieee80211_start_scan(sdata, &local->int_scan_req); | 1723 | |
| 1724 | if (ieee80211_start_scan(sdata, &local->int_scan_req)) | ||
| 1725 | ieee80211_scan_failed(local); | ||
| 1726 | |||
| 1728 | ifmgd->state = IEEE80211_STA_MLME_AUTHENTICATE; | 1727 | ifmgd->state = IEEE80211_STA_MLME_AUTHENTICATE; |
| 1729 | set_bit(IEEE80211_STA_REQ_AUTH, &ifmgd->request); | 1728 | set_bit(IEEE80211_STA_REQ_AUTH, &ifmgd->request); |
| 1730 | } else { | 1729 | } else { |
| @@ -1761,7 +1760,14 @@ static void ieee80211_sta_work(struct work_struct *work) | |||
| 1761 | ifmgd->state != IEEE80211_STA_MLME_AUTHENTICATE && | 1760 | ifmgd->state != IEEE80211_STA_MLME_AUTHENTICATE && |
| 1762 | ifmgd->state != IEEE80211_STA_MLME_ASSOCIATE && | 1761 | ifmgd->state != IEEE80211_STA_MLME_ASSOCIATE && |
| 1763 | test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request)) { | 1762 | test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request)) { |
| 1764 | ieee80211_start_scan(sdata, local->scan_req); | 1763 | /* |
| 1764 | * The call to ieee80211_start_scan can fail but ieee80211_request_scan | ||
| 1765 | * (which queued ieee80211_sta_work) did not return an error. Thus, call | ||
| 1766 | * ieee80211_scan_failed here if ieee80211_start_scan fails in order to | ||
| 1767 | * notify the scan requester. | ||
| 1768 | */ | ||
| 1769 | if (ieee80211_start_scan(sdata, local->scan_req)) | ||
| 1770 | ieee80211_scan_failed(local); | ||
| 1765 | return; | 1771 | return; |
| 1766 | } | 1772 | } |
| 1767 | 1773 | ||
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 0e81e1633a66..5030a3c87509 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
| @@ -202,6 +202,18 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, | |||
| 202 | return RX_QUEUED; | 202 | return RX_QUEUED; |
| 203 | } | 203 | } |
| 204 | 204 | ||
| 205 | void ieee80211_scan_failed(struct ieee80211_local *local) | ||
| 206 | { | ||
| 207 | if (WARN_ON(!local->scan_req)) | ||
| 208 | return; | ||
| 209 | |||
| 210 | /* notify cfg80211 about the failed scan */ | ||
| 211 | if (local->scan_req != &local->int_scan_req) | ||
| 212 | cfg80211_scan_done(local->scan_req, true); | ||
| 213 | |||
| 214 | local->scan_req = NULL; | ||
| 215 | } | ||
| 216 | |||
| 205 | void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) | 217 | void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) |
| 206 | { | 218 | { |
| 207 | struct ieee80211_local *local = hw_to_local(hw); | 219 | struct ieee80211_local *local = hw_to_local(hw); |
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index 093a4ab7f28b..0b8ad1f4ecdd 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c | |||
| @@ -99,10 +99,13 @@ static u16 classify80211(struct ieee80211_local *local, struct sk_buff *skb) | |||
| 99 | /* in case we are a client verify acm is not set for this ac */ | 99 | /* in case we are a client verify acm is not set for this ac */ |
| 100 | while (unlikely(local->wmm_acm & BIT(skb->priority))) { | 100 | while (unlikely(local->wmm_acm & BIT(skb->priority))) { |
| 101 | if (wme_downgrade_ac(skb)) { | 101 | if (wme_downgrade_ac(skb)) { |
| 102 | /* The old code would drop the packet in this | 102 | /* |
| 103 | * case. | 103 | * This should not really happen. The AP has marked all |
| 104 | * lower ACs to require admission control which is not | ||
| 105 | * a reasonable configuration. Allow the frame to be | ||
| 106 | * transmitted using AC_BK as a workaround. | ||
| 104 | */ | 107 | */ |
| 105 | return 0; | 108 | break; |
| 106 | } | 109 | } |
| 107 | } | 110 | } |
| 108 | 111 | ||
