diff options
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r-- | net/mac80211/main.c | 54 |
1 files changed, 41 insertions, 13 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index ffff54944f9d..88c1975a97a5 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -41,6 +41,8 @@ | |||
41 | */ | 41 | */ |
42 | struct ieee80211_tx_status_rtap_hdr { | 42 | struct ieee80211_tx_status_rtap_hdr { |
43 | struct ieee80211_radiotap_header hdr; | 43 | struct ieee80211_radiotap_header hdr; |
44 | u8 rate; | ||
45 | u8 padding_for_rate; | ||
44 | __le16 tx_flags; | 46 | __le16 tx_flags; |
45 | u8 data_retries; | 47 | u8 data_retries; |
46 | } __attribute__ ((packed)); | 48 | } __attribute__ ((packed)); |
@@ -465,13 +467,28 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
465 | struct ieee80211_sub_if_data *sdata; | 467 | struct ieee80211_sub_if_data *sdata; |
466 | struct net_device *prev_dev = NULL; | 468 | struct net_device *prev_dev = NULL; |
467 | struct sta_info *sta; | 469 | struct sta_info *sta; |
470 | int retry_count = -1, i; | ||
471 | |||
472 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { | ||
473 | /* the HW cannot have attempted that rate */ | ||
474 | if (i >= hw->max_rates) { | ||
475 | info->status.rates[i].idx = -1; | ||
476 | info->status.rates[i].count = 0; | ||
477 | } | ||
478 | |||
479 | retry_count += info->status.rates[i].count; | ||
480 | } | ||
481 | if (retry_count < 0) | ||
482 | retry_count = 0; | ||
468 | 483 | ||
469 | rcu_read_lock(); | 484 | rcu_read_lock(); |
470 | 485 | ||
486 | sband = local->hw.wiphy->bands[info->band]; | ||
487 | |||
471 | sta = sta_info_get(local, hdr->addr1); | 488 | sta = sta_info_get(local, hdr->addr1); |
472 | 489 | ||
473 | if (sta) { | 490 | if (sta) { |
474 | if (info->status.excessive_retries && | 491 | if (!(info->flags & IEEE80211_TX_STAT_ACK) && |
475 | test_sta_flags(sta, WLAN_STA_PS)) { | 492 | test_sta_flags(sta, WLAN_STA_PS)) { |
476 | /* | 493 | /* |
477 | * The STA is in power save mode, so assume | 494 | * The STA is in power save mode, so assume |
@@ -502,12 +519,11 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
502 | rcu_read_unlock(); | 519 | rcu_read_unlock(); |
503 | return; | 520 | return; |
504 | } else { | 521 | } else { |
505 | if (info->status.excessive_retries) | 522 | if (!(info->flags & IEEE80211_TX_STAT_ACK)) |
506 | sta->tx_retry_failed++; | 523 | sta->tx_retry_failed++; |
507 | sta->tx_retry_count += info->status.retry_count; | 524 | sta->tx_retry_count += retry_count; |
508 | } | 525 | } |
509 | 526 | ||
510 | sband = local->hw.wiphy->bands[info->band]; | ||
511 | rate_control_tx_status(local, sband, sta, skb); | 527 | rate_control_tx_status(local, sband, sta, skb); |
512 | } | 528 | } |
513 | 529 | ||
@@ -528,9 +544,9 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
528 | local->dot11TransmittedFrameCount++; | 544 | local->dot11TransmittedFrameCount++; |
529 | if (is_multicast_ether_addr(hdr->addr1)) | 545 | if (is_multicast_ether_addr(hdr->addr1)) |
530 | local->dot11MulticastTransmittedFrameCount++; | 546 | local->dot11MulticastTransmittedFrameCount++; |
531 | if (info->status.retry_count > 0) | 547 | if (retry_count > 0) |
532 | local->dot11RetryCount++; | 548 | local->dot11RetryCount++; |
533 | if (info->status.retry_count > 1) | 549 | if (retry_count > 1) |
534 | local->dot11MultipleRetryCount++; | 550 | local->dot11MultipleRetryCount++; |
535 | } | 551 | } |
536 | 552 | ||
@@ -574,19 +590,30 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
574 | rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr)); | 590 | rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr)); |
575 | rthdr->hdr.it_present = | 591 | rthdr->hdr.it_present = |
576 | cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) | | 592 | cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) | |
577 | (1 << IEEE80211_RADIOTAP_DATA_RETRIES)); | 593 | (1 << IEEE80211_RADIOTAP_DATA_RETRIES) | |
594 | (1 << IEEE80211_RADIOTAP_RATE)); | ||
578 | 595 | ||
579 | if (!(info->flags & IEEE80211_TX_STAT_ACK) && | 596 | if (!(info->flags & IEEE80211_TX_STAT_ACK) && |
580 | !is_multicast_ether_addr(hdr->addr1)) | 597 | !is_multicast_ether_addr(hdr->addr1)) |
581 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL); | 598 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL); |
582 | 599 | ||
583 | if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) && | 600 | /* |
584 | (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) | 601 | * XXX: Once radiotap gets the bitmap reset thing the vendor |
602 | * extensions proposal contains, we can actually report | ||
603 | * the whole set of tries we did. | ||
604 | */ | ||
605 | if ((info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) || | ||
606 | (info->status.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) | ||
585 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS); | 607 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS); |
586 | else if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) | 608 | else if (info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) |
587 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS); | 609 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS); |
610 | if (info->status.rates[0].idx >= 0 && | ||
611 | !(info->status.rates[0].flags & IEEE80211_TX_RC_MCS)) | ||
612 | rthdr->rate = sband->bitrates[ | ||
613 | info->status.rates[0].idx].bitrate / 5; | ||
588 | 614 | ||
589 | rthdr->data_retries = info->status.retry_count; | 615 | /* for now report the total retry_count */ |
616 | rthdr->data_retries = retry_count; | ||
590 | 617 | ||
591 | /* XXX: is this sufficient for BPF? */ | 618 | /* XXX: is this sufficient for BPF? */ |
592 | skb_set_mac_header(skb, 0); | 619 | skb_set_mac_header(skb, 0); |
@@ -671,8 +698,9 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
671 | BUG_ON(!ops->configure_filter); | 698 | BUG_ON(!ops->configure_filter); |
672 | local->ops = ops; | 699 | local->ops = ops; |
673 | 700 | ||
674 | local->hw.queues = 1; /* default */ | 701 | /* set up some defaults */ |
675 | 702 | local->hw.queues = 1; | |
703 | local->hw.max_rates = 1; | ||
676 | local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; | 704 | local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; |
677 | local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD; | 705 | local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD; |
678 | local->hw.conf.long_frame_max_tx_count = 4; | 706 | local->hw.conf.long_frame_max_tx_count = 4; |