diff options
Diffstat (limited to 'net/mac80211/util.c')
| -rw-r--r-- | net/mac80211/util.c | 126 |
1 files changed, 31 insertions, 95 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index e0431a1d218b..fdf432f14554 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
| @@ -166,18 +166,13 @@ int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) | |||
| 166 | 166 | ||
| 167 | void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx) | 167 | void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx) |
| 168 | { | 168 | { |
| 169 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data; | 169 | struct sk_buff *skb = tx->skb; |
| 170 | 170 | struct ieee80211_hdr *hdr; | |
| 171 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); | 171 | |
| 172 | if (tx->extra_frag) { | 172 | do { |
| 173 | struct ieee80211_hdr *fhdr; | 173 | hdr = (struct ieee80211_hdr *) skb->data; |
| 174 | int i; | 174 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); |
| 175 | for (i = 0; i < tx->num_extra_frag; i++) { | 175 | } while ((skb = skb->next)); |
| 176 | fhdr = (struct ieee80211_hdr *) | ||
| 177 | tx->extra_frag[i]->data; | ||
| 178 | fhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); | ||
| 179 | } | ||
| 180 | } | ||
| 181 | } | 176 | } |
| 182 | 177 | ||
| 183 | int ieee80211_frame_duration(struct ieee80211_local *local, size_t len, | 178 | int ieee80211_frame_duration(struct ieee80211_local *local, size_t len, |
| @@ -344,42 +339,21 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue, | |||
| 344 | { | 339 | { |
| 345 | struct ieee80211_local *local = hw_to_local(hw); | 340 | struct ieee80211_local *local = hw_to_local(hw); |
| 346 | 341 | ||
| 347 | if (queue >= hw->queues) { | 342 | if (WARN_ON(queue >= hw->queues)) |
| 348 | if (local->ampdu_ac_queue[queue - hw->queues] < 0) | 343 | return; |
| 349 | return; | ||
| 350 | |||
| 351 | /* | ||
| 352 | * for virtual aggregation queues, we need to refcount the | ||
| 353 | * internal mac80211 disable (multiple times!), keep track of | ||
| 354 | * driver disable _and_ make sure the regular queue is | ||
| 355 | * actually enabled. | ||
| 356 | */ | ||
| 357 | if (reason == IEEE80211_QUEUE_STOP_REASON_AGGREGATION) | ||
| 358 | local->amdpu_ac_stop_refcnt[queue - hw->queues]--; | ||
| 359 | else | ||
| 360 | __clear_bit(reason, &local->queue_stop_reasons[queue]); | ||
| 361 | |||
| 362 | if (local->queue_stop_reasons[queue] || | ||
| 363 | local->amdpu_ac_stop_refcnt[queue - hw->queues]) | ||
| 364 | return; | ||
| 365 | |||
| 366 | /* now go on to treat the corresponding regular queue */ | ||
| 367 | queue = local->ampdu_ac_queue[queue - hw->queues]; | ||
| 368 | reason = IEEE80211_QUEUE_STOP_REASON_AGGREGATION; | ||
| 369 | } | ||
| 370 | 344 | ||
| 371 | __clear_bit(reason, &local->queue_stop_reasons[queue]); | 345 | __clear_bit(reason, &local->queue_stop_reasons[queue]); |
| 372 | 346 | ||
| 347 | if (!skb_queue_empty(&local->pending[queue]) && | ||
| 348 | local->queue_stop_reasons[queue] == | ||
| 349 | BIT(IEEE80211_QUEUE_STOP_REASON_PENDING)) | ||
| 350 | tasklet_schedule(&local->tx_pending_tasklet); | ||
| 351 | |||
| 373 | if (local->queue_stop_reasons[queue] != 0) | 352 | if (local->queue_stop_reasons[queue] != 0) |
| 374 | /* someone still has this queue stopped */ | 353 | /* someone still has this queue stopped */ |
| 375 | return; | 354 | return; |
| 376 | 355 | ||
| 377 | if (test_bit(queue, local->queues_pending)) { | 356 | netif_wake_subqueue(local->mdev, queue); |
| 378 | set_bit(queue, local->queues_pending_run); | ||
| 379 | tasklet_schedule(&local->tx_pending_tasklet); | ||
| 380 | } else { | ||
| 381 | netif_wake_subqueue(local->mdev, queue); | ||
| 382 | } | ||
| 383 | } | 357 | } |
| 384 | 358 | ||
| 385 | void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, | 359 | void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, |
| @@ -405,29 +379,18 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue, | |||
| 405 | { | 379 | { |
| 406 | struct ieee80211_local *local = hw_to_local(hw); | 380 | struct ieee80211_local *local = hw_to_local(hw); |
| 407 | 381 | ||
| 408 | if (queue >= hw->queues) { | 382 | if (WARN_ON(queue >= hw->queues)) |
| 409 | if (local->ampdu_ac_queue[queue - hw->queues] < 0) | 383 | return; |
| 410 | return; | ||
| 411 | |||
| 412 | /* | ||
| 413 | * for virtual aggregation queues, we need to refcount the | ||
| 414 | * internal mac80211 disable (multiple times!), keep track of | ||
| 415 | * driver disable _and_ make sure the regular queue is | ||
| 416 | * actually enabled. | ||
| 417 | */ | ||
| 418 | if (reason == IEEE80211_QUEUE_STOP_REASON_AGGREGATION) | ||
| 419 | local->amdpu_ac_stop_refcnt[queue - hw->queues]++; | ||
| 420 | else | ||
| 421 | __set_bit(reason, &local->queue_stop_reasons[queue]); | ||
| 422 | 384 | ||
| 423 | /* now go on to treat the corresponding regular queue */ | 385 | /* |
| 424 | queue = local->ampdu_ac_queue[queue - hw->queues]; | 386 | * Only stop if it was previously running, this is necessary |
| 425 | reason = IEEE80211_QUEUE_STOP_REASON_AGGREGATION; | 387 | * for correct pending packets handling because there we may |
| 426 | } | 388 | * start (but not wake) the queue and rely on that. |
| 389 | */ | ||
| 390 | if (!local->queue_stop_reasons[queue]) | ||
| 391 | netif_stop_subqueue(local->mdev, queue); | ||
| 427 | 392 | ||
| 428 | __set_bit(reason, &local->queue_stop_reasons[queue]); | 393 | __set_bit(reason, &local->queue_stop_reasons[queue]); |
| 429 | |||
| 430 | netif_stop_subqueue(local->mdev, queue); | ||
| 431 | } | 394 | } |
| 432 | 395 | ||
| 433 | void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, | 396 | void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, |
| @@ -473,15 +436,9 @@ EXPORT_SYMBOL(ieee80211_stop_queues); | |||
| 473 | int ieee80211_queue_stopped(struct ieee80211_hw *hw, int queue) | 436 | int ieee80211_queue_stopped(struct ieee80211_hw *hw, int queue) |
| 474 | { | 437 | { |
| 475 | struct ieee80211_local *local = hw_to_local(hw); | 438 | struct ieee80211_local *local = hw_to_local(hw); |
| 476 | unsigned long flags; | ||
| 477 | 439 | ||
| 478 | if (queue >= hw->queues) { | 440 | if (WARN_ON(queue >= hw->queues)) |
| 479 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags); | 441 | return true; |
| 480 | queue = local->ampdu_ac_queue[queue - hw->queues]; | ||
| 481 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | ||
| 482 | if (queue < 0) | ||
| 483 | return true; | ||
| 484 | } | ||
| 485 | 442 | ||
| 486 | return __netif_subqueue_stopped(local->mdev, queue); | 443 | return __netif_subqueue_stopped(local->mdev, queue); |
| 487 | } | 444 | } |
| @@ -496,7 +453,7 @@ void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, | |||
| 496 | 453 | ||
| 497 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags); | 454 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags); |
| 498 | 455 | ||
| 499 | for (i = 0; i < hw->queues + hw->ampdu_queues; i++) | 456 | for (i = 0; i < hw->queues; i++) |
| 500 | __ieee80211_wake_queue(hw, i, reason); | 457 | __ieee80211_wake_queue(hw, i, reason); |
| 501 | 458 | ||
| 502 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | 459 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); |
| @@ -846,16 +803,9 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, | |||
| 846 | struct ieee80211_local *local = sdata->local; | 803 | struct ieee80211_local *local = sdata->local; |
| 847 | struct sk_buff *skb; | 804 | struct sk_buff *skb; |
| 848 | struct ieee80211_mgmt *mgmt; | 805 | struct ieee80211_mgmt *mgmt; |
| 849 | const u8 *ie_auth = NULL; | ||
| 850 | int ie_auth_len = 0; | ||
| 851 | |||
| 852 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { | ||
| 853 | ie_auth_len = sdata->u.mgd.ie_auth_len; | ||
| 854 | ie_auth = sdata->u.mgd.ie_auth; | ||
| 855 | } | ||
| 856 | 806 | ||
| 857 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + | 807 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + |
| 858 | sizeof(*mgmt) + 6 + extra_len + ie_auth_len); | 808 | sizeof(*mgmt) + 6 + extra_len); |
| 859 | if (!skb) { | 809 | if (!skb) { |
| 860 | printk(KERN_DEBUG "%s: failed to allocate buffer for auth " | 810 | printk(KERN_DEBUG "%s: failed to allocate buffer for auth " |
| 861 | "frame\n", sdata->dev->name); | 811 | "frame\n", sdata->dev->name); |
| @@ -877,8 +827,6 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, | |||
| 877 | mgmt->u.auth.status_code = cpu_to_le16(0); | 827 | mgmt->u.auth.status_code = cpu_to_le16(0); |
| 878 | if (extra) | 828 | if (extra) |
| 879 | memcpy(skb_put(skb, extra_len), extra, extra_len); | 829 | memcpy(skb_put(skb, extra_len), extra, extra_len); |
| 880 | if (ie_auth) | ||
| 881 | memcpy(skb_put(skb, ie_auth_len), ie_auth, ie_auth_len); | ||
| 882 | 830 | ||
| 883 | ieee80211_tx_skb(sdata, skb, encrypt); | 831 | ieee80211_tx_skb(sdata, skb, encrypt); |
| 884 | } | 832 | } |
| @@ -891,20 +839,11 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, | |||
| 891 | struct ieee80211_supported_band *sband; | 839 | struct ieee80211_supported_band *sband; |
| 892 | struct sk_buff *skb; | 840 | struct sk_buff *skb; |
| 893 | struct ieee80211_mgmt *mgmt; | 841 | struct ieee80211_mgmt *mgmt; |
| 894 | u8 *pos, *supp_rates, *esupp_rates = NULL, *extra_preq_ie = NULL; | 842 | u8 *pos, *supp_rates, *esupp_rates = NULL; |
| 895 | int i, extra_preq_ie_len = 0; | 843 | int i; |
| 896 | |||
| 897 | switch (sdata->vif.type) { | ||
| 898 | case NL80211_IFTYPE_STATION: | ||
| 899 | extra_preq_ie_len = sdata->u.mgd.ie_probereq_len; | ||
| 900 | extra_preq_ie = sdata->u.mgd.ie_probereq; | ||
| 901 | break; | ||
| 902 | default: | ||
| 903 | break; | ||
| 904 | } | ||
| 905 | 844 | ||
| 906 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + 200 + | 845 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + 200 + |
| 907 | ie_len + extra_preq_ie_len); | 846 | ie_len); |
| 908 | if (!skb) { | 847 | if (!skb) { |
| 909 | printk(KERN_DEBUG "%s: failed to allocate buffer for probe " | 848 | printk(KERN_DEBUG "%s: failed to allocate buffer for probe " |
| 910 | "request\n", sdata->dev->name); | 849 | "request\n", sdata->dev->name); |
| @@ -953,9 +892,6 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, | |||
| 953 | 892 | ||
| 954 | if (ie) | 893 | if (ie) |
| 955 | memcpy(skb_put(skb, ie_len), ie, ie_len); | 894 | memcpy(skb_put(skb, ie_len), ie, ie_len); |
| 956 | if (extra_preq_ie) | ||
| 957 | memcpy(skb_put(skb, extra_preq_ie_len), extra_preq_ie, | ||
| 958 | extra_preq_ie_len); | ||
| 959 | 895 | ||
| 960 | ieee80211_tx_skb(sdata, skb, 0); | 896 | ieee80211_tx_skb(sdata, skb, 0); |
| 961 | } | 897 | } |
