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 | } |