diff options
47 files changed, 889 insertions, 685 deletions
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c index 9a1e0c514c08..b96ebfe4ef3e 100644 --- a/drivers/net/wireless/adm8211.c +++ b/drivers/net/wireless/adm8211.c | |||
@@ -341,15 +341,14 @@ static void adm8211_interrupt_tci(struct ieee80211_hw *dev) | |||
341 | pci_unmap_single(priv->pdev, info->mapping, | 341 | pci_unmap_single(priv->pdev, info->mapping, |
342 | info->skb->len, PCI_DMA_TODEVICE); | 342 | info->skb->len, PCI_DMA_TODEVICE); |
343 | 343 | ||
344 | memset(&txi->status, 0, sizeof(txi->status)); | 344 | ieee80211_tx_info_clear_status(txi); |
345 | |||
345 | skb_pull(skb, sizeof(struct adm8211_tx_hdr)); | 346 | skb_pull(skb, sizeof(struct adm8211_tx_hdr)); |
346 | memcpy(skb_push(skb, info->hdrlen), skb->cb, info->hdrlen); | 347 | memcpy(skb_push(skb, info->hdrlen), skb->cb, info->hdrlen); |
347 | if (!(txi->flags & IEEE80211_TX_CTL_NO_ACK)) { | 348 | if (!(txi->flags & IEEE80211_TX_CTL_NO_ACK) && |
348 | if (status & TDES0_STATUS_ES) | 349 | !(status & TDES0_STATUS_ES)) |
349 | txi->status.excessive_retries = 1; | 350 | txi->flags |= IEEE80211_TX_STAT_ACK; |
350 | else | 351 | |
351 | txi->flags |= IEEE80211_TX_STAT_ACK; | ||
352 | } | ||
353 | ieee80211_tx_status_irqsafe(dev, skb); | 352 | ieee80211_tx_status_irqsafe(dev, skb); |
354 | 353 | ||
355 | info->skb = NULL; | 354 | info->skb = NULL; |
@@ -1691,8 +1690,10 @@ static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
1691 | struct ieee80211_hdr *hdr; | 1690 | struct ieee80211_hdr *hdr; |
1692 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 1691 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1693 | struct ieee80211_rate *txrate = ieee80211_get_tx_rate(dev, info); | 1692 | struct ieee80211_rate *txrate = ieee80211_get_tx_rate(dev, info); |
1693 | u8 rc_flags; | ||
1694 | 1694 | ||
1695 | short_preamble = !!(txrate->flags & IEEE80211_TX_CTL_SHORT_PREAMBLE); | 1695 | rc_flags = info->control.rates[0].flags; |
1696 | short_preamble = !!(rc_flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE); | ||
1696 | plcp_signal = txrate->bitrate; | 1697 | plcp_signal = txrate->bitrate; |
1697 | 1698 | ||
1698 | hdr = (struct ieee80211_hdr *)skb->data; | 1699 | hdr = (struct ieee80211_hdr *)skb->data; |
@@ -1724,10 +1725,10 @@ static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
1724 | if (short_preamble) | 1725 | if (short_preamble) |
1725 | txhdr->header_control |= cpu_to_le16(ADM8211_TXHDRCTL_SHORT_PREAMBLE); | 1726 | txhdr->header_control |= cpu_to_le16(ADM8211_TXHDRCTL_SHORT_PREAMBLE); |
1726 | 1727 | ||
1727 | if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) | 1728 | if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS) |
1728 | txhdr->header_control |= cpu_to_le16(ADM8211_TXHDRCTL_ENABLE_RTS); | 1729 | txhdr->header_control |= cpu_to_le16(ADM8211_TXHDRCTL_ENABLE_RTS); |
1729 | 1730 | ||
1730 | txhdr->retry_limit = info->control.retry_limit; | 1731 | txhdr->retry_limit = info->control.rates[0].count; |
1731 | 1732 | ||
1732 | adm8211_tx_raw(dev, skb, plcp_signal, hdrlen); | 1733 | adm8211_tx_raw(dev, skb, plcp_signal, hdrlen); |
1733 | 1734 | ||
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index 44401f6f578d..3773d983ea66 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c | |||
@@ -541,8 +541,8 @@ ath5k_pci_probe(struct pci_dev *pdev, | |||
541 | 541 | ||
542 | /* set up multi-rate retry capabilities */ | 542 | /* set up multi-rate retry capabilities */ |
543 | if (sc->ah->ah_version == AR5K_AR5212) { | 543 | if (sc->ah->ah_version == AR5K_AR5212) { |
544 | hw->max_altrates = 3; | 544 | hw->max_rates = 4; |
545 | hw->max_altrate_tries = 11; | 545 | hw->max_rate_tries = 11; |
546 | } | 546 | } |
547 | 547 | ||
548 | /* Finish private driver data initialization */ | 548 | /* Finish private driver data initialization */ |
@@ -1181,7 +1181,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) | |||
1181 | ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL, | 1181 | ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL, |
1182 | (sc->power_level * 2), | 1182 | (sc->power_level * 2), |
1183 | ieee80211_get_tx_rate(sc->hw, info)->hw_value, | 1183 | ieee80211_get_tx_rate(sc->hw, info)->hw_value, |
1184 | info->control.retry_limit, keyidx, 0, flags, 0, 0); | 1184 | info->control.rates[0].count, keyidx, 0, flags, 0, 0); |
1185 | if (ret) | 1185 | if (ret) |
1186 | goto err_unmap; | 1186 | goto err_unmap; |
1187 | 1187 | ||
@@ -1193,7 +1193,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) | |||
1193 | break; | 1193 | break; |
1194 | 1194 | ||
1195 | mrr_rate[i] = rate->hw_value; | 1195 | mrr_rate[i] = rate->hw_value; |
1196 | mrr_tries[i] = info->control.retries[i].limit; | 1196 | mrr_tries[i] = info->control.rates[i + 1].count; |
1197 | } | 1197 | } |
1198 | 1198 | ||
1199 | ah->ah_setup_mrr_tx_desc(ah, ds, | 1199 | ah->ah_setup_mrr_tx_desc(ah, ds, |
@@ -1849,30 +1849,26 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) | |||
1849 | pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, | 1849 | pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, |
1850 | PCI_DMA_TODEVICE); | 1850 | PCI_DMA_TODEVICE); |
1851 | 1851 | ||
1852 | memset(&info->status, 0, sizeof(info->status)); | 1852 | ieee80211_tx_info_clear_status(info); |
1853 | info->tx_rate_idx = ath5k_hw_to_driver_rix(sc, | ||
1854 | ts.ts_rate[ts.ts_final_idx]); | ||
1855 | info->status.retry_count = ts.ts_longretry; | ||
1856 | |||
1857 | for (i = 0; i < 4; i++) { | 1853 | for (i = 0; i < 4; i++) { |
1858 | struct ieee80211_tx_altrate *r = | 1854 | struct ieee80211_tx_rate *r = |
1859 | &info->status.retries[i]; | 1855 | &info->status.rates[i]; |
1860 | 1856 | ||
1861 | if (ts.ts_rate[i]) { | 1857 | if (ts.ts_rate[i]) { |
1862 | r->rate_idx = ath5k_hw_to_driver_rix(sc, ts.ts_rate[i]); | 1858 | r->idx = ath5k_hw_to_driver_rix(sc, ts.ts_rate[i]); |
1863 | r->limit = ts.ts_retry[i]; | 1859 | r->count = ts.ts_retry[i]; |
1864 | } else { | 1860 | } else { |
1865 | r->rate_idx = -1; | 1861 | r->idx = -1; |
1866 | r->limit = 0; | 1862 | r->count = 0; |
1867 | } | 1863 | } |
1868 | } | 1864 | } |
1869 | 1865 | ||
1870 | info->status.excessive_retries = 0; | 1866 | /* count the successful attempt as well */ |
1867 | info->status.rates[ts.ts_final_idx].count++; | ||
1868 | |||
1871 | if (unlikely(ts.ts_status)) { | 1869 | if (unlikely(ts.ts_status)) { |
1872 | sc->ll_stats.dot11ACKFailureCount++; | 1870 | sc->ll_stats.dot11ACKFailureCount++; |
1873 | if (ts.ts_status & AR5K_TXERR_XRETRY) | 1871 | if (ts.ts_status & AR5K_TXERR_FILT) |
1874 | info->status.excessive_retries = 1; | ||
1875 | else if (ts.ts_status & AR5K_TXERR_FILT) | ||
1876 | info->flags |= IEEE80211_TX_STAT_TX_FILTERED; | 1872 | info->flags |= IEEE80211_TX_STAT_TX_FILTERED; |
1877 | } else { | 1873 | } else { |
1878 | info->flags |= IEEE80211_TX_STAT_ACK; | 1874 | info->flags |= IEEE80211_TX_STAT_ACK; |
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 32acaf7ff622..a7656a3ea1b0 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c | |||
@@ -457,12 +457,13 @@ void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
457 | DPRINTF(sc, ATH_DBG_XMIT, | 457 | DPRINTF(sc, ATH_DBG_XMIT, |
458 | "%s: TX complete: skb: %p\n", __func__, skb); | 458 | "%s: TX complete: skb: %p\n", __func__, skb); |
459 | 459 | ||
460 | ieee80211_tx_info_clear_status(tx_info); | ||
460 | if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK || | 461 | if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK || |
461 | tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) { | 462 | tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) { |
462 | /* free driver's private data area of tx_info */ | 463 | /* free driver's private data area of tx_info, XXX: HACK! */ |
463 | if (tx_info->driver_data[0] != NULL) | 464 | if (tx_info->control.vif != NULL) |
464 | kfree(tx_info->driver_data[0]); | 465 | kfree(tx_info->control.vif); |
465 | tx_info->driver_data[0] = NULL; | 466 | tx_info->control.vif = NULL; |
466 | } | 467 | } |
467 | 468 | ||
468 | if (tx_status->flags & ATH_TX_BAR) { | 469 | if (tx_status->flags & ATH_TX_BAR) { |
@@ -470,17 +471,12 @@ void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
470 | tx_status->flags &= ~ATH_TX_BAR; | 471 | tx_status->flags &= ~ATH_TX_BAR; |
471 | } | 472 | } |
472 | 473 | ||
473 | if (tx_status->flags & (ATH_TX_ERROR | ATH_TX_XRETRY)) { | 474 | if (!(tx_status->flags & (ATH_TX_ERROR | ATH_TX_XRETRY))) { |
474 | if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) { | ||
475 | /* Frame was not ACKed, but an ACK was expected */ | ||
476 | tx_info->status.excessive_retries = 1; | ||
477 | } | ||
478 | } else { | ||
479 | /* Frame was ACKed */ | 475 | /* Frame was ACKed */ |
480 | tx_info->flags |= IEEE80211_TX_STAT_ACK; | 476 | tx_info->flags |= IEEE80211_TX_STAT_ACK; |
481 | } | 477 | } |
482 | 478 | ||
483 | tx_info->status.retry_count = tx_status->retries; | 479 | tx_info->status.rates[0].count = tx_status->retries + 1; |
484 | 480 | ||
485 | ieee80211_tx_status(hw, skb); | 481 | ieee80211_tx_status(hw, skb); |
486 | if (an) | 482 | if (an) |
diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c index 9b2526030965..6afafeddeda2 100644 --- a/drivers/net/wireless/ath9k/rc.c +++ b/drivers/net/wireless/ath9k/rc.c | |||
@@ -1864,24 +1864,21 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, | |||
1864 | 1864 | ||
1865 | hdr = (struct ieee80211_hdr *)skb->data; | 1865 | hdr = (struct ieee80211_hdr *)skb->data; |
1866 | fc = hdr->frame_control; | 1866 | fc = hdr->frame_control; |
1867 | tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0]; | 1867 | /* XXX: UGLY HACK!! */ |
1868 | tx_info_priv = (struct ath_tx_info_priv *)tx_info->control.vif; | ||
1868 | 1869 | ||
1869 | spin_lock_bh(&sc->node_lock); | 1870 | spin_lock_bh(&sc->node_lock); |
1870 | an = ath_node_find(sc, hdr->addr1); | 1871 | an = ath_node_find(sc, hdr->addr1); |
1871 | spin_unlock_bh(&sc->node_lock); | 1872 | spin_unlock_bh(&sc->node_lock); |
1872 | 1873 | ||
1873 | if (!an || !priv_sta || !ieee80211_is_data(fc)) { | 1874 | if (tx_info_priv == NULL) |
1874 | if (tx_info->driver_data[0] != NULL) { | ||
1875 | kfree(tx_info->driver_data[0]); | ||
1876 | tx_info->driver_data[0] = NULL; | ||
1877 | } | ||
1878 | return; | 1875 | return; |
1879 | } | 1876 | |
1880 | if (tx_info->driver_data[0] != NULL) { | 1877 | if (an && priv_sta && ieee80211_is_data(fc)) |
1881 | ath_rate_tx_complete(sc, an, priv_sta, tx_info_priv); | 1878 | ath_rate_tx_complete(sc, an, priv_sta, tx_info_priv); |
1882 | kfree(tx_info->driver_data[0]); | 1879 | |
1883 | tx_info->driver_data[0] = NULL; | 1880 | kfree(tx_info_priv); |
1884 | } | 1881 | tx_info->control.vif = NULL; |
1885 | } | 1882 | } |
1886 | 1883 | ||
1887 | static void ath_tx_aggr_resp(struct ath_softc *sc, | 1884 | static void ath_tx_aggr_resp(struct ath_softc *sc, |
@@ -1927,10 +1924,11 @@ static void ath_tx_aggr_resp(struct ath_softc *sc, | |||
1927 | } | 1924 | } |
1928 | } | 1925 | } |
1929 | 1926 | ||
1930 | static void ath_get_rate(void *priv, struct ieee80211_supported_band *sband, | 1927 | static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, |
1931 | struct ieee80211_sta *sta, void *priv_sta, | 1928 | struct ieee80211_tx_rate_control *txrc) |
1932 | struct sk_buff *skb, struct rate_selection *sel) | ||
1933 | { | 1929 | { |
1930 | struct ieee80211_supported_band *sband = txrc->sband; | ||
1931 | struct sk_buff *skb = txrc->skb; | ||
1934 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 1932 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
1935 | struct ath_softc *sc = priv; | 1933 | struct ath_softc *sc = priv; |
1936 | struct ieee80211_hw *hw = sc->hw; | 1934 | struct ieee80211_hw *hw = sc->hw; |
@@ -1945,17 +1943,17 @@ static void ath_get_rate(void *priv, struct ieee80211_supported_band *sband, | |||
1945 | 1943 | ||
1946 | DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__); | 1944 | DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__); |
1947 | 1945 | ||
1948 | /* allocate driver private area of tx_info */ | 1946 | /* allocate driver private area of tx_info, XXX: UGLY HACK! */ |
1949 | tx_info->driver_data[0] = kzalloc(sizeof(*tx_info_priv), GFP_ATOMIC); | 1947 | tx_info->control.vif = kzalloc(sizeof(*tx_info_priv), GFP_ATOMIC); |
1950 | ASSERT(tx_info->driver_data[0] != NULL); | 1948 | tx_info_priv = (struct ath_tx_info_priv *)tx_info->control.vif; |
1951 | tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0]; | 1949 | ASSERT(tx_info_priv != NULL); |
1952 | 1950 | ||
1953 | lowest_idx = rate_lowest_index(sband, sta); | 1951 | lowest_idx = rate_lowest_index(sband, sta); |
1954 | tx_info_priv->min_rate = (sband->bitrates[lowest_idx].bitrate * 2) / 10; | 1952 | tx_info_priv->min_rate = (sband->bitrates[lowest_idx].bitrate * 2) / 10; |
1955 | /* lowest rate for management and multicast/broadcast frames */ | 1953 | /* lowest rate for management and multicast/broadcast frames */ |
1956 | if (!ieee80211_is_data(fc) || | 1954 | if (!ieee80211_is_data(fc) || |
1957 | is_multicast_ether_addr(hdr->addr1) || !sta) { | 1955 | is_multicast_ether_addr(hdr->addr1) || !sta) { |
1958 | sel->rate_idx = lowest_idx; | 1956 | tx_info->control.rates[0].idx = lowest_idx; |
1959 | return; | 1957 | return; |
1960 | } | 1958 | } |
1961 | 1959 | ||
@@ -1966,8 +1964,10 @@ static void ath_get_rate(void *priv, struct ieee80211_supported_band *sband, | |||
1966 | tx_info_priv->rcs, | 1964 | tx_info_priv->rcs, |
1967 | &is_probe, | 1965 | &is_probe, |
1968 | false); | 1966 | false); |
1967 | #if 0 | ||
1969 | if (is_probe) | 1968 | if (is_probe) |
1970 | sel->probe_idx = ath_rc_priv->tx_ratectrl.probe_rate; | 1969 | sel->probe_idx = ath_rc_priv->tx_ratectrl.probe_rate; |
1970 | #endif | ||
1971 | 1971 | ||
1972 | /* Ratecontrol sometimes returns invalid rate index */ | 1972 | /* Ratecontrol sometimes returns invalid rate index */ |
1973 | if (tx_info_priv->rcs[0].rix != 0xff) | 1973 | if (tx_info_priv->rcs[0].rix != 0xff) |
@@ -1975,7 +1975,7 @@ static void ath_get_rate(void *priv, struct ieee80211_supported_band *sband, | |||
1975 | else | 1975 | else |
1976 | tx_info_priv->rcs[0].rix = ath_rc_priv->prev_data_rix; | 1976 | tx_info_priv->rcs[0].rix = ath_rc_priv->prev_data_rix; |
1977 | 1977 | ||
1978 | sel->rate_idx = tx_info_priv->rcs[0].rix; | 1978 | tx_info->control.rates[0].idx = tx_info_priv->rcs[0].rix; |
1979 | 1979 | ||
1980 | /* Check if aggregation has to be enabled for this tid */ | 1980 | /* Check if aggregation has to be enabled for this tid */ |
1981 | 1981 | ||
diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index ba818cc2fb5c..9fa395418a6c 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c | |||
@@ -168,7 +168,9 @@ static void fill_min_rates(struct sk_buff *skb, struct ath_tx_control *txctl) | |||
168 | 168 | ||
169 | hdr = (struct ieee80211_hdr *)skb->data; | 169 | hdr = (struct ieee80211_hdr *)skb->data; |
170 | fc = hdr->frame_control; | 170 | fc = hdr->frame_control; |
171 | tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0]; | 171 | |
172 | /* XXX: HACK! */ | ||
173 | tx_info_priv = (struct ath_tx_info_priv *)tx_info->control.vif; | ||
172 | 174 | ||
173 | if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc)) { | 175 | if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc)) { |
174 | txctl->use_minrate = 1; | 176 | txctl->use_minrate = 1; |
@@ -288,13 +290,16 @@ static int ath_tx_prepare(struct ath_softc *sc, | |||
288 | 290 | ||
289 | if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) | 291 | if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) |
290 | txctl->flags |= ATH9K_TXDESC_NOACK; | 292 | txctl->flags |= ATH9K_TXDESC_NOACK; |
291 | if (tx_info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) | 293 | |
294 | if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) | ||
292 | txctl->flags |= ATH9K_TXDESC_RTSENA; | 295 | txctl->flags |= ATH9K_TXDESC_RTSENA; |
293 | 296 | ||
294 | /* | 297 | /* |
295 | * Setup for rate calculations. | 298 | * Setup for rate calculations. |
296 | */ | 299 | */ |
297 | tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0]; | 300 | |
301 | /* XXX: HACK! */ | ||
302 | tx_info_priv = (struct ath_tx_info_priv *)tx_info->control.vif; | ||
298 | rcs = tx_info_priv->rcs; | 303 | rcs = tx_info_priv->rcs; |
299 | 304 | ||
300 | if (ieee80211_is_data(fc) && !txctl->use_minrate) { | 305 | if (ieee80211_is_data(fc) && !txctl->use_minrate) { |
@@ -855,7 +860,9 @@ static int ath_tx_send_normal(struct ath_softc *sc, | |||
855 | 860 | ||
856 | skb = (struct sk_buff *)bf->bf_mpdu; | 861 | skb = (struct sk_buff *)bf->bf_mpdu; |
857 | tx_info = IEEE80211_SKB_CB(skb); | 862 | tx_info = IEEE80211_SKB_CB(skb); |
858 | tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0]; | 863 | |
864 | /* XXX: HACK! */ | ||
865 | tx_info_priv = (struct ath_tx_info_priv *)tx_info->control.vif; | ||
859 | memcpy(bf->bf_rcs, tx_info_priv->rcs, 4 * sizeof(tx_info_priv->rcs[0])); | 866 | memcpy(bf->bf_rcs, tx_info_priv->rcs, 4 * sizeof(tx_info_priv->rcs[0])); |
860 | 867 | ||
861 | /* update starting sequence number for subsequent ADDBA request */ | 868 | /* update starting sequence number for subsequent ADDBA request */ |
@@ -1249,8 +1256,9 @@ static int ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
1249 | } | 1256 | } |
1250 | skb = bf->bf_mpdu; | 1257 | skb = bf->bf_mpdu; |
1251 | tx_info = IEEE80211_SKB_CB(skb); | 1258 | tx_info = IEEE80211_SKB_CB(skb); |
1252 | tx_info_priv = (struct ath_tx_info_priv *) | 1259 | |
1253 | tx_info->driver_data[0]; | 1260 | /* XXX: HACK! */ |
1261 | tx_info_priv = (struct ath_tx_info_priv *) tx_info->control.vif; | ||
1254 | if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) | 1262 | if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) |
1255 | tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; | 1263 | tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; |
1256 | if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 && | 1264 | if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 && |
@@ -1431,7 +1439,8 @@ static int ath_tx_send_ampdu(struct ath_softc *sc, | |||
1431 | 1439 | ||
1432 | skb = (struct sk_buff *)bf->bf_mpdu; | 1440 | skb = (struct sk_buff *)bf->bf_mpdu; |
1433 | tx_info = IEEE80211_SKB_CB(skb); | 1441 | tx_info = IEEE80211_SKB_CB(skb); |
1434 | tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0]; | 1442 | /* XXX: HACK! */ |
1443 | tx_info_priv = (struct ath_tx_info_priv *)tx_info->control.vif; | ||
1435 | memcpy(bf->bf_rcs, tx_info_priv->rcs, 4 * sizeof(tx_info_priv->rcs[0])); | 1444 | memcpy(bf->bf_rcs, tx_info_priv->rcs, 4 * sizeof(tx_info_priv->rcs[0])); |
1436 | 1445 | ||
1437 | /* Add sub-frame to BAW */ | 1446 | /* Add sub-frame to BAW */ |
@@ -1466,7 +1475,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc, | |||
1466 | skb = (struct sk_buff *)bf->bf_mpdu; | 1475 | skb = (struct sk_buff *)bf->bf_mpdu; |
1467 | tx_info = IEEE80211_SKB_CB(skb); | 1476 | tx_info = IEEE80211_SKB_CB(skb); |
1468 | tx_info_priv = (struct ath_tx_info_priv *) | 1477 | tx_info_priv = (struct ath_tx_info_priv *) |
1469 | tx_info->driver_data[0]; | 1478 | tx_info->control.vif; /* XXX: HACK! */ |
1470 | memcpy(bf->bf_rcs, | 1479 | memcpy(bf->bf_rcs, |
1471 | tx_info_priv->rcs, 4 * sizeof(tx_info_priv->rcs[0])); | 1480 | tx_info_priv->rcs, 4 * sizeof(tx_info_priv->rcs[0])); |
1472 | 1481 | ||
@@ -1927,7 +1936,8 @@ static int ath_tx_start_dma(struct ath_softc *sc, | |||
1927 | 1936 | ||
1928 | bf->bf_flags = txctl->flags; | 1937 | bf->bf_flags = txctl->flags; |
1929 | bf->bf_keytype = txctl->keytype; | 1938 | bf->bf_keytype = txctl->keytype; |
1930 | tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0]; | 1939 | /* XXX: HACK! */ |
1940 | tx_info_priv = (struct ath_tx_info_priv *)tx_info->control.vif; | ||
1931 | rcs = tx_info_priv->rcs; | 1941 | rcs = tx_info_priv->rcs; |
1932 | bf->bf_rcs[0] = rcs[0]; | 1942 | bf->bf_rcs[0] = rcs[0]; |
1933 | bf->bf_rcs[1] = rcs[1]; | 1943 | bf->bf_rcs[1] = rcs[1]; |
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index 098f886976f6..6d65a02b7052 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c | |||
@@ -1387,13 +1387,11 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, | |||
1387 | 1387 | ||
1388 | info = IEEE80211_SKB_CB(meta->skb); | 1388 | info = IEEE80211_SKB_CB(meta->skb); |
1389 | 1389 | ||
1390 | memset(&info->status, 0, sizeof(info->status)); | ||
1391 | |||
1392 | /* | 1390 | /* |
1393 | * Call back to inform the ieee80211 subsystem about | 1391 | * Call back to inform the ieee80211 subsystem about |
1394 | * the status of the transmission. | 1392 | * the status of the transmission. |
1395 | */ | 1393 | */ |
1396 | frame_succeed = b43_fill_txstatus_report(info, status); | 1394 | frame_succeed = b43_fill_txstatus_report(dev, info, status); |
1397 | #ifdef CONFIG_B43_DEBUG | 1395 | #ifdef CONFIG_B43_DEBUG |
1398 | if (frame_succeed) | 1396 | if (frame_succeed) |
1399 | ring->nr_succeed_tx_packets++; | 1397 | ring->nr_succeed_tx_packets++; |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 9aeeb6553a91..2a599fb772d9 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -4555,7 +4555,7 @@ static int b43_wireless_init(struct ssb_device *dev) | |||
4555 | BIT(NL80211_IFTYPE_ADHOC); | 4555 | BIT(NL80211_IFTYPE_ADHOC); |
4556 | 4556 | ||
4557 | hw->queues = b43_modparam_qos ? 4 : 1; | 4557 | hw->queues = b43_modparam_qos ? 4 : 1; |
4558 | hw->max_altrates = 1; | 4558 | hw->max_rates = 2; |
4559 | SET_IEEE80211_DEV(hw, dev->dev); | 4559 | SET_IEEE80211_DEV(hw, dev->dev); |
4560 | if (is_valid_ether_addr(sprom->et1mac)) | 4560 | if (is_valid_ether_addr(sprom->et1mac)) |
4561 | SET_IEEE80211_PERM_ADDR(hw, sprom->et1mac); | 4561 | SET_IEEE80211_PERM_ADDR(hw, sprom->et1mac); |
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c index 401591267592..1036bef8c4cc 100644 --- a/drivers/net/wireless/b43/pio.c +++ b/drivers/net/wireless/b43/pio.c | |||
@@ -587,9 +587,8 @@ void b43_pio_handle_txstatus(struct b43_wldev *dev, | |||
587 | spin_lock(&q->lock); /* IRQs are already disabled. */ | 587 | spin_lock(&q->lock); /* IRQs are already disabled. */ |
588 | 588 | ||
589 | info = IEEE80211_SKB_CB(pack->skb); | 589 | info = IEEE80211_SKB_CB(pack->skb); |
590 | memset(&info->status, 0, sizeof(info->status)); | ||
591 | 590 | ||
592 | b43_fill_txstatus_report(info, status); | 591 | b43_fill_txstatus_report(dev, info, status); |
593 | 592 | ||
594 | total_len = pack->skb->len + b43_txhdr_size(dev); | 593 | total_len = pack->skb->len + b43_txhdr_size(dev); |
595 | total_len = roundup(total_len, 4); | 594 | total_len = roundup(total_len, 4); |
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index 2fabcf8f0474..adba89b816d4 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c | |||
@@ -185,7 +185,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
185 | u8 *_txhdr, | 185 | u8 *_txhdr, |
186 | const unsigned char *fragment_data, | 186 | const unsigned char *fragment_data, |
187 | unsigned int fragment_len, | 187 | unsigned int fragment_len, |
188 | const struct ieee80211_tx_info *info, | 188 | struct ieee80211_tx_info *info, |
189 | u16 cookie) | 189 | u16 cookie) |
190 | { | 190 | { |
191 | struct b43_txhdr *txhdr = (struct b43_txhdr *)_txhdr; | 191 | struct b43_txhdr *txhdr = (struct b43_txhdr *)_txhdr; |
@@ -202,6 +202,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
202 | u16 phy_ctl = 0; | 202 | u16 phy_ctl = 0; |
203 | u8 extra_ft = 0; | 203 | u8 extra_ft = 0; |
204 | struct ieee80211_rate *txrate; | 204 | struct ieee80211_rate *txrate; |
205 | struct ieee80211_tx_rate *rates; | ||
205 | 206 | ||
206 | memset(txhdr, 0, sizeof(*txhdr)); | 207 | memset(txhdr, 0, sizeof(*txhdr)); |
207 | 208 | ||
@@ -291,7 +292,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
291 | phy_ctl |= B43_TXH_PHY_ENC_OFDM; | 292 | phy_ctl |= B43_TXH_PHY_ENC_OFDM; |
292 | else | 293 | else |
293 | phy_ctl |= B43_TXH_PHY_ENC_CCK; | 294 | phy_ctl |= B43_TXH_PHY_ENC_CCK; |
294 | if (info->flags & IEEE80211_TX_CTL_SHORT_PREAMBLE) | 295 | if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) |
295 | phy_ctl |= B43_TXH_PHY_SHORTPRMBL; | 296 | phy_ctl |= B43_TXH_PHY_SHORTPRMBL; |
296 | 297 | ||
297 | switch (b43_ieee80211_antenna_sanitize(dev, info->antenna_sel_tx)) { | 298 | switch (b43_ieee80211_antenna_sanitize(dev, info->antenna_sel_tx)) { |
@@ -314,6 +315,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
314 | B43_WARN_ON(1); | 315 | B43_WARN_ON(1); |
315 | } | 316 | } |
316 | 317 | ||
318 | rates = info->control.rates; | ||
317 | /* MAC control */ | 319 | /* MAC control */ |
318 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) | 320 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) |
319 | mac_ctl |= B43_TXH_MAC_ACK; | 321 | mac_ctl |= B43_TXH_MAC_ACK; |
@@ -324,12 +326,22 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
324 | mac_ctl |= B43_TXH_MAC_STMSDU; | 326 | mac_ctl |= B43_TXH_MAC_STMSDU; |
325 | if (phy->type == B43_PHYTYPE_A) | 327 | if (phy->type == B43_PHYTYPE_A) |
326 | mac_ctl |= B43_TXH_MAC_5GHZ; | 328 | mac_ctl |= B43_TXH_MAC_5GHZ; |
327 | if (info->flags & IEEE80211_TX_CTL_LONG_RETRY_LIMIT) | 329 | |
330 | /* Overwrite rates[0].count to make the retry calculation | ||
331 | * in the tx status easier. need the actual retry limit to | ||
332 | * detect whether the fallback rate was used. | ||
333 | */ | ||
334 | if ((rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) || | ||
335 | (rates[0].count <= dev->wl->hw->conf.long_frame_max_tx_count)) { | ||
336 | rates[0].count = dev->wl->hw->conf.long_frame_max_tx_count; | ||
328 | mac_ctl |= B43_TXH_MAC_LONGFRAME; | 337 | mac_ctl |= B43_TXH_MAC_LONGFRAME; |
338 | } else { | ||
339 | rates[0].count = dev->wl->hw->conf.short_frame_max_tx_count; | ||
340 | } | ||
329 | 341 | ||
330 | /* Generate the RTS or CTS-to-self frame */ | 342 | /* Generate the RTS or CTS-to-self frame */ |
331 | if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) || | 343 | if ((rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) || |
332 | (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) { | 344 | (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) { |
333 | unsigned int len; | 345 | unsigned int len; |
334 | struct ieee80211_hdr *hdr; | 346 | struct ieee80211_hdr *hdr; |
335 | int rts_rate, rts_rate_fb; | 347 | int rts_rate, rts_rate_fb; |
@@ -344,7 +356,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
344 | rts_rate_fb = b43_calc_fallback_rate(rts_rate); | 356 | rts_rate_fb = b43_calc_fallback_rate(rts_rate); |
345 | rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb); | 357 | rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb); |
346 | 358 | ||
347 | if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) { | 359 | if (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { |
348 | struct ieee80211_cts *cts; | 360 | struct ieee80211_cts *cts; |
349 | 361 | ||
350 | if (b43_is_old_txhdr_format(dev)) { | 362 | if (b43_is_old_txhdr_format(dev)) { |
@@ -687,10 +699,18 @@ void b43_handle_txstatus(struct b43_wldev *dev, | |||
687 | /* Fill out the mac80211 TXstatus report based on the b43-specific | 699 | /* Fill out the mac80211 TXstatus report based on the b43-specific |
688 | * txstatus report data. This returns a boolean whether the frame was | 700 | * txstatus report data. This returns a boolean whether the frame was |
689 | * successfully transmitted. */ | 701 | * successfully transmitted. */ |
690 | bool b43_fill_txstatus_report(struct ieee80211_tx_info *report, | 702 | bool b43_fill_txstatus_report(struct b43_wldev *dev, |
703 | struct ieee80211_tx_info *report, | ||
691 | const struct b43_txstatus *status) | 704 | const struct b43_txstatus *status) |
692 | { | 705 | { |
693 | bool frame_success = 1; | 706 | bool frame_success = 1; |
707 | int retry_limit; | ||
708 | |||
709 | /* preserve the confiured retry limit before clearing the status | ||
710 | * The xmit function has overwritten the rc's value with the actual | ||
711 | * retry limit done by the hardware */ | ||
712 | retry_limit = report->status.rates[0].count; | ||
713 | ieee80211_tx_info_clear_status(report); | ||
694 | 714 | ||
695 | if (status->acked) { | 715 | if (status->acked) { |
696 | /* The frame was ACKed. */ | 716 | /* The frame was ACKed. */ |
@@ -700,14 +720,32 @@ bool b43_fill_txstatus_report(struct ieee80211_tx_info *report, | |||
700 | if (!(report->flags & IEEE80211_TX_CTL_NO_ACK)) { | 720 | if (!(report->flags & IEEE80211_TX_CTL_NO_ACK)) { |
701 | /* ...but we expected an ACK. */ | 721 | /* ...but we expected an ACK. */ |
702 | frame_success = 0; | 722 | frame_success = 0; |
703 | report->status.excessive_retries = 1; | ||
704 | } | 723 | } |
705 | } | 724 | } |
706 | if (status->frame_count == 0) { | 725 | if (status->frame_count == 0) { |
707 | /* The frame was not transmitted at all. */ | 726 | /* The frame was not transmitted at all. */ |
708 | report->status.retry_count = 0; | 727 | report->status.rates[0].count = 0; |
709 | } else | 728 | } else if (status->rts_count > dev->wl->hw->conf.short_frame_max_tx_count) { |
710 | report->status.retry_count = status->frame_count - 1; | 729 | /* |
730 | * If the short retries (RTS, not data frame) have exceeded | ||
731 | * the limit, the hw will not have tried the selected rate, | ||
732 | * but will have used the fallback rate instead. | ||
733 | * Don't let the rate control count attempts for the selected | ||
734 | * rate in this case, otherwise the statistics will be off. | ||
735 | */ | ||
736 | report->status.rates[0].count = 0; | ||
737 | report->status.rates[1].count = status->frame_count; | ||
738 | } else { | ||
739 | if (status->frame_count > retry_limit) { | ||
740 | report->status.rates[0].count = retry_limit; | ||
741 | report->status.rates[1].count = status->frame_count - | ||
742 | retry_limit; | ||
743 | |||
744 | } else { | ||
745 | report->status.rates[0].count = status->frame_count; | ||
746 | report->status.rates[1].idx = -1; | ||
747 | } | ||
748 | } | ||
711 | 749 | ||
712 | return frame_success; | 750 | return frame_success; |
713 | } | 751 | } |
diff --git a/drivers/net/wireless/b43/xmit.h b/drivers/net/wireless/b43/xmit.h index 0215faf47541..4fb2a190f7a7 100644 --- a/drivers/net/wireless/b43/xmit.h +++ b/drivers/net/wireless/b43/xmit.h | |||
@@ -178,7 +178,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
178 | u8 * txhdr, | 178 | u8 * txhdr, |
179 | const unsigned char *fragment_data, | 179 | const unsigned char *fragment_data, |
180 | unsigned int fragment_len, | 180 | unsigned int fragment_len, |
181 | const struct ieee80211_tx_info *txctl, u16 cookie); | 181 | struct ieee80211_tx_info *txctl, u16 cookie); |
182 | 182 | ||
183 | /* Transmit Status */ | 183 | /* Transmit Status */ |
184 | struct b43_txstatus { | 184 | struct b43_txstatus { |
@@ -294,7 +294,8 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr); | |||
294 | 294 | ||
295 | void b43_handle_txstatus(struct b43_wldev *dev, | 295 | void b43_handle_txstatus(struct b43_wldev *dev, |
296 | const struct b43_txstatus *status); | 296 | const struct b43_txstatus *status); |
297 | bool b43_fill_txstatus_report(struct ieee80211_tx_info *report, | 297 | bool b43_fill_txstatus_report(struct b43_wldev *dev, |
298 | struct ieee80211_tx_info *report, | ||
298 | const struct b43_txstatus *status); | 299 | const struct b43_txstatus *status); |
299 | 300 | ||
300 | void b43_tx_suspend(struct b43_wldev *dev); | 301 | void b43_tx_suspend(struct b43_wldev *dev); |
diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c index fb6819e40f38..308c2647f002 100644 --- a/drivers/net/wireless/b43legacy/dma.c +++ b/drivers/net/wireless/b43legacy/dma.c | |||
@@ -1411,6 +1411,7 @@ void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev, | |||
1411 | struct b43legacy_dmaring *ring; | 1411 | struct b43legacy_dmaring *ring; |
1412 | struct b43legacy_dmadesc_generic *desc; | 1412 | struct b43legacy_dmadesc_generic *desc; |
1413 | struct b43legacy_dmadesc_meta *meta; | 1413 | struct b43legacy_dmadesc_meta *meta; |
1414 | int retry_limit; | ||
1414 | int slot; | 1415 | int slot; |
1415 | 1416 | ||
1416 | ring = parse_cookie(dev, status->cookie, &slot); | 1417 | ring = parse_cookie(dev, status->cookie, &slot); |
@@ -1437,25 +1438,42 @@ void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev, | |||
1437 | struct ieee80211_tx_info *info; | 1438 | struct ieee80211_tx_info *info; |
1438 | BUG_ON(!meta->skb); | 1439 | BUG_ON(!meta->skb); |
1439 | info = IEEE80211_SKB_CB(meta->skb); | 1440 | info = IEEE80211_SKB_CB(meta->skb); |
1440 | /* Call back to inform the ieee80211 subsystem about the | ||
1441 | * status of the transmission. | ||
1442 | * Some fields of txstat are already filled in dma_tx(). | ||
1443 | */ | ||
1444 | 1441 | ||
1445 | memset(&info->status, 0, sizeof(info->status)); | 1442 | /* preserve the confiured retry limit before clearing the status |
1443 | * The xmit function has overwritten the rc's value with the actual | ||
1444 | * retry limit done by the hardware */ | ||
1445 | retry_limit = info->status.rates[0].count; | ||
1446 | ieee80211_tx_info_clear_status(info); | ||
1446 | 1447 | ||
1447 | if (status->acked) { | 1448 | if (status->acked) |
1448 | info->flags |= IEEE80211_TX_STAT_ACK; | 1449 | info->flags |= IEEE80211_TX_STAT_ACK; |
1450 | |||
1451 | if (status->rts_count > dev->wl->hw->conf.short_frame_max_tx_count) { | ||
1452 | /* | ||
1453 | * If the short retries (RTS, not data frame) have exceeded | ||
1454 | * the limit, the hw will not have tried the selected rate, | ||
1455 | * but will have used the fallback rate instead. | ||
1456 | * Don't let the rate control count attempts for the selected | ||
1457 | * rate in this case, otherwise the statistics will be off. | ||
1458 | */ | ||
1459 | info->status.rates[0].count = 0; | ||
1460 | info->status.rates[1].count = status->frame_count; | ||
1449 | } else { | 1461 | } else { |
1450 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) | 1462 | if (status->frame_count > retry_limit) { |
1451 | info->status.excessive_retries = 1; | 1463 | info->status.rates[0].count = retry_limit; |
1464 | info->status.rates[1].count = status->frame_count - | ||
1465 | retry_limit; | ||
1466 | |||
1467 | } else { | ||
1468 | info->status.rates[0].count = status->frame_count; | ||
1469 | info->status.rates[1].idx = -1; | ||
1470 | } | ||
1452 | } | 1471 | } |
1453 | if (status->frame_count == 0) { | 1472 | |
1454 | /* The frame was not transmitted at all. */ | 1473 | /* Call back to inform the ieee80211 subsystem about the |
1455 | info->status.retry_count = 0; | 1474 | * status of the transmission. |
1456 | } else | 1475 | * Some fields of txstat are already filled in dma_tx(). |
1457 | info->status.retry_count = status->frame_count | 1476 | */ |
1458 | - 1; | ||
1459 | ieee80211_tx_status_irqsafe(dev->wl->hw, meta->skb); | 1477 | ieee80211_tx_status_irqsafe(dev->wl->hw, meta->skb); |
1460 | /* skb is freed by ieee80211_tx_status_irqsafe() */ | 1478 | /* skb is freed by ieee80211_tx_status_irqsafe() */ |
1461 | meta->skb = NULL; | 1479 | meta->skb = NULL; |
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 78e46365f69e..9edbdf9cb50f 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c | |||
@@ -3682,7 +3682,7 @@ static int b43legacy_wireless_init(struct ssb_device *dev) | |||
3682 | BIT(NL80211_IFTYPE_WDS) | | 3682 | BIT(NL80211_IFTYPE_WDS) | |
3683 | BIT(NL80211_IFTYPE_ADHOC); | 3683 | BIT(NL80211_IFTYPE_ADHOC); |
3684 | hw->queues = 1; /* FIXME: hardware has more queues */ | 3684 | hw->queues = 1; /* FIXME: hardware has more queues */ |
3685 | hw->max_altrates = 1; | 3685 | hw->max_rates = 2; |
3686 | SET_IEEE80211_DEV(hw, dev->dev); | 3686 | SET_IEEE80211_DEV(hw, dev->dev); |
3687 | if (is_valid_ether_addr(sprom->et1mac)) | 3687 | if (is_valid_ether_addr(sprom->et1mac)) |
3688 | SET_IEEE80211_PERM_ADDR(hw, sprom->et1mac); | 3688 | SET_IEEE80211_PERM_ADDR(hw, sprom->et1mac); |
diff --git a/drivers/net/wireless/b43legacy/pio.c b/drivers/net/wireless/b43legacy/pio.c index a86c7647fa2d..746d5361bba0 100644 --- a/drivers/net/wireless/b43legacy/pio.c +++ b/drivers/net/wireless/b43legacy/pio.c | |||
@@ -491,6 +491,7 @@ void b43legacy_pio_handle_txstatus(struct b43legacy_wldev *dev, | |||
491 | struct b43legacy_pioqueue *queue; | 491 | struct b43legacy_pioqueue *queue; |
492 | struct b43legacy_pio_txpacket *packet; | 492 | struct b43legacy_pio_txpacket *packet; |
493 | struct ieee80211_tx_info *info; | 493 | struct ieee80211_tx_info *info; |
494 | int retry_limit; | ||
494 | 495 | ||
495 | queue = parse_cookie(dev, status->cookie, &packet); | 496 | queue = parse_cookie(dev, status->cookie, &packet); |
496 | B43legacy_WARN_ON(!queue); | 497 | B43legacy_WARN_ON(!queue); |
@@ -503,11 +504,37 @@ void b43legacy_pio_handle_txstatus(struct b43legacy_wldev *dev, | |||
503 | sizeof(struct b43legacy_txhdr_fw3)); | 504 | sizeof(struct b43legacy_txhdr_fw3)); |
504 | 505 | ||
505 | info = IEEE80211_SKB_CB(packet->skb); | 506 | info = IEEE80211_SKB_CB(packet->skb); |
506 | memset(&info->status, 0, sizeof(info->status)); | 507 | |
508 | /* preserve the confiured retry limit before clearing the status | ||
509 | * The xmit function has overwritten the rc's value with the actual | ||
510 | * retry limit done by the hardware */ | ||
511 | retry_limit = info->status.rates[0].count; | ||
512 | ieee80211_tx_info_clear_status(info); | ||
507 | 513 | ||
508 | if (status->acked) | 514 | if (status->acked) |
509 | info->flags |= IEEE80211_TX_STAT_ACK; | 515 | info->flags |= IEEE80211_TX_STAT_ACK; |
510 | info->status.retry_count = status->frame_count - 1; | 516 | |
517 | if (status->rts_count > dev->wl->hw->conf.short_frame_max_tx_count) { | ||
518 | /* | ||
519 | * If the short retries (RTS, not data frame) have exceeded | ||
520 | * the limit, the hw will not have tried the selected rate, | ||
521 | * but will have used the fallback rate instead. | ||
522 | * Don't let the rate control count attempts for the selected | ||
523 | * rate in this case, otherwise the statistics will be off. | ||
524 | */ | ||
525 | info->status.rates[0].count = 0; | ||
526 | info->status.rates[1].count = status->frame_count; | ||
527 | } else { | ||
528 | if (status->frame_count > retry_limit) { | ||
529 | info->status.rates[0].count = retry_limit; | ||
530 | info->status.rates[1].count = status->frame_count - | ||
531 | retry_limit; | ||
532 | |||
533 | } else { | ||
534 | info->status.rates[0].count = status->frame_count; | ||
535 | info->status.rates[1].idx = -1; | ||
536 | } | ||
537 | } | ||
511 | ieee80211_tx_status_irqsafe(dev->wl->hw, packet->skb); | 538 | ieee80211_tx_status_irqsafe(dev->wl->hw, packet->skb); |
512 | packet->skb = NULL; | 539 | packet->skb = NULL; |
513 | 540 | ||
diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c index 65e833781608..12fca99f7578 100644 --- a/drivers/net/wireless/b43legacy/xmit.c +++ b/drivers/net/wireless/b43legacy/xmit.c | |||
@@ -188,7 +188,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, | |||
188 | struct b43legacy_txhdr_fw3 *txhdr, | 188 | struct b43legacy_txhdr_fw3 *txhdr, |
189 | const unsigned char *fragment_data, | 189 | const unsigned char *fragment_data, |
190 | unsigned int fragment_len, | 190 | unsigned int fragment_len, |
191 | const struct ieee80211_tx_info *info, | 191 | struct ieee80211_tx_info *info, |
192 | u16 cookie) | 192 | u16 cookie) |
193 | { | 193 | { |
194 | const struct ieee80211_hdr *wlhdr; | 194 | const struct ieee80211_hdr *wlhdr; |
@@ -201,6 +201,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, | |||
201 | u32 mac_ctl = 0; | 201 | u32 mac_ctl = 0; |
202 | u16 phy_ctl = 0; | 202 | u16 phy_ctl = 0; |
203 | struct ieee80211_rate *tx_rate; | 203 | struct ieee80211_rate *tx_rate; |
204 | struct ieee80211_tx_rate *rates; | ||
204 | 205 | ||
205 | wlhdr = (const struct ieee80211_hdr *)fragment_data; | 206 | wlhdr = (const struct ieee80211_hdr *)fragment_data; |
206 | 207 | ||
@@ -274,7 +275,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, | |||
274 | /* PHY TX Control word */ | 275 | /* PHY TX Control word */ |
275 | if (rate_ofdm) | 276 | if (rate_ofdm) |
276 | phy_ctl |= B43legacy_TX4_PHY_OFDM; | 277 | phy_ctl |= B43legacy_TX4_PHY_OFDM; |
277 | if (dev->short_preamble) | 278 | if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) |
278 | phy_ctl |= B43legacy_TX4_PHY_SHORTPRMBL; | 279 | phy_ctl |= B43legacy_TX4_PHY_SHORTPRMBL; |
279 | switch (info->antenna_sel_tx) { | 280 | switch (info->antenna_sel_tx) { |
280 | case 0: | 281 | case 0: |
@@ -291,6 +292,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, | |||
291 | } | 292 | } |
292 | 293 | ||
293 | /* MAC control */ | 294 | /* MAC control */ |
295 | rates = info->control.rates; | ||
294 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) | 296 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) |
295 | mac_ctl |= B43legacy_TX4_MAC_ACK; | 297 | mac_ctl |= B43legacy_TX4_MAC_ACK; |
296 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) | 298 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) |
@@ -299,12 +301,22 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, | |||
299 | mac_ctl |= B43legacy_TX4_MAC_STMSDU; | 301 | mac_ctl |= B43legacy_TX4_MAC_STMSDU; |
300 | if (rate_fb_ofdm) | 302 | if (rate_fb_ofdm) |
301 | mac_ctl |= B43legacy_TX4_MAC_FALLBACKOFDM; | 303 | mac_ctl |= B43legacy_TX4_MAC_FALLBACKOFDM; |
302 | if (info->flags & IEEE80211_TX_CTL_LONG_RETRY_LIMIT) | 304 | |
305 | /* Overwrite rates[0].count to make the retry calculation | ||
306 | * in the tx status easier. need the actual retry limit to | ||
307 | * detect whether the fallback rate was used. | ||
308 | */ | ||
309 | if ((rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) || | ||
310 | (rates[0].count <= dev->wl->hw->conf.long_frame_max_tx_count)) { | ||
311 | rates[0].count = dev->wl->hw->conf.long_frame_max_tx_count; | ||
303 | mac_ctl |= B43legacy_TX4_MAC_LONGFRAME; | 312 | mac_ctl |= B43legacy_TX4_MAC_LONGFRAME; |
313 | } else { | ||
314 | rates[0].count = dev->wl->hw->conf.short_frame_max_tx_count; | ||
315 | } | ||
304 | 316 | ||
305 | /* Generate the RTS or CTS-to-self frame */ | 317 | /* Generate the RTS or CTS-to-self frame */ |
306 | if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) || | 318 | if ((rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) || |
307 | (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) { | 319 | (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) { |
308 | unsigned int len; | 320 | unsigned int len; |
309 | struct ieee80211_hdr *hdr; | 321 | struct ieee80211_hdr *hdr; |
310 | int rts_rate; | 322 | int rts_rate; |
@@ -319,7 +331,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, | |||
319 | if (rts_rate_fb_ofdm) | 331 | if (rts_rate_fb_ofdm) |
320 | mac_ctl |= B43legacy_TX4_MAC_CTSFALLBACKOFDM; | 332 | mac_ctl |= B43legacy_TX4_MAC_CTSFALLBACKOFDM; |
321 | 333 | ||
322 | if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) { | 334 | if (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { |
323 | ieee80211_ctstoself_get(dev->wl->hw, | 335 | ieee80211_ctstoself_get(dev->wl->hw, |
324 | info->control.vif, | 336 | info->control.vif, |
325 | fragment_data, | 337 | fragment_data, |
@@ -362,7 +374,7 @@ int b43legacy_generate_txhdr(struct b43legacy_wldev *dev, | |||
362 | u8 *txhdr, | 374 | u8 *txhdr, |
363 | const unsigned char *fragment_data, | 375 | const unsigned char *fragment_data, |
364 | unsigned int fragment_len, | 376 | unsigned int fragment_len, |
365 | const struct ieee80211_tx_info *info, | 377 | struct ieee80211_tx_info *info, |
366 | u16 cookie) | 378 | u16 cookie) |
367 | { | 379 | { |
368 | return generate_txhdr_fw3(dev, (struct b43legacy_txhdr_fw3 *)txhdr, | 380 | return generate_txhdr_fw3(dev, (struct b43legacy_txhdr_fw3 *)txhdr, |
diff --git a/drivers/net/wireless/b43legacy/xmit.h b/drivers/net/wireless/b43legacy/xmit.h index e56777e0feab..62e09d02788f 100644 --- a/drivers/net/wireless/b43legacy/xmit.h +++ b/drivers/net/wireless/b43legacy/xmit.h | |||
@@ -80,7 +80,7 @@ int b43legacy_generate_txhdr(struct b43legacy_wldev *dev, | |||
80 | u8 *txhdr, | 80 | u8 *txhdr, |
81 | const unsigned char *fragment_data, | 81 | const unsigned char *fragment_data, |
82 | unsigned int fragment_len, | 82 | unsigned int fragment_len, |
83 | const struct ieee80211_tx_info *info, | 83 | struct ieee80211_tx_info *info, |
84 | u16 cookie); | 84 | u16 cookie); |
85 | 85 | ||
86 | 86 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c index c25daec4f93d..f440ed0fe543 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c | |||
@@ -422,34 +422,6 @@ static void rs_free_sta(void *priv, struct ieee80211_sta *sta, | |||
422 | } | 422 | } |
423 | 423 | ||
424 | 424 | ||
425 | /* | ||
426 | * get ieee prev rate from rate scale table. | ||
427 | * for A and B mode we need to overright prev | ||
428 | * value | ||
429 | */ | ||
430 | static int rs_adjust_next_rate(struct iwl3945_priv *priv, int rate) | ||
431 | { | ||
432 | int next_rate = iwl3945_get_prev_ieee_rate(rate); | ||
433 | |||
434 | switch (priv->band) { | ||
435 | case IEEE80211_BAND_5GHZ: | ||
436 | if (rate == IWL_RATE_12M_INDEX) | ||
437 | next_rate = IWL_RATE_9M_INDEX; | ||
438 | else if (rate == IWL_RATE_6M_INDEX) | ||
439 | next_rate = IWL_RATE_6M_INDEX; | ||
440 | break; | ||
441 | /* XXX cannot be invoked in current mac80211 so not a regression | ||
442 | case MODE_IEEE80211B: | ||
443 | if (rate == IWL_RATE_11M_INDEX_TABLE) | ||
444 | next_rate = IWL_RATE_5M_INDEX_TABLE; | ||
445 | break; | ||
446 | */ | ||
447 | default: | ||
448 | break; | ||
449 | } | ||
450 | |||
451 | return next_rate; | ||
452 | } | ||
453 | /** | 425 | /** |
454 | * rs_tx_status - Update rate control values based on Tx results | 426 | * rs_tx_status - Update rate control values based on Tx results |
455 | * | 427 | * |
@@ -460,17 +432,21 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband | |||
460 | struct ieee80211_sta *sta, void *priv_sta, | 432 | struct ieee80211_sta *sta, void *priv_sta, |
461 | struct sk_buff *skb) | 433 | struct sk_buff *skb) |
462 | { | 434 | { |
463 | u8 retries, current_count; | 435 | u8 retries = 0, current_count; |
464 | int scale_rate_index, first_index, last_index; | 436 | int scale_rate_index, first_index, last_index; |
465 | unsigned long flags; | 437 | unsigned long flags; |
466 | struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_rate; | 438 | struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_rate; |
467 | struct iwl3945_rs_sta *rs_sta = priv_sta; | 439 | struct iwl3945_rs_sta *rs_sta = priv_sta; |
468 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 440 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
441 | int i; | ||
469 | 442 | ||
470 | IWL_DEBUG_RATE("enter\n"); | 443 | IWL_DEBUG_RATE("enter\n"); |
471 | 444 | ||
472 | retries = info->status.retry_count; | 445 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) |
473 | first_index = sband->bitrates[info->tx_rate_idx].hw_value; | 446 | retries += info->status.rates[i].count; |
447 | retries--; | ||
448 | |||
449 | first_index = sband->bitrates[info->status.rates[0].idx].hw_value; | ||
474 | if ((first_index < 0) || (first_index >= IWL_RATE_COUNT)) { | 450 | if ((first_index < 0) || (first_index >= IWL_RATE_COUNT)) { |
475 | IWL_DEBUG_RATE("leave: Rate out of bounds: %d\n", first_index); | 451 | IWL_DEBUG_RATE("leave: Rate out of bounds: %d\n", first_index); |
476 | return; | 452 | return; |
@@ -502,7 +478,7 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband | |||
502 | last_index = scale_rate_index; | 478 | last_index = scale_rate_index; |
503 | } else { | 479 | } else { |
504 | current_count = priv->retry_rate; | 480 | current_count = priv->retry_rate; |
505 | last_index = rs_adjust_next_rate(priv, | 481 | last_index = iwl3945_rs_next_rate(priv, |
506 | scale_rate_index); | 482 | scale_rate_index); |
507 | } | 483 | } |
508 | 484 | ||
@@ -518,7 +494,7 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband | |||
518 | 494 | ||
519 | if (retries) | 495 | if (retries) |
520 | scale_rate_index = | 496 | scale_rate_index = |
521 | rs_adjust_next_rate(priv, scale_rate_index); | 497 | iwl3945_rs_next_rate(priv, scale_rate_index); |
522 | } | 498 | } |
523 | 499 | ||
524 | 500 | ||
@@ -630,10 +606,11 @@ static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta, | |||
630 | * rate table and must reference the driver allocated rate table | 606 | * rate table and must reference the driver allocated rate table |
631 | * | 607 | * |
632 | */ | 608 | */ |
633 | static void rs_get_rate(void *priv_r, struct ieee80211_supported_band *sband, | 609 | static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, |
634 | struct ieee80211_sta *sta, void *priv_sta, | 610 | void *priv_sta, struct ieee80211_tx_rate_control *txrc) |
635 | struct sk_buff *skb, struct rate_selection *sel) | ||
636 | { | 611 | { |
612 | struct ieee80211_supported_band *sband = txrc->sband; | ||
613 | struct sk_buff *skb = txrc->skb; | ||
637 | u8 low = IWL_RATE_INVALID; | 614 | u8 low = IWL_RATE_INVALID; |
638 | u8 high = IWL_RATE_INVALID; | 615 | u8 high = IWL_RATE_INVALID; |
639 | u16 high_low; | 616 | u16 high_low; |
@@ -649,6 +626,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_supported_band *sband, | |||
649 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 626 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
650 | u16 fc, rate_mask; | 627 | u16 fc, rate_mask; |
651 | struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_r; | 628 | struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_r; |
629 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
652 | 630 | ||
653 | IWL_DEBUG_RATE("enter\n"); | 631 | IWL_DEBUG_RATE("enter\n"); |
654 | 632 | ||
@@ -659,7 +637,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_supported_band *sband, | |||
659 | is_multicast_ether_addr(hdr->addr1) || | 637 | is_multicast_ether_addr(hdr->addr1) || |
660 | !sta || !priv_sta) { | 638 | !sta || !priv_sta) { |
661 | IWL_DEBUG_RATE("leave: No STA priv data to update!\n"); | 639 | IWL_DEBUG_RATE("leave: No STA priv data to update!\n"); |
662 | sel->rate_idx = rate_lowest_index(sband, sta); | 640 | info->control.rates[0].idx = rate_lowest_index(sband, sta); |
663 | return; | 641 | return; |
664 | } | 642 | } |
665 | 643 | ||
@@ -792,9 +770,10 @@ static void rs_get_rate(void *priv_r, struct ieee80211_supported_band *sband, | |||
792 | 770 | ||
793 | rs_sta->last_txrate_idx = index; | 771 | rs_sta->last_txrate_idx = index; |
794 | if (sband->band == IEEE80211_BAND_5GHZ) | 772 | if (sband->band == IEEE80211_BAND_5GHZ) |
795 | sel->rate_idx = rs_sta->last_txrate_idx - IWL_FIRST_OFDM_RATE; | 773 | info->control.rates[0].idx = rs_sta->last_txrate_idx - |
774 | IWL_FIRST_OFDM_RATE; | ||
796 | else | 775 | else |
797 | sel->rate_idx = rs_sta->last_txrate_idx; | 776 | info->control.rates[0].idx = rs_sta->last_txrate_idx; |
798 | 777 | ||
799 | IWL_DEBUG_RATE("leave: %d\n", index); | 778 | IWL_DEBUG_RATE("leave: %d\n", index); |
800 | } | 779 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 8a00245be51e..7afafb629706 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
@@ -261,6 +261,35 @@ static inline const char *iwl3945_get_tx_fail_reason(u32 status) | |||
261 | } | 261 | } |
262 | #endif | 262 | #endif |
263 | 263 | ||
264 | /* | ||
265 | * get ieee prev rate from rate scale table. | ||
266 | * for A and B mode we need to overright prev | ||
267 | * value | ||
268 | */ | ||
269 | int iwl3945_rs_next_rate(struct iwl3945_priv *priv, int rate) | ||
270 | { | ||
271 | int next_rate = iwl3945_get_prev_ieee_rate(rate); | ||
272 | |||
273 | switch (priv->band) { | ||
274 | case IEEE80211_BAND_5GHZ: | ||
275 | if (rate == IWL_RATE_12M_INDEX) | ||
276 | next_rate = IWL_RATE_9M_INDEX; | ||
277 | else if (rate == IWL_RATE_6M_INDEX) | ||
278 | next_rate = IWL_RATE_6M_INDEX; | ||
279 | break; | ||
280 | /* XXX cannot be invoked in current mac80211 so not a regression | ||
281 | case MODE_IEEE80211B: | ||
282 | if (rate == IWL_RATE_11M_INDEX_TABLE) | ||
283 | next_rate = IWL_RATE_5M_INDEX_TABLE; | ||
284 | break; | ||
285 | */ | ||
286 | default: | ||
287 | break; | ||
288 | } | ||
289 | |||
290 | return next_rate; | ||
291 | } | ||
292 | |||
264 | 293 | ||
265 | /** | 294 | /** |
266 | * iwl3945_tx_queue_reclaim - Reclaim Tx queue entries already Tx'd | 295 | * iwl3945_tx_queue_reclaim - Reclaim Tx queue entries already Tx'd |
@@ -308,6 +337,7 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv, | |||
308 | struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; | 337 | struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; |
309 | u32 status = le32_to_cpu(tx_resp->status); | 338 | u32 status = le32_to_cpu(tx_resp->status); |
310 | int rate_idx; | 339 | int rate_idx; |
340 | int fail, i; | ||
311 | 341 | ||
312 | if ((index >= txq->q.n_bd) || (iwl3945_x2_queue_used(&txq->q, index) == 0)) { | 342 | if ((index >= txq->q.n_bd) || (iwl3945_x2_queue_used(&txq->q, index) == 0)) { |
313 | IWL_ERROR("Read index for DMA queue txq_id (%d) index %d " | 343 | IWL_ERROR("Read index for DMA queue txq_id (%d) index %d " |
@@ -318,9 +348,36 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv, | |||
318 | } | 348 | } |
319 | 349 | ||
320 | info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]); | 350 | info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]); |
321 | memset(&info->status, 0, sizeof(info->status)); | 351 | ieee80211_tx_info_clear_status(info); |
352 | |||
353 | /* Fill the MRR chain with some info about on-chip retransmissions */ | ||
354 | rate_idx = iwl3945_hwrate_to_plcp_idx(tx_resp->rate); | ||
355 | if (info->band == IEEE80211_BAND_5GHZ) | ||
356 | rate_idx -= IWL_FIRST_OFDM_RATE; | ||
357 | |||
358 | fail = tx_resp->failure_frame; | ||
359 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { | ||
360 | int next = iwl3945_rs_next_rate(priv, rate_idx); | ||
361 | |||
362 | info->status.rates[i].idx = rate_idx; | ||
363 | |||
364 | /* | ||
365 | * Put remaining into the last count as best approximation | ||
366 | * of saying exactly what the hardware would have done... | ||
367 | */ | ||
368 | if ((rate_idx == next) || (i == IEEE80211_TX_MAX_RATES - 1)) { | ||
369 | info->status.rates[i].count = fail; | ||
370 | break; | ||
371 | } | ||
372 | |||
373 | info->status.rates[i].count = priv->retry_rate; | ||
374 | fail -= priv->retry_rate; | ||
375 | rate_idx = next; | ||
376 | if (fail <= 0) | ||
377 | break; | ||
378 | } | ||
379 | info->status.rates[i].count++; /* add final attempt */ | ||
322 | 380 | ||
323 | info->status.retry_count = tx_resp->failure_frame; | ||
324 | /* tx_status->rts_retry_count = tx_resp->failure_rts; */ | 381 | /* tx_status->rts_retry_count = tx_resp->failure_rts; */ |
325 | info->flags |= ((status & TX_STATUS_MSK) == TX_STATUS_SUCCESS) ? | 382 | info->flags |= ((status & TX_STATUS_MSK) == TX_STATUS_SUCCESS) ? |
326 | IEEE80211_TX_STAT_ACK : 0; | 383 | IEEE80211_TX_STAT_ACK : 0; |
@@ -329,10 +386,6 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv, | |||
329 | txq_id, iwl3945_get_tx_fail_reason(status), status, | 386 | txq_id, iwl3945_get_tx_fail_reason(status), status, |
330 | tx_resp->rate, tx_resp->failure_frame); | 387 | tx_resp->rate, tx_resp->failure_frame); |
331 | 388 | ||
332 | rate_idx = iwl3945_hwrate_to_plcp_idx(tx_resp->rate); | ||
333 | if (info->band == IEEE80211_BAND_5GHZ) | ||
334 | rate_idx -= IWL_FIRST_OFDM_RATE; | ||
335 | info->tx_rate_idx = rate_idx; | ||
336 | IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index); | 389 | IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index); |
337 | iwl3945_tx_queue_reclaim(priv, txq_id, index); | 390 | iwl3945_tx_queue_reclaim(priv, txq_id, index); |
338 | 391 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index bdd32475b99c..592c5958723b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h | |||
@@ -954,6 +954,8 @@ static inline int is_channel_ibss(const struct iwl3945_channel_info *ch) | |||
954 | extern const struct iwl3945_channel_info *iwl3945_get_channel_info( | 954 | extern const struct iwl3945_channel_info *iwl3945_get_channel_info( |
955 | const struct iwl3945_priv *priv, enum ieee80211_band band, u16 channel); | 955 | const struct iwl3945_priv *priv, enum ieee80211_band band, u16 channel); |
956 | 956 | ||
957 | extern int iwl3945_rs_next_rate(struct iwl3945_priv *priv, int rate); | ||
958 | |||
957 | /* Requires full declaration of iwl3945_priv before including */ | 959 | /* Requires full declaration of iwl3945_priv before including */ |
958 | #include "iwl-3945-io.h" | 960 | #include "iwl-3945-io.h" |
959 | 961 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 9838de5f4369..222c2baa95ca 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -619,10 +619,10 @@ static void iwl4965_gain_computation(struct iwl_priv *priv, | |||
619 | static void iwl4965_rts_tx_cmd_flag(struct ieee80211_tx_info *info, | 619 | static void iwl4965_rts_tx_cmd_flag(struct ieee80211_tx_info *info, |
620 | __le32 *tx_flags) | 620 | __le32 *tx_flags) |
621 | { | 621 | { |
622 | if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) { | 622 | if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) { |
623 | *tx_flags |= TX_CMD_FLG_RTS_MSK; | 623 | *tx_flags |= TX_CMD_FLG_RTS_MSK; |
624 | *tx_flags &= ~TX_CMD_FLG_CTS_MSK; | 624 | *tx_flags &= ~TX_CMD_FLG_CTS_MSK; |
625 | } else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) { | 625 | } else if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { |
626 | *tx_flags &= ~TX_CMD_FLG_RTS_MSK; | 626 | *tx_flags &= ~TX_CMD_FLG_RTS_MSK; |
627 | *tx_flags |= TX_CMD_FLG_CTS_MSK; | 627 | *tx_flags |= TX_CMD_FLG_CTS_MSK; |
628 | } | 628 | } |
@@ -2070,7 +2070,7 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, | |||
2070 | agg->frame_count, agg->start_idx, idx); | 2070 | agg->frame_count, agg->start_idx, idx); |
2071 | 2071 | ||
2072 | info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb[0]); | 2072 | info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb[0]); |
2073 | info->status.retry_count = tx_resp->failure_frame; | 2073 | info->status.rates[0].count = tx_resp->failure_frame + 1; |
2074 | info->flags &= ~IEEE80211_TX_CTL_AMPDU; | 2074 | info->flags &= ~IEEE80211_TX_CTL_AMPDU; |
2075 | info->flags |= iwl_is_tx_success(status)? | 2075 | info->flags |= iwl_is_tx_success(status)? |
2076 | IEEE80211_TX_STAT_ACK : 0; | 2076 | IEEE80211_TX_STAT_ACK : 0; |
@@ -2227,7 +2227,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, | |||
2227 | iwl_txq_check_empty(priv, sta_id, tid, txq_id); | 2227 | iwl_txq_check_empty(priv, sta_id, tid, txq_id); |
2228 | } | 2228 | } |
2229 | } else { | 2229 | } else { |
2230 | info->status.retry_count = tx_resp->failure_frame; | 2230 | info->status.rates[0].count = tx_resp->failure_frame + 1; |
2231 | info->flags |= | 2231 | info->flags |= |
2232 | iwl_is_tx_success(status) ? IEEE80211_TX_STAT_ACK : 0; | 2232 | iwl_is_tx_success(status) ? IEEE80211_TX_STAT_ACK : 0; |
2233 | iwl_hwrate_to_tx_control(priv, | 2233 | iwl_hwrate_to_tx_control(priv, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 56a3f0c84a1e..d5282fa65084 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -390,8 +390,8 @@ static void iwl5000_chain_noise_reset(struct iwl_priv *priv) | |||
390 | static void iwl5000_rts_tx_cmd_flag(struct ieee80211_tx_info *info, | 390 | static void iwl5000_rts_tx_cmd_flag(struct ieee80211_tx_info *info, |
391 | __le32 *tx_flags) | 391 | __le32 *tx_flags) |
392 | { | 392 | { |
393 | if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) || | 393 | if ((info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) || |
394 | (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) | 394 | (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) |
395 | *tx_flags |= TX_CMD_FLG_RTS_CTS_MSK; | 395 | *tx_flags |= TX_CMD_FLG_RTS_CTS_MSK; |
396 | else | 396 | else |
397 | *tx_flags &= ~TX_CMD_FLG_RTS_CTS_MSK; | 397 | *tx_flags &= ~TX_CMD_FLG_RTS_CTS_MSK; |
@@ -1154,7 +1154,7 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv, | |||
1154 | agg->frame_count, agg->start_idx, idx); | 1154 | agg->frame_count, agg->start_idx, idx); |
1155 | 1155 | ||
1156 | info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb[0]); | 1156 | info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb[0]); |
1157 | info->status.retry_count = tx_resp->failure_frame; | 1157 | info->status.rates[0].count = tx_resp->failure_frame + 1; |
1158 | info->flags &= ~IEEE80211_TX_CTL_AMPDU; | 1158 | info->flags &= ~IEEE80211_TX_CTL_AMPDU; |
1159 | info->flags |= iwl_is_tx_success(status)? | 1159 | info->flags |= iwl_is_tx_success(status)? |
1160 | IEEE80211_TX_STAT_ACK : 0; | 1160 | IEEE80211_TX_STAT_ACK : 0; |
@@ -1307,7 +1307,7 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv, | |||
1307 | iwl_txq_check_empty(priv, sta_id, tid, txq_id); | 1307 | iwl_txq_check_empty(priv, sta_id, tid, txq_id); |
1308 | } | 1308 | } |
1309 | } else { | 1309 | } else { |
1310 | info->status.retry_count = tx_resp->failure_frame; | 1310 | info->status.rates[0].count = tx_resp->failure_frame + 1; |
1311 | info->flags = | 1311 | info->flags = |
1312 | iwl_is_tx_success(status) ? IEEE80211_TX_STAT_ACK : 0; | 1312 | iwl_is_tx_success(status) ? IEEE80211_TX_STAT_ACK : 0; |
1313 | iwl_hwrate_to_tx_control(priv, | 1313 | iwl_hwrate_to_tx_control(priv, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index e10e0ca09ce9..f685e5d6c281 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c | |||
@@ -798,7 +798,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, | |||
798 | !(info->flags & IEEE80211_TX_STAT_AMPDU)) | 798 | !(info->flags & IEEE80211_TX_STAT_AMPDU)) |
799 | return; | 799 | return; |
800 | 800 | ||
801 | retries = info->status.retry_count; | 801 | retries = info->status.rates[0].count - 1; |
802 | 802 | ||
803 | if (retries > 15) | 803 | if (retries > 15) |
804 | retries = 15; | 804 | retries = 15; |
@@ -830,20 +830,15 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, | |||
830 | if (priv->band == IEEE80211_BAND_5GHZ) | 830 | if (priv->band == IEEE80211_BAND_5GHZ) |
831 | rs_index -= IWL_FIRST_OFDM_RATE; | 831 | rs_index -= IWL_FIRST_OFDM_RATE; |
832 | 832 | ||
833 | if ((info->tx_rate_idx < 0) || | 833 | if ((info->status.rates[0].idx < 0) || |
834 | (tbl_type.is_SGI ^ | 834 | (tbl_type.is_SGI != !!(info->status.rates[0].flags & IEEE80211_TX_RC_SHORT_GI)) || |
835 | !!(info->flags & IEEE80211_TX_CTL_SHORT_GI)) || | 835 | (tbl_type.is_fat != !!(info->status.rates[0].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)) || |
836 | (tbl_type.is_fat ^ | 836 | (tbl_type.is_dup != !!(info->status.rates[0].flags & IEEE80211_TX_RC_DUP_DATA)) || |
837 | !!(info->flags & IEEE80211_TX_CTL_40_MHZ_WIDTH)) || | 837 | (tbl_type.ant_type != info->antenna_sel_tx) || |
838 | (tbl_type.is_dup ^ | 838 | (!!(tx_rate & RATE_MCS_HT_MSK) != !!(info->status.rates[0].flags & IEEE80211_TX_RC_MCS)) || |
839 | !!(info->flags & IEEE80211_TX_CTL_DUP_DATA)) || | 839 | (!!(tx_rate & RATE_MCS_GF_MSK) != !!(info->status.rates[0].flags & IEEE80211_TX_RC_GREEN_FIELD)) || |
840 | (tbl_type.ant_type ^ info->antenna_sel_tx) || | ||
841 | (!!(tx_rate & RATE_MCS_HT_MSK) ^ | ||
842 | !!(info->flags & IEEE80211_TX_CTL_OFDM_HT)) || | ||
843 | (!!(tx_rate & RATE_MCS_GF_MSK) ^ | ||
844 | !!(info->flags & IEEE80211_TX_CTL_GREEN_FIELD)) || | ||
845 | (hw->wiphy->bands[priv->band]->bitrates[rs_index].bitrate != | 840 | (hw->wiphy->bands[priv->band]->bitrates[rs_index].bitrate != |
846 | hw->wiphy->bands[info->band]->bitrates[info->tx_rate_idx].bitrate)) { | 841 | hw->wiphy->bands[info->band]->bitrates[info->status.rates[0].idx].bitrate)) { |
847 | IWL_DEBUG_RATE("initial rate does not match 0x%x\n", tx_rate); | 842 | IWL_DEBUG_RATE("initial rate does not match 0x%x\n", tx_rate); |
848 | goto out; | 843 | goto out; |
849 | } | 844 | } |
@@ -2098,15 +2093,17 @@ static void rs_initialize_lq(struct iwl_priv *priv, | |||
2098 | return; | 2093 | return; |
2099 | } | 2094 | } |
2100 | 2095 | ||
2101 | static void rs_get_rate(void *priv_r, struct ieee80211_supported_band *sband, | 2096 | static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta, |
2102 | struct ieee80211_sta *sta, void *priv_sta, | 2097 | struct ieee80211_tx_rate_control *txrc) |
2103 | struct sk_buff *skb, struct rate_selection *sel) | ||
2104 | { | 2098 | { |
2105 | 2099 | ||
2106 | int i; | 2100 | int i; |
2101 | struct sk_buff *skb = txrc->skb; | ||
2102 | struct ieee80211_supported_band *sband = txrc->sband; | ||
2107 | struct iwl_priv *priv = (struct iwl_priv *)priv_r; | 2103 | struct iwl_priv *priv = (struct iwl_priv *)priv_r; |
2108 | struct ieee80211_conf *conf = &priv->hw->conf; | 2104 | struct ieee80211_conf *conf = &priv->hw->conf; |
2109 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 2105 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
2106 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
2110 | __le16 fc; | 2107 | __le16 fc; |
2111 | struct iwl_lq_sta *lq_sta; | 2108 | struct iwl_lq_sta *lq_sta; |
2112 | 2109 | ||
@@ -2117,7 +2114,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_supported_band *sband, | |||
2117 | fc = hdr->frame_control; | 2114 | fc = hdr->frame_control; |
2118 | if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) || | 2115 | if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) || |
2119 | !sta || !priv_sta) { | 2116 | !sta || !priv_sta) { |
2120 | sel->rate_idx = rate_lowest_index(sband, sta); | 2117 | info->control.rates[0].idx = rate_lowest_index(sband, sta); |
2121 | return; | 2118 | return; |
2122 | } | 2119 | } |
2123 | 2120 | ||
@@ -2143,13 +2140,13 @@ static void rs_get_rate(void *priv_r, struct ieee80211_supported_band *sband, | |||
2143 | } | 2140 | } |
2144 | 2141 | ||
2145 | if ((i < 0) || (i > IWL_RATE_COUNT)) { | 2142 | if ((i < 0) || (i > IWL_RATE_COUNT)) { |
2146 | sel->rate_idx = rate_lowest_index(sband, sta); | 2143 | info->control.rates[0].idx = rate_lowest_index(sband, sta); |
2147 | return; | 2144 | return; |
2148 | } | 2145 | } |
2149 | 2146 | ||
2150 | if (sband->band == IEEE80211_BAND_5GHZ) | 2147 | if (sband->band == IEEE80211_BAND_5GHZ) |
2151 | i -= IWL_FIRST_OFDM_RATE; | 2148 | i -= IWL_FIRST_OFDM_RATE; |
2152 | sel->rate_idx = i; | 2149 | info->control.rates[0].idx = i; |
2153 | } | 2150 | } |
2154 | 2151 | ||
2155 | static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta, | 2152 | static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 10f5a0a233fe..2c4162e48140 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -88,26 +88,27 @@ EXPORT_SYMBOL(iwl_rates); | |||
88 | * translate ucode response to mac80211 tx status control values | 88 | * translate ucode response to mac80211 tx status control values |
89 | */ | 89 | */ |
90 | void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags, | 90 | void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags, |
91 | struct ieee80211_tx_info *control) | 91 | struct ieee80211_tx_info *info) |
92 | { | 92 | { |
93 | int rate_index; | 93 | int rate_index; |
94 | struct ieee80211_tx_rate *r = &info->control.rates[0]; | ||
94 | 95 | ||
95 | control->antenna_sel_tx = | 96 | info->antenna_sel_tx = |
96 | ((rate_n_flags & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS); | 97 | ((rate_n_flags & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS); |
97 | if (rate_n_flags & RATE_MCS_HT_MSK) | 98 | if (rate_n_flags & RATE_MCS_HT_MSK) |
98 | control->flags |= IEEE80211_TX_CTL_OFDM_HT; | 99 | r->flags |= IEEE80211_TX_RC_MCS; |
99 | if (rate_n_flags & RATE_MCS_GF_MSK) | 100 | if (rate_n_flags & RATE_MCS_GF_MSK) |
100 | control->flags |= IEEE80211_TX_CTL_GREEN_FIELD; | 101 | r->flags |= IEEE80211_TX_RC_GREEN_FIELD; |
101 | if (rate_n_flags & RATE_MCS_FAT_MSK) | 102 | if (rate_n_flags & RATE_MCS_FAT_MSK) |
102 | control->flags |= IEEE80211_TX_CTL_40_MHZ_WIDTH; | 103 | r->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; |
103 | if (rate_n_flags & RATE_MCS_DUP_MSK) | 104 | if (rate_n_flags & RATE_MCS_DUP_MSK) |
104 | control->flags |= IEEE80211_TX_CTL_DUP_DATA; | 105 | r->flags |= IEEE80211_TX_RC_DUP_DATA; |
105 | if (rate_n_flags & RATE_MCS_SGI_MSK) | 106 | if (rate_n_flags & RATE_MCS_SGI_MSK) |
106 | control->flags |= IEEE80211_TX_CTL_SHORT_GI; | 107 | r->flags |= IEEE80211_TX_RC_SHORT_GI; |
107 | rate_index = iwl_hwrate_to_plcp_idx(rate_n_flags); | 108 | rate_index = iwl_hwrate_to_plcp_idx(rate_n_flags); |
108 | if (control->band == IEEE80211_BAND_5GHZ) | 109 | if (info->band == IEEE80211_BAND_5GHZ) |
109 | rate_index -= IWL_FIRST_OFDM_RATE; | 110 | rate_index -= IWL_FIRST_OFDM_RATE; |
110 | control->tx_rate_idx = rate_index; | 111 | r->idx = rate_index; |
111 | } | 112 | } |
112 | EXPORT_SYMBOL(iwl_hwrate_to_tx_control); | 113 | EXPORT_SYMBOL(iwl_hwrate_to_tx_control); |
113 | 114 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index b1464c71ea0a..2cd33b4e9e13 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -2395,6 +2395,7 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv, | |||
2395 | { | 2395 | { |
2396 | __le16 fc = hdr->frame_control; | 2396 | __le16 fc = hdr->frame_control; |
2397 | __le32 tx_flags = cmd->cmd.tx.tx_flags; | 2397 | __le32 tx_flags = cmd->cmd.tx.tx_flags; |
2398 | u8 rc_flags = info->control.rates[0].flags; | ||
2398 | 2399 | ||
2399 | cmd->cmd.tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; | 2400 | cmd->cmd.tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; |
2400 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { | 2401 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { |
@@ -2421,10 +2422,10 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv, | |||
2421 | tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; | 2422 | tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; |
2422 | } | 2423 | } |
2423 | 2424 | ||
2424 | if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) { | 2425 | if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS) { |
2425 | tx_flags |= TX_CMD_FLG_RTS_MSK; | 2426 | tx_flags |= TX_CMD_FLG_RTS_MSK; |
2426 | tx_flags &= ~TX_CMD_FLG_CTS_MSK; | 2427 | tx_flags &= ~TX_CMD_FLG_CTS_MSK; |
2427 | } else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) { | 2428 | } else if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { |
2428 | tx_flags &= ~TX_CMD_FLG_RTS_MSK; | 2429 | tx_flags &= ~TX_CMD_FLG_RTS_MSK; |
2429 | tx_flags |= TX_CMD_FLG_CTS_MSK; | 2430 | tx_flags |= TX_CMD_FLG_CTS_MSK; |
2430 | } | 2431 | } |
diff --git a/drivers/net/wireless/libertas_tf/main.c b/drivers/net/wireless/libertas_tf/main.c index 241ddcfa352e..d1fc305de5fe 100644 --- a/drivers/net/wireless/libertas_tf/main.c +++ b/drivers/net/wireless/libertas_tf/main.c | |||
@@ -592,14 +592,14 @@ EXPORT_SYMBOL_GPL(lbtf_remove_card); | |||
592 | void lbtf_send_tx_feedback(struct lbtf_private *priv, u8 retrycnt, u8 fail) | 592 | void lbtf_send_tx_feedback(struct lbtf_private *priv, u8 retrycnt, u8 fail) |
593 | { | 593 | { |
594 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(priv->tx_skb); | 594 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(priv->tx_skb); |
595 | memset(&info->status, 0, sizeof(info->status)); | 595 | |
596 | ieee80211_tx_info_clear_status(info); | ||
596 | /* | 597 | /* |
597 | * Commented out, otherwise we never go beyond 1Mbit/s using mac80211 | 598 | * Commented out, otherwise we never go beyond 1Mbit/s using mac80211 |
598 | * default pid rc algorithm. | 599 | * default pid rc algorithm. |
599 | * | 600 | * |
600 | * info->status.retry_count = MRVL_DEFAULT_RETRIES - retrycnt; | 601 | * info->status.retry_count = MRVL_DEFAULT_RETRIES - retrycnt; |
601 | */ | 602 | */ |
602 | info->status.excessive_retries = fail ? 1 : 0; | ||
603 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && !fail) | 603 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && !fail) |
604 | info->flags |= IEEE80211_TX_STAT_ACK; | 604 | info->flags |= IEEE80211_TX_STAT_ACK; |
605 | skb_pull(priv->tx_skb, sizeof(struct txpd)); | 605 | skb_pull(priv->tx_skb, sizeof(struct txpd)); |
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index e2aeef8de707..c57652325286 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
@@ -209,7 +209,7 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, | |||
209 | /* TODO: set mactime */ | 209 | /* TODO: set mactime */ |
210 | rx_status.freq = data->channel->center_freq; | 210 | rx_status.freq = data->channel->center_freq; |
211 | rx_status.band = data->channel->band; | 211 | rx_status.band = data->channel->band; |
212 | rx_status.rate_idx = info->tx_rate_idx; | 212 | rx_status.rate_idx = info->control.rates[0].idx; |
213 | /* TODO: simulate signal strength (and optional packet drop) */ | 213 | /* TODO: simulate signal strength (and optional packet drop) */ |
214 | 214 | ||
215 | /* Copy skb to all enabled radios that are on the current frequency */ | 215 | /* Copy skb to all enabled radios that are on the current frequency */ |
@@ -269,13 +269,9 @@ static int mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
269 | if (txi->control.sta) | 269 | if (txi->control.sta) |
270 | hwsim_check_sta_magic(txi->control.sta); | 270 | hwsim_check_sta_magic(txi->control.sta); |
271 | 271 | ||
272 | memset(&txi->status, 0, sizeof(txi->status)); | 272 | ieee80211_tx_info_clear_status(txi); |
273 | if (!(txi->flags & IEEE80211_TX_CTL_NO_ACK)) { | 273 | if (!(txi->flags & IEEE80211_TX_CTL_NO_ACK) && ack) |
274 | if (ack) | 274 | txi->flags |= IEEE80211_TX_STAT_ACK; |
275 | txi->flags |= IEEE80211_TX_STAT_ACK; | ||
276 | else | ||
277 | txi->status.excessive_retries = 1; | ||
278 | } | ||
279 | ieee80211_tx_status_irqsafe(hw, skb); | 275 | ieee80211_tx_status_irqsafe(hw, skb); |
280 | return NETDEV_TX_OK; | 276 | return NETDEV_TX_OK; |
281 | } | 277 | } |
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index 81a9756254fb..65be5eca2340 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c | |||
@@ -548,7 +548,7 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
548 | spin_lock_irqsave(&priv->tx_queue.lock, flags); | 548 | spin_lock_irqsave(&priv->tx_queue.lock, flags); |
549 | while (entry != (struct sk_buff *)&priv->tx_queue) { | 549 | while (entry != (struct sk_buff *)&priv->tx_queue) { |
550 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(entry); | 550 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(entry); |
551 | range = (void *)info->driver_data; | 551 | range = (void *)info->rate_driver_data; |
552 | if (range->start_addr == addr) { | 552 | if (range->start_addr == addr) { |
553 | struct p54_control_hdr *entry_hdr; | 553 | struct p54_control_hdr *entry_hdr; |
554 | struct p54_tx_control_allocdata *entry_data; | 554 | struct p54_tx_control_allocdata *entry_data; |
@@ -559,7 +559,7 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
559 | struct memrecord *mr; | 559 | struct memrecord *mr; |
560 | 560 | ||
561 | ni = IEEE80211_SKB_CB(entry->next); | 561 | ni = IEEE80211_SKB_CB(entry->next); |
562 | mr = (struct memrecord *)ni->driver_data; | 562 | mr = (struct memrecord *)ni->rate_driver_data; |
563 | freed = mr->start_addr - last_addr; | 563 | freed = mr->start_addr - last_addr; |
564 | } else | 564 | } else |
565 | freed = priv->rx_end - last_addr; | 565 | freed = priv->rx_end - last_addr; |
@@ -568,7 +568,7 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
568 | __skb_unlink(entry, &priv->tx_queue); | 568 | __skb_unlink(entry, &priv->tx_queue); |
569 | spin_unlock_irqrestore(&priv->tx_queue.lock, flags); | 569 | spin_unlock_irqrestore(&priv->tx_queue.lock, flags); |
570 | 570 | ||
571 | memset(&info->status, 0, sizeof(info->status)); | 571 | ieee80211_tx_info_clear_status(info); |
572 | entry_hdr = (struct p54_control_hdr *) entry->data; | 572 | entry_hdr = (struct p54_control_hdr *) entry->data; |
573 | entry_data = (struct p54_tx_control_allocdata *) entry_hdr->data; | 573 | entry_data = (struct p54_tx_control_allocdata *) entry_hdr->data; |
574 | if ((entry_hdr->magic1 & cpu_to_le16(0x4000)) != 0) | 574 | if ((entry_hdr->magic1 & cpu_to_le16(0x4000)) != 0) |
@@ -578,10 +578,8 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
578 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { | 578 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { |
579 | if (!(payload->status & 0x01)) | 579 | if (!(payload->status & 0x01)) |
580 | info->flags |= IEEE80211_TX_STAT_ACK; | 580 | info->flags |= IEEE80211_TX_STAT_ACK; |
581 | else | ||
582 | info->status.excessive_retries = 1; | ||
583 | } | 581 | } |
584 | info->status.retry_count = payload->retries - 1; | 582 | info->status.rates[0].count = payload->retries; |
585 | info->status.ack_signal = p54_rssi_to_dbm(dev, | 583 | info->status.ack_signal = p54_rssi_to_dbm(dev, |
586 | le16_to_cpu(payload->ack_rssi)); | 584 | le16_to_cpu(payload->ack_rssi)); |
587 | skb_pull(entry, sizeof(*hdr) + pad + sizeof(*entry_data)); | 585 | skb_pull(entry, sizeof(*hdr) + pad + sizeof(*entry_data)); |
@@ -699,7 +697,7 @@ static void p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
699 | while (left--) { | 697 | while (left--) { |
700 | u32 hole_size; | 698 | u32 hole_size; |
701 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(entry); | 699 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(entry); |
702 | struct memrecord *range = (void *)info->driver_data; | 700 | struct memrecord *range = (void *)info->rate_driver_data; |
703 | hole_size = range->start_addr - last_addr; | 701 | hole_size = range->start_addr - last_addr; |
704 | if (!target_skb && hole_size >= len) { | 702 | if (!target_skb && hole_size >= len) { |
705 | target_skb = entry->prev; | 703 | target_skb = entry->prev; |
@@ -715,7 +713,7 @@ static void p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
715 | largest_hole = max(largest_hole, priv->rx_end - last_addr - len); | 713 | largest_hole = max(largest_hole, priv->rx_end - last_addr - len); |
716 | if (!skb_queue_empty(&priv->tx_queue)) { | 714 | if (!skb_queue_empty(&priv->tx_queue)) { |
717 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(target_skb); | 715 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(target_skb); |
718 | struct memrecord *range = (void *)info->driver_data; | 716 | struct memrecord *range = (void *)info->rate_driver_data; |
719 | target_addr = range->end_addr; | 717 | target_addr = range->end_addr; |
720 | } | 718 | } |
721 | } else | 719 | } else |
@@ -723,7 +721,7 @@ static void p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
723 | 721 | ||
724 | if (skb) { | 722 | if (skb) { |
725 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 723 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
726 | struct memrecord *range = (void *)info->driver_data; | 724 | struct memrecord *range = (void *)info->rate_driver_data; |
727 | range->start_addr = target_addr; | 725 | range->start_addr = target_addr; |
728 | range->end_addr = target_addr + len; | 726 | range->end_addr = target_addr + len; |
729 | __skb_queue_after(&priv->tx_queue, target_skb, skb); | 727 | __skb_queue_after(&priv->tx_queue, target_skb, skb); |
@@ -806,6 +804,7 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
806 | size_t padding, len; | 804 | size_t padding, len; |
807 | u8 rate; | 805 | u8 rate; |
808 | u8 cts_rate = 0x20; | 806 | u8 cts_rate = 0x20; |
807 | u8 rc_flags; | ||
809 | 808 | ||
810 | current_queue = &priv->tx_stats[skb_get_queue_mapping(skb) + 4]; | 809 | current_queue = &priv->tx_stats[skb_get_queue_mapping(skb) + 4]; |
811 | if (unlikely(current_queue->len > current_queue->limit)) | 810 | if (unlikely(current_queue->len > current_queue->limit)) |
@@ -828,18 +827,19 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
828 | hdr->magic1 = cpu_to_le16(0x0010); | 827 | hdr->magic1 = cpu_to_le16(0x0010); |
829 | hdr->len = cpu_to_le16(len); | 828 | hdr->len = cpu_to_le16(len); |
830 | hdr->type = (info->flags & IEEE80211_TX_CTL_NO_ACK) ? 0 : cpu_to_le16(1); | 829 | hdr->type = (info->flags & IEEE80211_TX_CTL_NO_ACK) ? 0 : cpu_to_le16(1); |
831 | hdr->retry1 = hdr->retry2 = info->control.retry_limit; | 830 | hdr->retry1 = hdr->retry2 = info->control.rates[0].count; |
832 | 831 | ||
833 | /* TODO: add support for alternate retry TX rates */ | 832 | /* TODO: add support for alternate retry TX rates */ |
834 | rate = ieee80211_get_tx_rate(dev, info)->hw_value; | 833 | rate = ieee80211_get_tx_rate(dev, info)->hw_value; |
835 | if (info->flags & IEEE80211_TX_CTL_SHORT_PREAMBLE) { | 834 | rc_flags = info->control.rates[0].flags; |
835 | if (rc_flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) { | ||
836 | rate |= 0x10; | 836 | rate |= 0x10; |
837 | cts_rate |= 0x10; | 837 | cts_rate |= 0x10; |
838 | } | 838 | } |
839 | if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) { | 839 | if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS) { |
840 | rate |= 0x40; | 840 | rate |= 0x40; |
841 | cts_rate |= ieee80211_get_rts_cts_rate(dev, info)->hw_value; | 841 | cts_rate |= ieee80211_get_rts_cts_rate(dev, info)->hw_value; |
842 | } else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) { | 842 | } else if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { |
843 | rate |= 0x20; | 843 | rate |= 0x20; |
844 | cts_rate |= ieee80211_get_rts_cts_rate(dev, info)->hw_value; | 844 | cts_rate |= ieee80211_get_rts_cts_rate(dev, info)->hw_value; |
845 | } | 845 | } |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 697806cf94e2..e1feab8b6b02 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -498,7 +498,9 @@ void rt2x00lib_txdone(struct queue_entry *entry, | |||
498 | { | 498 | { |
499 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 499 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
500 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); | 500 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); |
501 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | ||
501 | enum data_queue_qid qid = skb_get_queue_mapping(entry->skb); | 502 | enum data_queue_qid qid = skb_get_queue_mapping(entry->skb); |
503 | u8 rate_idx, rate_flags; | ||
502 | 504 | ||
503 | /* | 505 | /* |
504 | * Unmap the skb. | 506 | * Unmap the skb. |
@@ -528,14 +530,18 @@ void rt2x00lib_txdone(struct queue_entry *entry, | |||
528 | rt2x00dev->link.qual.tx_failed += | 530 | rt2x00dev->link.qual.tx_failed += |
529 | test_bit(TXDONE_FAILURE, &txdesc->flags); | 531 | test_bit(TXDONE_FAILURE, &txdesc->flags); |
530 | 532 | ||
533 | rate_idx = skbdesc->tx_rate_idx; | ||
534 | rate_flags = skbdesc->tx_rate_flags; | ||
535 | |||
531 | /* | 536 | /* |
532 | * Initialize TX status | 537 | * Initialize TX status |
533 | */ | 538 | */ |
534 | memset(&tx_info->status, 0, sizeof(tx_info->status)); | 539 | memset(&tx_info->status, 0, sizeof(tx_info->status)); |
535 | tx_info->status.ack_signal = 0; | 540 | tx_info->status.ack_signal = 0; |
536 | tx_info->status.excessive_retries = | 541 | tx_info->status.rates[0].idx = rate_idx; |
537 | test_bit(TXDONE_EXCESSIVE_RETRY, &txdesc->flags); | 542 | tx_info->status.rates[0].flags = rate_flags; |
538 | tx_info->status.retry_count = txdesc->retry; | 543 | tx_info->status.rates[0].count = txdesc->retry + 1; |
544 | tx_info->status.rates[1].idx = -1; /* terminate */ | ||
539 | 545 | ||
540 | if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) { | 546 | if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) { |
541 | if (test_bit(TXDONE_SUCCESS, &txdesc->flags)) | 547 | if (test_bit(TXDONE_SUCCESS, &txdesc->flags)) |
@@ -544,7 +550,7 @@ void rt2x00lib_txdone(struct queue_entry *entry, | |||
544 | rt2x00dev->low_level_stats.dot11ACKFailureCount++; | 550 | rt2x00dev->low_level_stats.dot11ACKFailureCount++; |
545 | } | 551 | } |
546 | 552 | ||
547 | if (tx_info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) { | 553 | if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) { |
548 | if (test_bit(TXDONE_SUCCESS, &txdesc->flags)) | 554 | if (test_bit(TXDONE_SUCCESS, &txdesc->flags)) |
549 | rt2x00dev->low_level_stats.dot11RTSSuccessCount++; | 555 | rt2x00dev->low_level_stats.dot11RTSSuccessCount++; |
550 | else if (test_bit(TXDONE_FAILURE, &txdesc->flags)) | 556 | else if (test_bit(TXDONE_FAILURE, &txdesc->flags)) |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 931183369f07..b32d59eafaa3 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -39,7 +39,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, | |||
39 | unsigned int data_length; | 39 | unsigned int data_length; |
40 | int retval = 0; | 40 | int retval = 0; |
41 | 41 | ||
42 | if (tx_info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) | 42 | if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) |
43 | data_length = sizeof(struct ieee80211_cts); | 43 | data_length = sizeof(struct ieee80211_cts); |
44 | else | 44 | else |
45 | data_length = sizeof(struct ieee80211_rts); | 45 | data_length = sizeof(struct ieee80211_rts); |
@@ -64,11 +64,11 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, | |||
64 | */ | 64 | */ |
65 | memcpy(skb->cb, frag_skb->cb, sizeof(skb->cb)); | 65 | memcpy(skb->cb, frag_skb->cb, sizeof(skb->cb)); |
66 | rts_info = IEEE80211_SKB_CB(skb); | 66 | rts_info = IEEE80211_SKB_CB(skb); |
67 | rts_info->flags &= ~IEEE80211_TX_CTL_USE_RTS_CTS; | 67 | rts_info->control.rates[0].flags &= ~IEEE80211_TX_RC_USE_RTS_CTS; |
68 | rts_info->flags &= ~IEEE80211_TX_CTL_USE_CTS_PROTECT; | 68 | rts_info->control.rates[0].flags &= ~IEEE80211_TX_RC_USE_CTS_PROTECT; |
69 | rts_info->flags &= ~IEEE80211_TX_CTL_REQ_TX_STATUS; | 69 | rts_info->flags &= ~IEEE80211_TX_CTL_REQ_TX_STATUS; |
70 | 70 | ||
71 | if (tx_info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) | 71 | if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) |
72 | rts_info->flags |= IEEE80211_TX_CTL_NO_ACK; | 72 | rts_info->flags |= IEEE80211_TX_CTL_NO_ACK; |
73 | else | 73 | else |
74 | rts_info->flags &= ~IEEE80211_TX_CTL_NO_ACK; | 74 | rts_info->flags &= ~IEEE80211_TX_CTL_NO_ACK; |
@@ -84,7 +84,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, | |||
84 | data_length += rt2x00crypto_tx_overhead(tx_info); | 84 | data_length += rt2x00crypto_tx_overhead(tx_info); |
85 | #endif /* CONFIG_RT2X00_LIB_CRYPTO */ | 85 | #endif /* CONFIG_RT2X00_LIB_CRYPTO */ |
86 | 86 | ||
87 | if (tx_info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) | 87 | if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) |
88 | ieee80211_ctstoself_get(rt2x00dev->hw, tx_info->control.vif, | 88 | ieee80211_ctstoself_get(rt2x00dev->hw, tx_info->control.vif, |
89 | frag_skb->data, data_length, tx_info, | 89 | frag_skb->data, data_length, tx_info, |
90 | (struct ieee80211_cts *)(skb->data)); | 90 | (struct ieee80211_cts *)(skb->data)); |
@@ -146,8 +146,8 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
146 | * inside the hardware. | 146 | * inside the hardware. |
147 | */ | 147 | */ |
148 | frame_control = le16_to_cpu(ieee80211hdr->frame_control); | 148 | frame_control = le16_to_cpu(ieee80211hdr->frame_control); |
149 | if ((tx_info->flags & (IEEE80211_TX_CTL_USE_RTS_CTS | | 149 | if ((tx_info->control.rates[0].flags & (IEEE80211_TX_RC_USE_RTS_CTS | |
150 | IEEE80211_TX_CTL_USE_CTS_PROTECT)) && | 150 | IEEE80211_TX_RC_USE_CTS_PROTECT)) && |
151 | !rt2x00dev->ops->hw->set_rts_threshold) { | 151 | !rt2x00dev->ops->hw->set_rts_threshold) { |
152 | if (rt2x00queue_available(queue) <= 1) | 152 | if (rt2x00queue_available(queue) <= 1) |
153 | goto exit_fail; | 153 | goto exit_fail; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 451d410ecdae..070786ebd076 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -230,8 +230,15 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | |||
230 | /* | 230 | /* |
231 | * Determine retry information. | 231 | * Determine retry information. |
232 | */ | 232 | */ |
233 | txdesc->retry_limit = tx_info->control.retry_limit; | 233 | txdesc->retry_limit = tx_info->control.rates[0].count - 1; |
234 | if (tx_info->flags & IEEE80211_TX_CTL_LONG_RETRY_LIMIT) | 234 | /* |
235 | * XXX: If at this point we knew whether the HW is going to use | ||
236 | * the RETRY_MODE bit or the retry_limit (currently all | ||
237 | * use the RETRY_MODE bit) we could do something like b43 | ||
238 | * does, set the RETRY_MODE bit when the RC algorithm is | ||
239 | * requesting more than the long retry limit. | ||
240 | */ | ||
241 | if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) | ||
235 | __set_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags); | 242 | __set_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags); |
236 | 243 | ||
237 | /* | 244 | /* |
@@ -371,10 +378,12 @@ static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, | |||
371 | 378 | ||
372 | int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb) | 379 | int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb) |
373 | { | 380 | { |
381 | struct ieee80211_tx_info *tx_info; | ||
374 | struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); | 382 | struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); |
375 | struct txentry_desc txdesc; | 383 | struct txentry_desc txdesc; |
376 | struct skb_frame_desc *skbdesc; | 384 | struct skb_frame_desc *skbdesc; |
377 | unsigned int iv_len = 0; | 385 | unsigned int iv_len = 0; |
386 | u8 rate_idx, rate_flags; | ||
378 | 387 | ||
379 | if (unlikely(rt2x00queue_full(queue))) | 388 | if (unlikely(rt2x00queue_full(queue))) |
380 | return -EINVAL; | 389 | return -EINVAL; |
@@ -399,13 +408,18 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb) | |||
399 | iv_len = IEEE80211_SKB_CB(skb)->control.hw_key->iv_len; | 408 | iv_len = IEEE80211_SKB_CB(skb)->control.hw_key->iv_len; |
400 | 409 | ||
401 | /* | 410 | /* |
402 | * All information is retreived from the skb->cb array, | 411 | * All information is retrieved from the skb->cb array, |
403 | * now we should claim ownership of the driver part of that | 412 | * now we should claim ownership of the driver part of that |
404 | * array. | 413 | * array, preserving the bitrate index and flags. |
405 | */ | 414 | */ |
415 | tx_info = IEEE80211_SKB_CB(skb); | ||
416 | rate_idx = tx_info->control.rates[0].idx; | ||
417 | rate_flags = tx_info->control.rates[0].flags; | ||
406 | skbdesc = get_skb_frame_desc(entry->skb); | 418 | skbdesc = get_skb_frame_desc(entry->skb); |
407 | memset(skbdesc, 0, sizeof(*skbdesc)); | 419 | memset(skbdesc, 0, sizeof(*skbdesc)); |
408 | skbdesc->entry = entry; | 420 | skbdesc->entry = entry; |
421 | skbdesc->tx_rate_idx = rate_idx; | ||
422 | skbdesc->tx_rate_flags = rate_flags; | ||
409 | 423 | ||
410 | /* | 424 | /* |
411 | * When hardware encryption is supported, and this frame | 425 | * When hardware encryption is supported, and this frame |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 9dbf04f0f04c..4d3c7246f9ae 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h | |||
@@ -104,6 +104,8 @@ enum skb_frame_desc_flags { | |||
104 | * | 104 | * |
105 | * @flags: Frame flags, see &enum skb_frame_desc_flags. | 105 | * @flags: Frame flags, see &enum skb_frame_desc_flags. |
106 | * @desc_len: Length of the frame descriptor. | 106 | * @desc_len: Length of the frame descriptor. |
107 | * @tx_rate_idx: the index of the TX rate, used for TX status reporting | ||
108 | * @tx_rate_flags: the TX rate flags, used for TX status reporting | ||
107 | * @desc: Pointer to descriptor part of the frame. | 109 | * @desc: Pointer to descriptor part of the frame. |
108 | * Note that this pointer could point to something outside | 110 | * Note that this pointer could point to something outside |
109 | * of the scope of the skb->data pointer. | 111 | * of the scope of the skb->data pointer. |
@@ -113,9 +115,12 @@ enum skb_frame_desc_flags { | |||
113 | * @entry: The entry to which this sk buffer belongs. | 115 | * @entry: The entry to which this sk buffer belongs. |
114 | */ | 116 | */ |
115 | struct skb_frame_desc { | 117 | struct skb_frame_desc { |
116 | unsigned int flags; | 118 | u8 flags; |
119 | |||
120 | u8 desc_len; | ||
121 | u8 tx_rate_idx; | ||
122 | u8 tx_rate_flags; | ||
117 | 123 | ||
118 | unsigned int desc_len; | ||
119 | void *desc; | 124 | void *desc; |
120 | 125 | ||
121 | __le32 iv; | 126 | __le32 iv; |
diff --git a/drivers/net/wireless/rtl8180_dev.c b/drivers/net/wireless/rtl8180_dev.c index e8d22393797f..6c226c024dd9 100644 --- a/drivers/net/wireless/rtl8180_dev.c +++ b/drivers/net/wireless/rtl8180_dev.c | |||
@@ -182,15 +182,13 @@ static void rtl8180_handle_tx(struct ieee80211_hw *dev, unsigned int prio) | |||
182 | skb->len, PCI_DMA_TODEVICE); | 182 | skb->len, PCI_DMA_TODEVICE); |
183 | 183 | ||
184 | info = IEEE80211_SKB_CB(skb); | 184 | info = IEEE80211_SKB_CB(skb); |
185 | memset(&info->status, 0, sizeof(info->status)); | 185 | ieee80211_tx_info_clear_status(info); |
186 | 186 | ||
187 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { | 187 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && |
188 | if (flags & RTL818X_TX_DESC_FLAG_TX_OK) | 188 | (flags & RTL818X_TX_DESC_FLAG_TX_OK)) |
189 | info->flags |= IEEE80211_TX_STAT_ACK; | 189 | info->flags |= IEEE80211_TX_STAT_ACK; |
190 | else | 190 | |
191 | info->status.excessive_retries = 1; | 191 | info->status.rates[0].count = (flags & 0xFF) + 1; |
192 | } | ||
193 | info->status.retry_count = flags & 0xFF; | ||
194 | 192 | ||
195 | ieee80211_tx_status_irqsafe(dev, skb); | 193 | ieee80211_tx_status_irqsafe(dev, skb); |
196 | if (ring->entries - skb_queue_len(&ring->queue) == 2) | 194 | if (ring->entries - skb_queue_len(&ring->queue) == 2) |
@@ -243,6 +241,7 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
243 | unsigned int idx, prio; | 241 | unsigned int idx, prio; |
244 | dma_addr_t mapping; | 242 | dma_addr_t mapping; |
245 | u32 tx_flags; | 243 | u32 tx_flags; |
244 | u8 rc_flags; | ||
246 | u16 plcp_len = 0; | 245 | u16 plcp_len = 0; |
247 | __le16 rts_duration = 0; | 246 | __le16 rts_duration = 0; |
248 | 247 | ||
@@ -261,15 +260,16 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
261 | tx_flags |= RTL818X_TX_DESC_FLAG_DMA | | 260 | tx_flags |= RTL818X_TX_DESC_FLAG_DMA | |
262 | RTL818X_TX_DESC_FLAG_NO_ENC; | 261 | RTL818X_TX_DESC_FLAG_NO_ENC; |
263 | 262 | ||
264 | if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) { | 263 | rc_flags = info->control.rates[0].flags; |
264 | if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS) { | ||
265 | tx_flags |= RTL818X_TX_DESC_FLAG_RTS; | 265 | tx_flags |= RTL818X_TX_DESC_FLAG_RTS; |
266 | tx_flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19; | 266 | tx_flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19; |
267 | } else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) { | 267 | } else if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { |
268 | tx_flags |= RTL818X_TX_DESC_FLAG_CTS; | 268 | tx_flags |= RTL818X_TX_DESC_FLAG_CTS; |
269 | tx_flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19; | 269 | tx_flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19; |
270 | } | 270 | } |
271 | 271 | ||
272 | if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) | 272 | if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS) |
273 | rts_duration = ieee80211_rts_duration(dev, priv->vif, skb->len, | 273 | rts_duration = ieee80211_rts_duration(dev, priv->vif, skb->len, |
274 | info); | 274 | info); |
275 | 275 | ||
@@ -292,9 +292,9 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
292 | entry->plcp_len = cpu_to_le16(plcp_len); | 292 | entry->plcp_len = cpu_to_le16(plcp_len); |
293 | entry->tx_buf = cpu_to_le32(mapping); | 293 | entry->tx_buf = cpu_to_le32(mapping); |
294 | entry->frame_len = cpu_to_le32(skb->len); | 294 | entry->frame_len = cpu_to_le32(skb->len); |
295 | entry->flags2 = info->control.retries[0].rate_idx >= 0 ? | 295 | entry->flags2 = info->control.rates[1].idx >= 0 ? |
296 | ieee80211_get_alt_retry_rate(dev, info, 0)->bitrate << 4 : 0; | 296 | ieee80211_get_alt_retry_rate(dev, info, 0)->bitrate << 4 : 0; |
297 | entry->retry_limit = info->control.retry_limit; | 297 | entry->retry_limit = info->control.rates[0].count; |
298 | entry->flags = cpu_to_le32(tx_flags); | 298 | entry->flags = cpu_to_le32(tx_flags); |
299 | __skb_queue_tail(&ring->queue, skb); | 299 | __skb_queue_tail(&ring->queue, skb); |
300 | if (ring->entries - skb_queue_len(&ring->queue) < 2) | 300 | if (ring->entries - skb_queue_len(&ring->queue) < 2) |
@@ -855,7 +855,7 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev, | |||
855 | priv = dev->priv; | 855 | priv = dev->priv; |
856 | priv->pdev = pdev; | 856 | priv->pdev = pdev; |
857 | 857 | ||
858 | dev->max_altrates = 1; | 858 | dev->max_rates = 2; |
859 | SET_IEEE80211_DEV(dev, &pdev->dev); | 859 | SET_IEEE80211_DEV(dev, &pdev->dev); |
860 | pci_set_drvdata(pdev, dev); | 860 | pci_set_drvdata(pdev, dev); |
861 | 861 | ||
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c index cd839bcb6d78..6260ed8ce12b 100644 --- a/drivers/net/wireless/rtl8187_dev.c +++ b/drivers/net/wireless/rtl8187_dev.c | |||
@@ -160,13 +160,13 @@ static void rtl8187_tx_cb(struct urb *urb) | |||
160 | { | 160 | { |
161 | struct sk_buff *skb = (struct sk_buff *)urb->context; | 161 | struct sk_buff *skb = (struct sk_buff *)urb->context; |
162 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 162 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
163 | struct ieee80211_hw *hw = info->driver_data[0]; | 163 | struct ieee80211_hw *hw = info->rate_driver_data[0]; |
164 | struct rtl8187_priv *priv = hw->priv; | 164 | struct rtl8187_priv *priv = hw->priv; |
165 | 165 | ||
166 | usb_free_urb(info->driver_data[1]); | 166 | usb_free_urb(info->rate_driver_data[1]); |
167 | skb_pull(skb, priv->is_rtl8187b ? sizeof(struct rtl8187b_tx_hdr) : | 167 | skb_pull(skb, priv->is_rtl8187b ? sizeof(struct rtl8187b_tx_hdr) : |
168 | sizeof(struct rtl8187_tx_hdr)); | 168 | sizeof(struct rtl8187_tx_hdr)); |
169 | memset(&info->status, 0, sizeof(info->status)); | 169 | ieee80211_tx_info_clear_status(info); |
170 | info->flags |= IEEE80211_TX_STAT_ACK; | 170 | info->flags |= IEEE80211_TX_STAT_ACK; |
171 | ieee80211_tx_status_irqsafe(hw, skb); | 171 | ieee80211_tx_status_irqsafe(hw, skb); |
172 | } | 172 | } |
@@ -194,12 +194,12 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
194 | flags |= ieee80211_get_tx_rate(dev, info)->hw_value << 24; | 194 | flags |= ieee80211_get_tx_rate(dev, info)->hw_value << 24; |
195 | if (ieee80211_has_morefrags(((struct ieee80211_hdr *)skb->data)->frame_control)) | 195 | if (ieee80211_has_morefrags(((struct ieee80211_hdr *)skb->data)->frame_control)) |
196 | flags |= RTL818X_TX_DESC_FLAG_MOREFRAG; | 196 | flags |= RTL818X_TX_DESC_FLAG_MOREFRAG; |
197 | if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) { | 197 | if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) { |
198 | flags |= RTL818X_TX_DESC_FLAG_RTS; | 198 | flags |= RTL818X_TX_DESC_FLAG_RTS; |
199 | flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19; | 199 | flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19; |
200 | rts_dur = ieee80211_rts_duration(dev, priv->vif, | 200 | rts_dur = ieee80211_rts_duration(dev, priv->vif, |
201 | skb->len, info); | 201 | skb->len, info); |
202 | } else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) { | 202 | } else if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { |
203 | flags |= RTL818X_TX_DESC_FLAG_CTS; | 203 | flags |= RTL818X_TX_DESC_FLAG_CTS; |
204 | flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19; | 204 | flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19; |
205 | } | 205 | } |
@@ -210,7 +210,7 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
210 | hdr->flags = cpu_to_le32(flags); | 210 | hdr->flags = cpu_to_le32(flags); |
211 | hdr->len = 0; | 211 | hdr->len = 0; |
212 | hdr->rts_duration = rts_dur; | 212 | hdr->rts_duration = rts_dur; |
213 | hdr->retry = cpu_to_le32(info->control.retry_limit << 8); | 213 | hdr->retry = cpu_to_le32((info->control.rates[0].count - 1) << 8); |
214 | buf = hdr; | 214 | buf = hdr; |
215 | 215 | ||
216 | ep = 2; | 216 | ep = 2; |
@@ -228,7 +228,7 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
228 | memset(hdr, 0, sizeof(*hdr)); | 228 | memset(hdr, 0, sizeof(*hdr)); |
229 | hdr->flags = cpu_to_le32(flags); | 229 | hdr->flags = cpu_to_le32(flags); |
230 | hdr->rts_duration = rts_dur; | 230 | hdr->rts_duration = rts_dur; |
231 | hdr->retry = cpu_to_le32(info->control.retry_limit << 8); | 231 | hdr->retry = cpu_to_le32((info->control.rates[0].count - 1) << 8); |
232 | hdr->tx_duration = | 232 | hdr->tx_duration = |
233 | ieee80211_generic_frame_duration(dev, priv->vif, | 233 | ieee80211_generic_frame_duration(dev, priv->vif, |
234 | skb->len, txrate); | 234 | skb->len, txrate); |
@@ -240,8 +240,8 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
240 | ep = epmap[skb_get_queue_mapping(skb)]; | 240 | ep = epmap[skb_get_queue_mapping(skb)]; |
241 | } | 241 | } |
242 | 242 | ||
243 | info->driver_data[0] = dev; | 243 | info->rate_driver_data[0] = dev; |
244 | info->driver_data[1] = urb; | 244 | info->rate_driver_data[1] = urb; |
245 | 245 | ||
246 | usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, ep), | 246 | usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, ep), |
247 | buf, skb->len, rtl8187_tx_cb, skb); | 247 | buf, skb->len, rtl8187_tx_cb, skb); |
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 6c3e21887fc8..2f0802b29c4b 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
@@ -296,15 +296,14 @@ static void zd_op_stop(struct ieee80211_hw *hw) | |||
296 | * If no status information has been requested, the skb is freed. | 296 | * If no status information has been requested, the skb is freed. |
297 | */ | 297 | */ |
298 | static void tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | 298 | static void tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, |
299 | u32 flags, int ackssi, bool success) | 299 | int ackssi, bool success) |
300 | { | 300 | { |
301 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 301 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
302 | 302 | ||
303 | memset(&info->status, 0, sizeof(info->status)); | 303 | ieee80211_tx_info_clear_status(info); |
304 | 304 | ||
305 | if (!success) | 305 | if (success) |
306 | info->status.excessive_retries = 1; | 306 | info->flags |= IEEE80211_TX_STAT_ACK; |
307 | info->flags |= flags; | ||
308 | info->status.ack_signal = ackssi; | 307 | info->status.ack_signal = ackssi; |
309 | ieee80211_tx_status_irqsafe(hw, skb); | 308 | ieee80211_tx_status_irqsafe(hw, skb); |
310 | } | 309 | } |
@@ -326,7 +325,7 @@ void zd_mac_tx_failed(struct ieee80211_hw *hw) | |||
326 | if (skb == NULL) | 325 | if (skb == NULL) |
327 | return; | 326 | return; |
328 | 327 | ||
329 | tx_status(hw, skb, 0, 0, 0); | 328 | tx_status(hw, skb, 0, 0); |
330 | } | 329 | } |
331 | 330 | ||
332 | /** | 331 | /** |
@@ -342,12 +341,12 @@ void zd_mac_tx_failed(struct ieee80211_hw *hw) | |||
342 | void zd_mac_tx_to_dev(struct sk_buff *skb, int error) | 341 | void zd_mac_tx_to_dev(struct sk_buff *skb, int error) |
343 | { | 342 | { |
344 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 343 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
345 | struct ieee80211_hw *hw = info->driver_data[0]; | 344 | struct ieee80211_hw *hw = info->rate_driver_data[0]; |
346 | 345 | ||
347 | skb_pull(skb, sizeof(struct zd_ctrlset)); | 346 | skb_pull(skb, sizeof(struct zd_ctrlset)); |
348 | if (unlikely(error || | 347 | if (unlikely(error || |
349 | (info->flags & IEEE80211_TX_CTL_NO_ACK))) { | 348 | (info->flags & IEEE80211_TX_CTL_NO_ACK))) { |
350 | tx_status(hw, skb, 0, 0, !error); | 349 | tx_status(hw, skb, 0, !error); |
351 | } else { | 350 | } else { |
352 | struct sk_buff_head *q = | 351 | struct sk_buff_head *q = |
353 | &zd_hw_mac(hw)->ack_wait_queue; | 352 | &zd_hw_mac(hw)->ack_wait_queue; |
@@ -406,7 +405,8 @@ static int zd_calc_tx_length_us(u8 *service, u8 zd_rate, u16 tx_length) | |||
406 | } | 405 | } |
407 | 406 | ||
408 | static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs, | 407 | static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs, |
409 | struct ieee80211_hdr *header, u32 flags) | 408 | struct ieee80211_hdr *header, |
409 | struct ieee80211_tx_info *info) | ||
410 | { | 410 | { |
411 | /* | 411 | /* |
412 | * CONTROL TODO: | 412 | * CONTROL TODO: |
@@ -417,7 +417,7 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs, | |||
417 | cs->control = 0; | 417 | cs->control = 0; |
418 | 418 | ||
419 | /* First fragment */ | 419 | /* First fragment */ |
420 | if (flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) | 420 | if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) |
421 | cs->control |= ZD_CS_NEED_RANDOM_BACKOFF; | 421 | cs->control |= ZD_CS_NEED_RANDOM_BACKOFF; |
422 | 422 | ||
423 | /* Multicast */ | 423 | /* Multicast */ |
@@ -428,10 +428,10 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs, | |||
428 | if (ieee80211_is_pspoll(header->frame_control)) | 428 | if (ieee80211_is_pspoll(header->frame_control)) |
429 | cs->control |= ZD_CS_PS_POLL_FRAME; | 429 | cs->control |= ZD_CS_PS_POLL_FRAME; |
430 | 430 | ||
431 | if (flags & IEEE80211_TX_CTL_USE_RTS_CTS) | 431 | if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) |
432 | cs->control |= ZD_CS_RTS; | 432 | cs->control |= ZD_CS_RTS; |
433 | 433 | ||
434 | if (flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) | 434 | if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) |
435 | cs->control |= ZD_CS_SELF_CTS; | 435 | cs->control |= ZD_CS_SELF_CTS; |
436 | 436 | ||
437 | /* FIXME: Management frame? */ | 437 | /* FIXME: Management frame? */ |
@@ -517,12 +517,12 @@ static int fill_ctrlset(struct zd_mac *mac, | |||
517 | txrate = ieee80211_get_tx_rate(mac->hw, info); | 517 | txrate = ieee80211_get_tx_rate(mac->hw, info); |
518 | 518 | ||
519 | cs->modulation = txrate->hw_value; | 519 | cs->modulation = txrate->hw_value; |
520 | if (info->flags & IEEE80211_TX_CTL_SHORT_PREAMBLE) | 520 | if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) |
521 | cs->modulation = txrate->hw_value_short; | 521 | cs->modulation = txrate->hw_value_short; |
522 | 522 | ||
523 | cs->tx_length = cpu_to_le16(frag_len); | 523 | cs->tx_length = cpu_to_le16(frag_len); |
524 | 524 | ||
525 | cs_set_control(mac, cs, hdr, info->flags); | 525 | cs_set_control(mac, cs, hdr, info); |
526 | 526 | ||
527 | packet_length = frag_len + sizeof(struct zd_ctrlset) + 10; | 527 | packet_length = frag_len + sizeof(struct zd_ctrlset) + 10; |
528 | ZD_ASSERT(packet_length <= 0xffff); | 528 | ZD_ASSERT(packet_length <= 0xffff); |
@@ -577,7 +577,7 @@ static int zd_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
577 | if (r) | 577 | if (r) |
578 | return r; | 578 | return r; |
579 | 579 | ||
580 | info->driver_data[0] = hw; | 580 | info->rate_driver_data[0] = hw; |
581 | 581 | ||
582 | r = zd_usb_tx(&mac->chip.usb, skb); | 582 | r = zd_usb_tx(&mac->chip.usb, skb); |
583 | if (r) | 583 | if (r) |
@@ -618,7 +618,7 @@ static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr, | |||
618 | if (likely(!compare_ether_addr(tx_hdr->addr2, rx_hdr->addr1))) | 618 | if (likely(!compare_ether_addr(tx_hdr->addr2, rx_hdr->addr1))) |
619 | { | 619 | { |
620 | __skb_unlink(skb, q); | 620 | __skb_unlink(skb, q); |
621 | tx_status(hw, skb, IEEE80211_TX_STAT_ACK, stats->signal, 1); | 621 | tx_status(hw, skb, stats->signal, 1); |
622 | goto out; | 622 | goto out; |
623 | } | 623 | } |
624 | } | 624 | } |
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index a60ae86bd5c9..d7a2f52e40cf 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c | |||
@@ -907,7 +907,7 @@ free_urb: | |||
907 | * it might be freed by zd_mac_tx_to_dev or mac80211) | 907 | * it might be freed by zd_mac_tx_to_dev or mac80211) |
908 | */ | 908 | */ |
909 | info = IEEE80211_SKB_CB(skb); | 909 | info = IEEE80211_SKB_CB(skb); |
910 | usb = &zd_hw_mac(info->driver_data[0])->chip.usb; | 910 | usb = &zd_hw_mac(info->rate_driver_data[0])->chip.usb; |
911 | zd_mac_tx_to_dev(skb, urb->status); | 911 | zd_mac_tx_to_dev(skb, urb->status); |
912 | free_tx_urb(usb, urb); | 912 | free_tx_urb(usb, urb); |
913 | tx_dec_submitted_urbs(usb); | 913 | tx_dec_submitted_urbs(usb); |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 9801afb62545..3741c0a7978a 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -214,29 +214,24 @@ struct ieee80211_bss_conf { | |||
214 | * These flags are used with the @flags member of &ieee80211_tx_info. | 214 | * These flags are used with the @flags member of &ieee80211_tx_info. |
215 | * | 215 | * |
216 | * @IEEE80211_TX_CTL_REQ_TX_STATUS: request TX status callback for this frame. | 216 | * @IEEE80211_TX_CTL_REQ_TX_STATUS: request TX status callback for this frame. |
217 | * @IEEE80211_TX_CTL_USE_RTS_CTS: use RTS-CTS before sending frame | 217 | * @IEEE80211_TX_CTL_ASSIGN_SEQ: The driver has to assign a sequence |
218 | * @IEEE80211_TX_CTL_USE_CTS_PROTECT: use CTS protection for the frame (e.g., | 218 | * number to this frame, taking care of not overwriting the fragment |
219 | * for combined 802.11g / 802.11b networks) | 219 | * number and increasing the sequence number only when the |
220 | * IEEE80211_TX_CTL_FIRST_FRAGMENT flag is set. mac80211 will properly | ||
221 | * assign sequence numbers to QoS-data frames but cannot do so correctly | ||
222 | * for non-QoS-data and management frames because beacons need them from | ||
223 | * that counter as well and mac80211 cannot guarantee proper sequencing. | ||
224 | * If this flag is set, the driver should instruct the hardware to | ||
225 | * assign a sequence number to the frame or assign one itself. Cf. IEEE | ||
226 | * 802.11-2007 7.1.3.4.1 paragraph 3. This flag will always be set for | ||
227 | * beacons and always be clear for frames without a sequence number field. | ||
220 | * @IEEE80211_TX_CTL_NO_ACK: tell the low level not to wait for an ack | 228 | * @IEEE80211_TX_CTL_NO_ACK: tell the low level not to wait for an ack |
221 | * @IEEE80211_TX_CTL_RATE_CTRL_PROBE: TBD | ||
222 | * @IEEE80211_TX_CTL_CLEAR_PS_FILT: clear powersave filter for destination | 229 | * @IEEE80211_TX_CTL_CLEAR_PS_FILT: clear powersave filter for destination |
223 | * station | 230 | * station |
224 | * @IEEE80211_TX_CTL_REQUEUE: TBD | ||
225 | * @IEEE80211_TX_CTL_FIRST_FRAGMENT: this is a first fragment of the frame | 231 | * @IEEE80211_TX_CTL_FIRST_FRAGMENT: this is a first fragment of the frame |
226 | * @IEEE80211_TX_CTL_SHORT_PREAMBLE: TBD | ||
227 | * @IEEE80211_TX_CTL_LONG_RETRY_LIMIT: this frame should be send using the | ||
228 | * through set_retry_limit configured long retry value | ||
229 | * @IEEE80211_TX_CTL_SEND_AFTER_DTIM: send this frame after DTIM beacon | 232 | * @IEEE80211_TX_CTL_SEND_AFTER_DTIM: send this frame after DTIM beacon |
230 | * @IEEE80211_TX_CTL_AMPDU: this frame should be sent as part of an A-MPDU | 233 | * @IEEE80211_TX_CTL_AMPDU: this frame should be sent as part of an A-MPDU |
231 | * @IEEE80211_TX_CTL_OFDM_HT: this frame can be sent in HT OFDM rates. number | 234 | * @IEEE80211_TX_CTL_INJECTED: Frame was injected, internal to mac80211. |
232 | * of streams when this flag is on can be extracted from antenna_sel_tx, | ||
233 | * so if 1 antenna is marked use SISO, 2 antennas marked use MIMO, n | ||
234 | * antennas marked use MIMO_n. | ||
235 | * @IEEE80211_TX_CTL_GREEN_FIELD: use green field protection for this frame | ||
236 | * @IEEE80211_TX_CTL_40_MHZ_WIDTH: send this frame using 40 Mhz channel width | ||
237 | * @IEEE80211_TX_CTL_DUP_DATA: duplicate data frame on both 20 Mhz channels | ||
238 | * @IEEE80211_TX_CTL_SHORT_GI: send this frame using short guard interval | ||
239 | * @IEEE80211_TX_CTL_INJECTED: TBD | ||
240 | * @IEEE80211_TX_STAT_TX_FILTERED: The frame was not transmitted | 235 | * @IEEE80211_TX_STAT_TX_FILTERED: The frame was not transmitted |
241 | * because the destination STA was in powersave mode. | 236 | * because the destination STA was in powersave mode. |
242 | * @IEEE80211_TX_STAT_ACK: Frame was acknowledged | 237 | * @IEEE80211_TX_STAT_ACK: Frame was acknowledged |
@@ -244,62 +239,70 @@ struct ieee80211_bss_conf { | |||
244 | * is for the whole aggregation. | 239 | * is for the whole aggregation. |
245 | * @IEEE80211_TX_STAT_AMPDU_NO_BACK: no block ack was returned, | 240 | * @IEEE80211_TX_STAT_AMPDU_NO_BACK: no block ack was returned, |
246 | * so consider using block ack request (BAR). | 241 | * so consider using block ack request (BAR). |
247 | * @IEEE80211_TX_CTL_ASSIGN_SEQ: The driver has to assign a sequence | 242 | * @IEEE80211_TX_CTL_RATE_CTRL_PROBE: internal to mac80211, can be |
248 | * number to this frame, taking care of not overwriting the fragment | 243 | * set by rate control algorithms to indicate probe rate, will |
249 | * number and increasing the sequence number only when the | 244 | * be cleared for fragmented frames (except on the last fragment) |
250 | * IEEE80211_TX_CTL_FIRST_FRAGMENT flags is set. mac80211 will properly | 245 | * @IEEE80211_TX_CTL_REQUEUE: REMOVE THIS |
251 | * assign sequence numbers to QoS-data frames but cannot do so correctly | ||
252 | * for non-QoS-data and management frames because beacons need them from | ||
253 | * that counter as well and mac80211 cannot guarantee proper sequencing. | ||
254 | * If this flag is set, the driver should instruct the hardware to | ||
255 | * assign a sequence number to the frame or assign one itself. Cf. IEEE | ||
256 | * 802.11-2007 7.1.3.4.1 paragraph 3. This flag will always be set for | ||
257 | * beacons always be clear for frames without a sequence number field. | ||
258 | */ | 246 | */ |
259 | enum mac80211_tx_control_flags { | 247 | enum mac80211_tx_control_flags { |
260 | IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0), | 248 | IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0), |
261 | IEEE80211_TX_CTL_USE_RTS_CTS = BIT(2), | 249 | IEEE80211_TX_CTL_ASSIGN_SEQ = BIT(1), |
262 | IEEE80211_TX_CTL_USE_CTS_PROTECT = BIT(3), | 250 | IEEE80211_TX_CTL_NO_ACK = BIT(2), |
263 | IEEE80211_TX_CTL_NO_ACK = BIT(4), | 251 | IEEE80211_TX_CTL_CLEAR_PS_FILT = BIT(3), |
264 | IEEE80211_TX_CTL_RATE_CTRL_PROBE = BIT(5), | 252 | IEEE80211_TX_CTL_FIRST_FRAGMENT = BIT(4), |
265 | IEEE80211_TX_CTL_CLEAR_PS_FILT = BIT(6), | 253 | IEEE80211_TX_CTL_SEND_AFTER_DTIM = BIT(5), |
266 | IEEE80211_TX_CTL_REQUEUE = BIT(7), | 254 | IEEE80211_TX_CTL_AMPDU = BIT(6), |
267 | IEEE80211_TX_CTL_FIRST_FRAGMENT = BIT(8), | 255 | IEEE80211_TX_CTL_INJECTED = BIT(7), |
268 | IEEE80211_TX_CTL_SHORT_PREAMBLE = BIT(9), | 256 | IEEE80211_TX_STAT_TX_FILTERED = BIT(8), |
269 | IEEE80211_TX_CTL_LONG_RETRY_LIMIT = BIT(10), | 257 | IEEE80211_TX_STAT_ACK = BIT(9), |
270 | IEEE80211_TX_CTL_SEND_AFTER_DTIM = BIT(12), | 258 | IEEE80211_TX_STAT_AMPDU = BIT(10), |
271 | IEEE80211_TX_CTL_AMPDU = BIT(13), | 259 | IEEE80211_TX_STAT_AMPDU_NO_BACK = BIT(11), |
272 | IEEE80211_TX_CTL_OFDM_HT = BIT(14), | 260 | IEEE80211_TX_CTL_RATE_CTRL_PROBE = BIT(12), |
273 | IEEE80211_TX_CTL_GREEN_FIELD = BIT(15), | 261 | |
274 | IEEE80211_TX_CTL_40_MHZ_WIDTH = BIT(16), | 262 | /* XXX: remove this */ |
275 | IEEE80211_TX_CTL_DUP_DATA = BIT(17), | 263 | IEEE80211_TX_CTL_REQUEUE = BIT(13), |
276 | IEEE80211_TX_CTL_SHORT_GI = BIT(18), | ||
277 | IEEE80211_TX_CTL_INJECTED = BIT(19), | ||
278 | IEEE80211_TX_STAT_TX_FILTERED = BIT(20), | ||
279 | IEEE80211_TX_STAT_ACK = BIT(21), | ||
280 | IEEE80211_TX_STAT_AMPDU = BIT(22), | ||
281 | IEEE80211_TX_STAT_AMPDU_NO_BACK = BIT(23), | ||
282 | IEEE80211_TX_CTL_ASSIGN_SEQ = BIT(24), | ||
283 | }; | 264 | }; |
284 | 265 | ||
266 | enum mac80211_rate_control_flags { | ||
267 | IEEE80211_TX_RC_USE_RTS_CTS = BIT(0), | ||
268 | IEEE80211_TX_RC_USE_CTS_PROTECT = BIT(1), | ||
269 | IEEE80211_TX_RC_USE_SHORT_PREAMBLE = BIT(2), | ||
270 | |||
271 | /* rate index is an MCS rate number instead of an index */ | ||
272 | IEEE80211_TX_RC_MCS = BIT(3), | ||
273 | IEEE80211_TX_RC_GREEN_FIELD = BIT(4), | ||
274 | IEEE80211_TX_RC_40_MHZ_WIDTH = BIT(5), | ||
275 | IEEE80211_TX_RC_DUP_DATA = BIT(6), | ||
276 | IEEE80211_TX_RC_SHORT_GI = BIT(7), | ||
277 | }; | ||
278 | |||
279 | |||
280 | /* there are 40 bytes if you don't need the rateset to be kept */ | ||
281 | #define IEEE80211_TX_INFO_DRIVER_DATA_SIZE 40 | ||
285 | 282 | ||
286 | #define IEEE80211_TX_INFO_DRIVER_DATA_SIZE \ | 283 | /* if you do need the rateset, then you have less space */ |
287 | (sizeof(((struct sk_buff *)0)->cb) - 8) | 284 | #define IEEE80211_TX_INFO_RATE_DRIVER_DATA_SIZE 24 |
288 | #define IEEE80211_TX_INFO_DRIVER_DATA_PTRS \ | ||
289 | (IEEE80211_TX_INFO_DRIVER_DATA_SIZE / sizeof(void *)) | ||
290 | 285 | ||
291 | /* maximum number of alternate rate retry stages */ | 286 | /* maximum number of rate stages */ |
292 | #define IEEE80211_TX_MAX_ALTRATE 3 | 287 | #define IEEE80211_TX_MAX_RATES 5 |
293 | 288 | ||
294 | /** | 289 | /** |
295 | * struct ieee80211_tx_altrate - alternate rate selection/status | 290 | * struct ieee80211_tx_rate - rate selection/status |
296 | * | 291 | * |
297 | * @rate_idx: rate index to attempt to send with | 292 | * @idx: rate index to attempt to send with |
293 | * @flags: rate control flags (&enum mac80211_rate_control_flags) | ||
298 | * @limit: number of retries before fallback | 294 | * @limit: number of retries before fallback |
295 | * | ||
296 | * A value of -1 for @idx indicates an invalid rate and, if used | ||
297 | * in an array of retry rates, that no more rates should be tried. | ||
298 | * | ||
299 | * When used for transmit status reporting, the driver should | ||
300 | * always report the rate along with the flags it used. | ||
299 | */ | 301 | */ |
300 | struct ieee80211_tx_altrate { | 302 | struct ieee80211_tx_rate { |
301 | s8 rate_idx; | 303 | s8 idx; |
302 | u8 limit; | 304 | u8 count; |
305 | u8 flags; | ||
303 | }; | 306 | }; |
304 | 307 | ||
305 | /** | 308 | /** |
@@ -314,15 +317,12 @@ struct ieee80211_tx_altrate { | |||
314 | * it may be NULL. | 317 | * it may be NULL. |
315 | * | 318 | * |
316 | * @flags: transmit info flags, defined above | 319 | * @flags: transmit info flags, defined above |
317 | * @band: TBD | 320 | * @band: the band to transmit on (use for checking for races) |
318 | * @tx_rate_idx: TBD | ||
319 | * @antenna_sel_tx: antenna to use, 0 for automatic diversity | 321 | * @antenna_sel_tx: antenna to use, 0 for automatic diversity |
320 | * @control: union for control data | 322 | * @control: union for control data |
321 | * @status: union for status data | 323 | * @status: union for status data |
322 | * @driver_data: array of driver_data pointers | 324 | * @driver_data: array of driver_data pointers |
323 | * @retry_count: number of retries | 325 | * @retry_count: number of retries |
324 | * @excessive_retries: set to 1 if the frame was retried many times | ||
325 | * but not acknowledged | ||
326 | * @ampdu_ack_len: number of aggregated frames. | 326 | * @ampdu_ack_len: number of aggregated frames. |
327 | * relevant only if IEEE80211_TX_STATUS_AMPDU was set. | 327 | * relevant only if IEEE80211_TX_STATUS_AMPDU was set. |
328 | * @ampdu_ack_map: block ack bit map for the aggregation. | 328 | * @ampdu_ack_map: block ack bit map for the aggregation. |
@@ -333,31 +333,43 @@ struct ieee80211_tx_info { | |||
333 | /* common information */ | 333 | /* common information */ |
334 | u32 flags; | 334 | u32 flags; |
335 | u8 band; | 335 | u8 band; |
336 | s8 tx_rate_idx; | 336 | |
337 | u8 antenna_sel_tx; | 337 | u8 antenna_sel_tx; |
338 | 338 | ||
339 | /* 1 byte hole */ | 339 | /* 2 byte hole */ |
340 | 340 | ||
341 | union { | 341 | union { |
342 | struct { | 342 | struct { |
343 | union { | ||
344 | /* rate control */ | ||
345 | struct { | ||
346 | struct ieee80211_tx_rate rates[ | ||
347 | IEEE80211_TX_MAX_RATES]; | ||
348 | s8 rts_cts_rate_idx; | ||
349 | }; | ||
350 | /* only needed before rate control */ | ||
351 | unsigned long jiffies; | ||
352 | }; | ||
343 | /* NB: vif can be NULL for injected frames */ | 353 | /* NB: vif can be NULL for injected frames */ |
344 | struct ieee80211_vif *vif; | 354 | struct ieee80211_vif *vif; |
345 | struct ieee80211_key_conf *hw_key; | 355 | struct ieee80211_key_conf *hw_key; |
346 | struct ieee80211_sta *sta; | 356 | struct ieee80211_sta *sta; |
347 | unsigned long jiffies; | ||
348 | s8 rts_cts_rate_idx; | ||
349 | u8 retry_limit; | ||
350 | struct ieee80211_tx_altrate retries[IEEE80211_TX_MAX_ALTRATE]; | ||
351 | } control; | 357 | } control; |
352 | struct { | 358 | struct { |
359 | struct ieee80211_tx_rate rates[IEEE80211_TX_MAX_RATES]; | ||
360 | u8 ampdu_ack_len; | ||
353 | u64 ampdu_ack_map; | 361 | u64 ampdu_ack_map; |
354 | int ack_signal; | 362 | int ack_signal; |
355 | struct ieee80211_tx_altrate retries[IEEE80211_TX_MAX_ALTRATE + 1]; | 363 | /* 8 bytes free */ |
356 | u8 retry_count; | ||
357 | bool excessive_retries; | ||
358 | u8 ampdu_ack_len; | ||
359 | } status; | 364 | } status; |
360 | void *driver_data[IEEE80211_TX_INFO_DRIVER_DATA_PTRS]; | 365 | struct { |
366 | struct ieee80211_tx_rate driver_rates[ | ||
367 | IEEE80211_TX_MAX_RATES]; | ||
368 | void *rate_driver_data[ | ||
369 | IEEE80211_TX_INFO_RATE_DRIVER_DATA_SIZE / sizeof(void *)]; | ||
370 | }; | ||
371 | void *driver_data[ | ||
372 | IEEE80211_TX_INFO_DRIVER_DATA_SIZE / sizeof(void *)]; | ||
361 | }; | 373 | }; |
362 | }; | 374 | }; |
363 | 375 | ||
@@ -366,6 +378,41 @@ static inline struct ieee80211_tx_info *IEEE80211_SKB_CB(struct sk_buff *skb) | |||
366 | return (struct ieee80211_tx_info *)skb->cb; | 378 | return (struct ieee80211_tx_info *)skb->cb; |
367 | } | 379 | } |
368 | 380 | ||
381 | /** | ||
382 | * ieee80211_tx_info_clear_status - clear TX status | ||
383 | * | ||
384 | * @info: The &struct ieee80211_tx_info to be cleared. | ||
385 | * | ||
386 | * When the driver passes an skb back to mac80211, it must report | ||
387 | * a number of things in TX status. This function clears everything | ||
388 | * in the TX status but the rate control information (it does clear | ||
389 | * the count since you need to fill that in anyway). | ||
390 | * | ||
391 | * NOTE: You can only use this function if you do NOT use | ||
392 | * info->driver_data! Use info->rate_driver_data | ||
393 | * instead if you need only the less space that allows. | ||
394 | */ | ||
395 | static inline void | ||
396 | ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info) | ||
397 | { | ||
398 | int i; | ||
399 | |||
400 | BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, status.rates) != | ||
401 | offsetof(struct ieee80211_tx_info, control.rates)); | ||
402 | BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, status.rates) != | ||
403 | offsetof(struct ieee80211_tx_info, driver_rates)); | ||
404 | BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, status.rates) != 8); | ||
405 | /* clear the rate counts */ | ||
406 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) | ||
407 | info->status.rates[i].count = 0; | ||
408 | |||
409 | BUILD_BUG_ON( | ||
410 | offsetof(struct ieee80211_tx_info, status.ampdu_ack_len) != 23); | ||
411 | memset(&info->status.ampdu_ack_len, 0, | ||
412 | sizeof(struct ieee80211_tx_info) - | ||
413 | offsetof(struct ieee80211_tx_info, status.ampdu_ack_len)); | ||
414 | } | ||
415 | |||
369 | 416 | ||
370 | /** | 417 | /** |
371 | * enum mac80211_rx_flags - receive flags | 418 | * enum mac80211_rx_flags - receive flags |
@@ -869,8 +916,8 @@ enum ieee80211_hw_flags { | |||
869 | * @sta_data_size: size (in bytes) of the drv_priv data area | 916 | * @sta_data_size: size (in bytes) of the drv_priv data area |
870 | * within &struct ieee80211_sta. | 917 | * within &struct ieee80211_sta. |
871 | * | 918 | * |
872 | * @max_altrates: maximum number of alternate rate retry stages | 919 | * @max_rates: maximum number of alternate rate retry stages |
873 | * @max_altrate_tries: maximum number of tries for each stage | 920 | * @max_rate_tries: maximum number of tries for each stage |
874 | */ | 921 | */ |
875 | struct ieee80211_hw { | 922 | struct ieee80211_hw { |
876 | struct ieee80211_conf conf; | 923 | struct ieee80211_conf conf; |
@@ -887,8 +934,8 @@ struct ieee80211_hw { | |||
887 | u16 ampdu_queues; | 934 | u16 ampdu_queues; |
888 | u16 max_listen_interval; | 935 | u16 max_listen_interval; |
889 | s8 max_signal; | 936 | s8 max_signal; |
890 | u8 max_altrates; | 937 | u8 max_rates; |
891 | u8 max_altrate_tries; | 938 | u8 max_rate_tries; |
892 | }; | 939 | }; |
893 | 940 | ||
894 | /** | 941 | /** |
@@ -927,9 +974,9 @@ static inline struct ieee80211_rate * | |||
927 | ieee80211_get_tx_rate(const struct ieee80211_hw *hw, | 974 | ieee80211_get_tx_rate(const struct ieee80211_hw *hw, |
928 | const struct ieee80211_tx_info *c) | 975 | const struct ieee80211_tx_info *c) |
929 | { | 976 | { |
930 | if (WARN_ON(c->tx_rate_idx < 0)) | 977 | if (WARN_ON(c->control.rates[0].idx < 0)) |
931 | return NULL; | 978 | return NULL; |
932 | return &hw->wiphy->bands[c->band]->bitrates[c->tx_rate_idx]; | 979 | return &hw->wiphy->bands[c->band]->bitrates[c->control.rates[0].idx]; |
933 | } | 980 | } |
934 | 981 | ||
935 | static inline struct ieee80211_rate * | 982 | static inline struct ieee80211_rate * |
@@ -945,9 +992,9 @@ static inline struct ieee80211_rate * | |||
945 | ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw, | 992 | ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw, |
946 | const struct ieee80211_tx_info *c, int idx) | 993 | const struct ieee80211_tx_info *c, int idx) |
947 | { | 994 | { |
948 | if (c->control.retries[idx].rate_idx < 0) | 995 | if (c->control.rates[idx + 1].idx < 0) |
949 | return NULL; | 996 | return NULL; |
950 | return &hw->wiphy->bands[c->band]->bitrates[c->control.retries[idx].rate_idx]; | 997 | return &hw->wiphy->bands[c->band]->bitrates[c->control.rates[idx + 1].idx]; |
951 | } | 998 | } |
952 | 999 | ||
953 | /** | 1000 | /** |
@@ -1840,17 +1887,30 @@ struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_hw *hw, | |||
1840 | 1887 | ||
1841 | 1888 | ||
1842 | /* Rate control API */ | 1889 | /* Rate control API */ |
1890 | |||
1843 | /** | 1891 | /** |
1844 | * struct rate_selection - rate information for/from rate control algorithms | 1892 | * struct ieee80211_tx_rate_control - rate control information for/from RC algo |
1845 | * | 1893 | * |
1846 | * @rate_idx: selected transmission rate index | 1894 | * @hw: The hardware the algorithm is invoked for. |
1847 | * @nonerp_idx: Non-ERP rate to use instead if ERP cannot be used | 1895 | * @sband: The band this frame is being transmitted on. |
1848 | * @probe_idx: rate for probing (or -1) | 1896 | * @bss_conf: the current BSS configuration |
1849 | * @max_rate_idx: maximum rate index that can be used, this is | 1897 | * @reported_rate: The rate control algorithm can fill this in to indicate |
1850 | * input to the algorithm and will be enforced | 1898 | * which rate should be reported to userspace as the current rate and |
1851 | */ | 1899 | * used for rate calculations in the mesh network. |
1852 | struct rate_selection { | 1900 | * @rts: whether RTS will be used for this frame because it is longer than the |
1853 | s8 rate_idx, nonerp_idx, probe_idx, max_rate_idx; | 1901 | * RTS threshold |
1902 | * @short_preamble: whether mac80211 will request short-preamble transmission | ||
1903 | * if the selected rate supports it | ||
1904 | * @max_rate_idx: user-requested maximum rate (not MCS for now) | ||
1905 | */ | ||
1906 | struct ieee80211_tx_rate_control { | ||
1907 | struct ieee80211_hw *hw; | ||
1908 | struct ieee80211_supported_band *sband; | ||
1909 | struct ieee80211_bss_conf *bss_conf; | ||
1910 | struct sk_buff *skb; | ||
1911 | struct ieee80211_tx_rate reported_rate; | ||
1912 | bool rts, short_preamble; | ||
1913 | u8 max_rate_idx; | ||
1854 | }; | 1914 | }; |
1855 | 1915 | ||
1856 | struct rate_control_ops { | 1916 | struct rate_control_ops { |
@@ -1869,10 +1929,8 @@ struct rate_control_ops { | |||
1869 | void (*tx_status)(void *priv, struct ieee80211_supported_band *sband, | 1929 | void (*tx_status)(void *priv, struct ieee80211_supported_band *sband, |
1870 | struct ieee80211_sta *sta, void *priv_sta, | 1930 | struct ieee80211_sta *sta, void *priv_sta, |
1871 | struct sk_buff *skb); | 1931 | struct sk_buff *skb); |
1872 | void (*get_rate)(void *priv, struct ieee80211_supported_band *sband, | 1932 | void (*get_rate)(void *priv, struct ieee80211_sta *sta, void *priv_sta, |
1873 | struct ieee80211_sta *sta, void *priv_sta, | 1933 | struct ieee80211_tx_rate_control *txrc); |
1874 | struct sk_buff *skb, | ||
1875 | struct rate_selection *sel); | ||
1876 | 1934 | ||
1877 | void (*add_sta_debugfs)(void *priv, void *priv_sta, | 1935 | void (*add_sta_debugfs)(void *priv, void *priv_sta, |
1878 | struct dentry *dir); | 1936 | struct dentry *dir); |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 6f8756d26a93..fe4efdd4253d 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -142,7 +142,6 @@ typedef unsigned __bitwise__ ieee80211_tx_result; | |||
142 | #define IEEE80211_TX_FRAGMENTED BIT(0) | 142 | #define IEEE80211_TX_FRAGMENTED BIT(0) |
143 | #define IEEE80211_TX_UNICAST BIT(1) | 143 | #define IEEE80211_TX_UNICAST BIT(1) |
144 | #define IEEE80211_TX_PS_BUFFERED BIT(2) | 144 | #define IEEE80211_TX_PS_BUFFERED BIT(2) |
145 | #define IEEE80211_TX_PROBE_LAST_FRAG BIT(3) | ||
146 | 145 | ||
147 | struct ieee80211_tx_data { | 146 | struct ieee80211_tx_data { |
148 | struct sk_buff *skb; | 147 | struct sk_buff *skb; |
@@ -153,11 +152,6 @@ struct ieee80211_tx_data { | |||
153 | struct ieee80211_key *key; | 152 | struct ieee80211_key *key; |
154 | 153 | ||
155 | struct ieee80211_channel *channel; | 154 | struct ieee80211_channel *channel; |
156 | s8 rate_idx; | ||
157 | /* use this rate (if set) for last fragment; rate can | ||
158 | * be set to lower rate for the first fragments, e.g., | ||
159 | * when using CTS protection with IEEE 802.11g. */ | ||
160 | s8 last_frag_rate_idx; | ||
161 | 155 | ||
162 | /* Extra fragments (in addition to the first fragment | 156 | /* Extra fragments (in addition to the first fragment |
163 | * in skb) */ | 157 | * in skb) */ |
@@ -203,9 +197,7 @@ struct ieee80211_rx_data { | |||
203 | struct ieee80211_tx_stored_packet { | 197 | struct ieee80211_tx_stored_packet { |
204 | struct sk_buff *skb; | 198 | struct sk_buff *skb; |
205 | struct sk_buff **extra_frag; | 199 | struct sk_buff **extra_frag; |
206 | s8 last_frag_rate_idx; | ||
207 | int num_extra_frag; | 200 | int num_extra_frag; |
208 | bool last_frag_rate_ctrl_probe; | ||
209 | }; | 201 | }; |
210 | 202 | ||
211 | struct beacon_data { | 203 | struct beacon_data { |
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; |
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 501c7831adb4..e8d573d592e7 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c | |||
@@ -218,12 +218,16 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local, | |||
218 | 218 | ||
219 | if (sta->fail_avg >= 100) | 219 | if (sta->fail_avg >= 100) |
220 | return MAX_METRIC; | 220 | return MAX_METRIC; |
221 | |||
222 | if (sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS) | ||
223 | return MAX_METRIC; | ||
224 | |||
221 | err = (sta->fail_avg << ARITH_SHIFT) / 100; | 225 | err = (sta->fail_avg << ARITH_SHIFT) / 100; |
222 | 226 | ||
223 | /* bitrate is in units of 100 Kbps, while we need rate in units of | 227 | /* bitrate is in units of 100 Kbps, while we need rate in units of |
224 | * 1Mbps. This will be corrected on tx_time computation. | 228 | * 1Mbps. This will be corrected on tx_time computation. |
225 | */ | 229 | */ |
226 | rate = sband->bitrates[sta->last_txrate_idx].bitrate; | 230 | rate = sband->bitrates[sta->last_tx_rate.idx].bitrate; |
227 | tx_time = (device_constant + 10 * test_frame_len / rate); | 231 | tx_time = (device_constant + 10 * test_frame_len / rate); |
228 | estimated_retx = ((1 << (2 * ARITH_SHIFT)) / (s_unit - err)); | 232 | estimated_retx = ((1 << (2 * ARITH_SHIFT)) / (s_unit - err)); |
229 | result = (tx_time * estimated_retx) >> (2 * ARITH_SHIFT) ; | 233 | result = (tx_time * estimated_retx) >> (2 * ARITH_SHIFT) ; |
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index 5d786720d935..3fa7ab285066 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c | |||
@@ -199,48 +199,44 @@ static void rate_control_release(struct kref *kref) | |||
199 | } | 199 | } |
200 | 200 | ||
201 | void rate_control_get_rate(struct ieee80211_sub_if_data *sdata, | 201 | void rate_control_get_rate(struct ieee80211_sub_if_data *sdata, |
202 | struct ieee80211_supported_band *sband, | 202 | struct sta_info *sta, |
203 | struct sta_info *sta, struct sk_buff *skb, | 203 | struct ieee80211_tx_rate_control *txrc) |
204 | struct rate_selection *sel) | ||
205 | { | 204 | { |
206 | struct rate_control_ref *ref = sdata->local->rate_ctrl; | 205 | struct rate_control_ref *ref = sdata->local->rate_ctrl; |
207 | void *priv_sta = NULL; | 206 | void *priv_sta = NULL; |
208 | struct ieee80211_sta *ista = NULL; | 207 | struct ieee80211_sta *ista = NULL; |
208 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb); | ||
209 | int i; | 209 | int i; |
210 | 210 | ||
211 | sel->rate_idx = -1; | ||
212 | sel->nonerp_idx = -1; | ||
213 | sel->probe_idx = -1; | ||
214 | sel->max_rate_idx = sdata->max_ratectrl_rateidx; | ||
215 | |||
216 | if (sta) { | 211 | if (sta) { |
217 | ista = &sta->sta; | 212 | ista = &sta->sta; |
218 | priv_sta = sta->rate_ctrl_priv; | 213 | priv_sta = sta->rate_ctrl_priv; |
219 | } | 214 | } |
220 | 215 | ||
216 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { | ||
217 | info->control.rates[i].idx = -1; | ||
218 | info->control.rates[i].flags = 0; | ||
219 | info->control.rates[i].count = 1; | ||
220 | } | ||
221 | |||
221 | if (sta && sdata->force_unicast_rateidx > -1) | 222 | if (sta && sdata->force_unicast_rateidx > -1) |
222 | sel->rate_idx = sdata->force_unicast_rateidx; | 223 | info->control.rates[0].idx = sdata->force_unicast_rateidx; |
223 | else | 224 | else |
224 | ref->ops->get_rate(ref->priv, sband, ista, priv_sta, skb, sel); | 225 | ref->ops->get_rate(ref->priv, ista, priv_sta, txrc); |
225 | 226 | ||
226 | if (sdata->max_ratectrl_rateidx > -1 && | 227 | /* |
227 | sel->rate_idx > sdata->max_ratectrl_rateidx) | 228 | * try to enforce the maximum rate the user wanted |
228 | sel->rate_idx = sdata->max_ratectrl_rateidx; | 229 | */ |
229 | 230 | if (sdata->max_ratectrl_rateidx > -1) | |
230 | BUG_ON(sel->rate_idx < 0); | 231 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { |
231 | 232 | if (info->control.rates[i].flags & IEEE80211_TX_RC_MCS) | |
232 | /* Select a non-ERP backup rate. */ | 233 | continue; |
233 | if (sel->nonerp_idx < 0) { | 234 | info->control.rates[i].idx = |
234 | for (i = 0; i < sband->n_bitrates; i++) { | 235 | min_t(s8, info->control.rates[i].idx, |
235 | struct ieee80211_rate *rate = &sband->bitrates[i]; | 236 | sdata->max_ratectrl_rateidx); |
236 | if (sband->bitrates[sel->rate_idx].bitrate < rate->bitrate) | ||
237 | break; | ||
238 | |||
239 | if (rate_supported(ista, sband->band, i) && | ||
240 | !(rate->flags & IEEE80211_RATE_ERP_G)) | ||
241 | sel->nonerp_idx = i; | ||
242 | } | ||
243 | } | 237 | } |
238 | |||
239 | BUG_ON(info->control.rates[0].idx < 0); | ||
244 | } | 240 | } |
245 | 241 | ||
246 | struct rate_control_ref *rate_control_get(struct rate_control_ref *ref) | 242 | struct rate_control_ref *rate_control_get(struct rate_control_ref *ref) |
diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h index d0092f847f82..7c25edf9ac55 100644 --- a/net/mac80211/rate.h +++ b/net/mac80211/rate.h | |||
@@ -31,9 +31,8 @@ struct rate_control_ref { | |||
31 | struct rate_control_ref *rate_control_alloc(const char *name, | 31 | struct rate_control_ref *rate_control_alloc(const char *name, |
32 | struct ieee80211_local *local); | 32 | struct ieee80211_local *local); |
33 | void rate_control_get_rate(struct ieee80211_sub_if_data *sdata, | 33 | void rate_control_get_rate(struct ieee80211_sub_if_data *sdata, |
34 | struct ieee80211_supported_band *sband, | 34 | struct sta_info *sta, |
35 | struct sta_info *sta, struct sk_buff *skb, | 35 | struct ieee80211_tx_rate_control *txrc); |
36 | struct rate_selection *sel); | ||
37 | struct rate_control_ref *rate_control_get(struct rate_control_ref *ref); | 36 | struct rate_control_ref *rate_control_get(struct rate_control_ref *ref); |
38 | void rate_control_put(struct rate_control_ref *ref); | 37 | void rate_control_put(struct rate_control_ref *ref); |
39 | 38 | ||
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c index f6d69dab07a3..759ddd8bf0f4 100644 --- a/net/mac80211/rc80211_minstrel.c +++ b/net/mac80211/rc80211_minstrel.c | |||
@@ -169,30 +169,20 @@ minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband, | |||
169 | { | 169 | { |
170 | struct minstrel_sta_info *mi = priv_sta; | 170 | struct minstrel_sta_info *mi = priv_sta; |
171 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 171 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
172 | struct ieee80211_tx_altrate *ar = info->status.retries; | 172 | struct ieee80211_tx_rate *ar = info->status.rates; |
173 | struct minstrel_priv *mp = priv; | 173 | int i, ndx; |
174 | int i, ndx, tries; | 174 | int success; |
175 | int success = 0; | ||
176 | 175 | ||
177 | if (!info->status.excessive_retries) | 176 | success = !!(info->flags & IEEE80211_TX_STAT_ACK); |
178 | success = 1; | ||
179 | 177 | ||
180 | if (!mp->has_mrr || (ar[0].rate_idx < 0)) { | 178 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { |
181 | ndx = rix_to_ndx(mi, info->tx_rate_idx); | 179 | if (ar[i].idx < 0) |
182 | tries = info->status.retry_count + 1; | ||
183 | mi->r[ndx].success += success; | ||
184 | mi->r[ndx].attempts += tries; | ||
185 | return; | ||
186 | } | ||
187 | |||
188 | for (i = 0; i < 4; i++) { | ||
189 | if (ar[i].rate_idx < 0) | ||
190 | break; | 180 | break; |
191 | 181 | ||
192 | ndx = rix_to_ndx(mi, ar[i].rate_idx); | 182 | ndx = rix_to_ndx(mi, ar[i].idx); |
193 | mi->r[ndx].attempts += ar[i].limit + 1; | 183 | mi->r[ndx].attempts += ar[i].count; |
194 | 184 | ||
195 | if ((i != 3) && (ar[i + 1].rate_idx < 0)) | 185 | if ((i != IEEE80211_TX_MAX_RATES - 1) && (ar[i + 1].idx < 0)) |
196 | mi->r[ndx].success += success; | 186 | mi->r[ndx].success += success; |
197 | } | 187 | } |
198 | 188 | ||
@@ -210,9 +200,9 @@ minstrel_get_retry_count(struct minstrel_rate *mr, | |||
210 | { | 200 | { |
211 | unsigned int retry = mr->adjusted_retry_count; | 201 | unsigned int retry = mr->adjusted_retry_count; |
212 | 202 | ||
213 | if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) | 203 | if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) |
214 | retry = max(2U, min(mr->retry_count_rtscts, retry)); | 204 | retry = max(2U, min(mr->retry_count_rtscts, retry)); |
215 | else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) | 205 | else if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) |
216 | retry = max(2U, min(mr->retry_count_cts, retry)); | 206 | retry = max(2U, min(mr->retry_count_cts, retry)); |
217 | return retry; | 207 | return retry; |
218 | } | 208 | } |
@@ -234,14 +224,15 @@ minstrel_get_next_sample(struct minstrel_sta_info *mi) | |||
234 | } | 224 | } |
235 | 225 | ||
236 | void | 226 | void |
237 | minstrel_get_rate(void *priv, struct ieee80211_supported_band *sband, | 227 | minstrel_get_rate(void *priv, struct ieee80211_sta *sta, |
238 | struct ieee80211_sta *sta, void *priv_sta, | 228 | void *priv_sta, struct ieee80211_tx_rate_control *txrc) |
239 | struct sk_buff *skb, struct rate_selection *sel) | ||
240 | { | 229 | { |
230 | struct sk_buff *skb = txrc->skb; | ||
231 | struct ieee80211_supported_band *sband = txrc->sband; | ||
241 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 232 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
242 | struct minstrel_sta_info *mi = priv_sta; | 233 | struct minstrel_sta_info *mi = priv_sta; |
243 | struct minstrel_priv *mp = priv; | 234 | struct minstrel_priv *mp = priv; |
244 | struct ieee80211_tx_altrate *ar = info->control.retries; | 235 | struct ieee80211_tx_rate *ar = info->control.rates; |
245 | unsigned int ndx, sample_ndx = 0; | 236 | unsigned int ndx, sample_ndx = 0; |
246 | bool mrr; | 237 | bool mrr; |
247 | bool sample_slower = false; | 238 | bool sample_slower = false; |
@@ -251,16 +242,12 @@ minstrel_get_rate(void *priv, struct ieee80211_supported_band *sband, | |||
251 | int sample_rate; | 242 | int sample_rate; |
252 | 243 | ||
253 | if (!sta || !mi || use_low_rate(skb)) { | 244 | if (!sta || !mi || use_low_rate(skb)) { |
254 | sel->rate_idx = rate_lowest_index(sband, sta); | 245 | ar[0].idx = rate_lowest_index(sband, sta); |
246 | ar[0].count = mp->max_retry; | ||
255 | return; | 247 | return; |
256 | } | 248 | } |
257 | 249 | ||
258 | mrr = mp->has_mrr; | 250 | mrr = mp->has_mrr && !txrc->rts && !txrc->bss_conf->use_cts_prot; |
259 | |||
260 | /* mac80211 does not allow mrr for RTS/CTS */ | ||
261 | if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) || | ||
262 | (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) | ||
263 | mrr = false; | ||
264 | 251 | ||
265 | if (time_after(jiffies, mi->stats_update + (mp->update_interval * | 252 | if (time_after(jiffies, mi->stats_update + (mp->update_interval * |
266 | HZ) / 1000)) | 253 | HZ) / 1000)) |
@@ -315,13 +302,12 @@ minstrel_get_rate(void *priv, struct ieee80211_supported_band *sband, | |||
315 | mi->sample_deferred++; | 302 | mi->sample_deferred++; |
316 | } | 303 | } |
317 | } | 304 | } |
318 | sel->rate_idx = mi->r[ndx].rix; | 305 | ar[0].idx = mi->r[ndx].rix; |
319 | info->control.retry_limit = minstrel_get_retry_count(&mi->r[ndx], info); | 306 | ar[0].count = minstrel_get_retry_count(&mi->r[ndx], info); |
320 | 307 | ||
321 | if (!mrr) { | 308 | if (!mrr) { |
322 | ar[0].rate_idx = mi->lowest_rix; | 309 | ar[1].idx = mi->lowest_rix; |
323 | ar[0].limit = mp->max_retry; | 310 | ar[1].count = mp->max_retry; |
324 | ar[1].rate_idx = -1; | ||
325 | return; | 311 | return; |
326 | } | 312 | } |
327 | 313 | ||
@@ -336,9 +322,9 @@ minstrel_get_rate(void *priv, struct ieee80211_supported_band *sband, | |||
336 | } | 322 | } |
337 | mrr_ndx[1] = mi->max_prob_rate; | 323 | mrr_ndx[1] = mi->max_prob_rate; |
338 | mrr_ndx[2] = 0; | 324 | mrr_ndx[2] = 0; |
339 | for (i = 0; i < 3; i++) { | 325 | for (i = 1; i < 4; i++) { |
340 | ar[i].rate_idx = mi->r[mrr_ndx[i]].rix; | 326 | ar[i].idx = mi->r[mrr_ndx[i - 1]].rix; |
341 | ar[i].limit = mi->r[mrr_ndx[i]].adjusted_retry_count; | 327 | ar[i].count = mi->r[mrr_ndx[i - 1]].adjusted_retry_count; |
342 | } | 328 | } |
343 | } | 329 | } |
344 | 330 | ||
@@ -532,13 +518,13 @@ minstrel_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) | |||
532 | /* maximum time that the hw is allowed to stay in one MRR segment */ | 518 | /* maximum time that the hw is allowed to stay in one MRR segment */ |
533 | mp->segment_size = 6000; | 519 | mp->segment_size = 6000; |
534 | 520 | ||
535 | if (hw->max_altrate_tries > 0) | 521 | if (hw->max_rate_tries > 0) |
536 | mp->max_retry = hw->max_altrate_tries; | 522 | mp->max_retry = hw->max_rate_tries; |
537 | else | 523 | else |
538 | /* safe default, does not necessarily have to match hw properties */ | 524 | /* safe default, does not necessarily have to match hw properties */ |
539 | mp->max_retry = 7; | 525 | mp->max_retry = 7; |
540 | 526 | ||
541 | if (hw->max_altrates >= 3) | 527 | if (hw->max_rates >= 4) |
542 | mp->has_mrr = true; | 528 | mp->has_mrr = true; |
543 | 529 | ||
544 | mp->hw = hw; | 530 | mp->hw = hw; |
diff --git a/net/mac80211/rc80211_pid.h b/net/mac80211/rc80211_pid.h index ce099ea1d5d3..1a873f00691a 100644 --- a/net/mac80211/rc80211_pid.h +++ b/net/mac80211/rc80211_pid.h | |||
@@ -61,6 +61,7 @@ enum rc_pid_event_type { | |||
61 | union rc_pid_event_data { | 61 | union rc_pid_event_data { |
62 | /* RC_PID_EVENT_TX_STATUS */ | 62 | /* RC_PID_EVENT_TX_STATUS */ |
63 | struct { | 63 | struct { |
64 | u32 flags; | ||
64 | struct ieee80211_tx_info tx_status; | 65 | struct ieee80211_tx_info tx_status; |
65 | }; | 66 | }; |
66 | /* RC_PID_EVENT_TYPE_RATE_CHANGE */ | 67 | /* RC_PID_EVENT_TYPE_RATE_CHANGE */ |
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c index 86eb374e3b87..92caecfcee78 100644 --- a/net/mac80211/rc80211_pid_algo.c +++ b/net/mac80211/rc80211_pid_algo.c | |||
@@ -241,7 +241,7 @@ static void rate_control_pid_tx_status(void *priv, struct ieee80211_supported_ba | |||
241 | 241 | ||
242 | /* Ignore all frames that were sent with a different rate than the rate | 242 | /* Ignore all frames that were sent with a different rate than the rate |
243 | * we currently advise mac80211 to use. */ | 243 | * we currently advise mac80211 to use. */ |
244 | if (info->tx_rate_idx != spinfo->txrate_idx) | 244 | if (info->status.rates[0].idx != spinfo->txrate_idx) |
245 | return; | 245 | return; |
246 | 246 | ||
247 | spinfo->tx_num_xmit++; | 247 | spinfo->tx_num_xmit++; |
@@ -253,10 +253,10 @@ static void rate_control_pid_tx_status(void *priv, struct ieee80211_supported_ba | |||
253 | /* We count frames that totally failed to be transmitted as two bad | 253 | /* We count frames that totally failed to be transmitted as two bad |
254 | * frames, those that made it out but had some retries as one good and | 254 | * frames, those that made it out but had some retries as one good and |
255 | * one bad frame. */ | 255 | * one bad frame. */ |
256 | if (info->status.excessive_retries) { | 256 | if (!(info->flags & IEEE80211_TX_STAT_ACK)) { |
257 | spinfo->tx_num_failed += 2; | 257 | spinfo->tx_num_failed += 2; |
258 | spinfo->tx_num_xmit++; | 258 | spinfo->tx_num_xmit++; |
259 | } else if (info->status.retry_count) { | 259 | } else if (info->status.rates[0].count) { |
260 | spinfo->tx_num_failed++; | 260 | spinfo->tx_num_failed++; |
261 | spinfo->tx_num_xmit++; | 261 | spinfo->tx_num_xmit++; |
262 | } | 262 | } |
@@ -270,23 +270,32 @@ static void rate_control_pid_tx_status(void *priv, struct ieee80211_supported_ba | |||
270 | } | 270 | } |
271 | 271 | ||
272 | static void | 272 | static void |
273 | rate_control_pid_get_rate(void *priv, struct ieee80211_supported_band *sband, | 273 | rate_control_pid_get_rate(void *priv, struct ieee80211_sta *sta, |
274 | struct ieee80211_sta *sta, void *priv_sta, | 274 | void *priv_sta, |
275 | struct sk_buff *skb, | 275 | struct ieee80211_tx_rate_control *txrc) |
276 | struct rate_selection *sel) | ||
277 | { | 276 | { |
277 | struct sk_buff *skb = txrc->skb; | ||
278 | struct ieee80211_supported_band *sband = txrc->sband; | ||
278 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 279 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
280 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
279 | struct rc_pid_sta_info *spinfo = priv_sta; | 281 | struct rc_pid_sta_info *spinfo = priv_sta; |
280 | int rateidx; | 282 | int rateidx; |
281 | u16 fc; | 283 | u16 fc; |
282 | 284 | ||
285 | if (txrc->rts) | ||
286 | info->control.rates[0].count = | ||
287 | txrc->hw->conf.long_frame_max_tx_count; | ||
288 | else | ||
289 | info->control.rates[0].count = | ||
290 | txrc->hw->conf.short_frame_max_tx_count; | ||
291 | |||
283 | /* Send management frames and broadcast/multicast data using lowest | 292 | /* Send management frames and broadcast/multicast data using lowest |
284 | * rate. */ | 293 | * rate. */ |
285 | fc = le16_to_cpu(hdr->frame_control); | 294 | fc = le16_to_cpu(hdr->frame_control); |
286 | if (!sta || !spinfo || | 295 | if (!sta || !spinfo || |
287 | (fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA || | 296 | (fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA || |
288 | is_multicast_ether_addr(hdr->addr1)) { | 297 | is_multicast_ether_addr(hdr->addr1)) { |
289 | sel->rate_idx = rate_lowest_index(sband, sta); | 298 | info->control.rates[0].idx = rate_lowest_index(sband, sta); |
290 | return; | 299 | return; |
291 | } | 300 | } |
292 | 301 | ||
@@ -295,7 +304,7 @@ rate_control_pid_get_rate(void *priv, struct ieee80211_supported_band *sband, | |||
295 | if (rateidx >= sband->n_bitrates) | 304 | if (rateidx >= sband->n_bitrates) |
296 | rateidx = sband->n_bitrates - 1; | 305 | rateidx = sband->n_bitrates - 1; |
297 | 306 | ||
298 | sel->rate_idx = rateidx; | 307 | info->control.rates[0].idx = rateidx; |
299 | 308 | ||
300 | #ifdef CONFIG_MAC80211_DEBUGFS | 309 | #ifdef CONFIG_MAC80211_DEBUGFS |
301 | rate_control_pid_event_tx_rate(&spinfo->events, | 310 | rate_control_pid_event_tx_rate(&spinfo->events, |
diff --git a/net/mac80211/rc80211_pid_debugfs.c b/net/mac80211/rc80211_pid_debugfs.c index 8121d3bc6835..a08a9b530347 100644 --- a/net/mac80211/rc80211_pid_debugfs.c +++ b/net/mac80211/rc80211_pid_debugfs.c | |||
@@ -43,6 +43,7 @@ void rate_control_pid_event_tx_status(struct rc_pid_event_buffer *buf, | |||
43 | { | 43 | { |
44 | union rc_pid_event_data evd; | 44 | union rc_pid_event_data evd; |
45 | 45 | ||
46 | evd.flags = stat->flags; | ||
46 | memcpy(&evd.tx_status, stat, sizeof(struct ieee80211_tx_info)); | 47 | memcpy(&evd.tx_status, stat, sizeof(struct ieee80211_tx_info)); |
47 | rate_control_pid_event(buf, RC_PID_EVENT_TYPE_TX_STATUS, &evd); | 48 | rate_control_pid_event(buf, RC_PID_EVENT_TYPE_TX_STATUS, &evd); |
48 | } | 49 | } |
@@ -167,8 +168,8 @@ static ssize_t rate_control_pid_events_read(struct file *file, char __user *buf, | |||
167 | switch (ev->type) { | 168 | switch (ev->type) { |
168 | case RC_PID_EVENT_TYPE_TX_STATUS: | 169 | case RC_PID_EVENT_TYPE_TX_STATUS: |
169 | p += snprintf(pb + p, length - p, "tx_status %u %u", | 170 | p += snprintf(pb + p, length - p, "tx_status %u %u", |
170 | ev->data.tx_status.status.excessive_retries, | 171 | !(ev->data.flags & IEEE80211_TX_STAT_ACK), |
171 | ev->data.tx_status.status.retry_count); | 172 | ev->data.tx_status.status.rates[0].idx); |
172 | break; | 173 | break; |
173 | case RC_PID_EVENT_TYPE_RATE_CHANGE: | 174 | case RC_PID_EVENT_TYPE_RATE_CHANGE: |
174 | p += snprintf(pb + p, length - p, "rate_change %d %d", | 175 | p += snprintf(pb + p, length - p, "rate_change %d %d", |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 168a39a298bd..4ac372aa75ce 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -196,7 +196,7 @@ struct sta_ampdu_mlme { | |||
196 | * @tx_packets: number of RX/TX MSDUs | 196 | * @tx_packets: number of RX/TX MSDUs |
197 | * @tx_bytes: TBD | 197 | * @tx_bytes: TBD |
198 | * @tx_fragments: number of transmitted MPDUs | 198 | * @tx_fragments: number of transmitted MPDUs |
199 | * @last_txrate_idx: Index of the last used transmit rate | 199 | * @last_txrate: description of the last used transmit rate |
200 | * @tid_seq: TBD | 200 | * @tid_seq: TBD |
201 | * @ampdu_mlme: TBD | 201 | * @ampdu_mlme: TBD |
202 | * @timer_to_tid: identity mapping to ID timers | 202 | * @timer_to_tid: identity mapping to ID timers |
@@ -267,7 +267,7 @@ struct sta_info { | |||
267 | unsigned long tx_packets; | 267 | unsigned long tx_packets; |
268 | unsigned long tx_bytes; | 268 | unsigned long tx_bytes; |
269 | unsigned long tx_fragments; | 269 | unsigned long tx_fragments; |
270 | unsigned int last_txrate_idx; | 270 | struct ieee80211_tx_rate last_tx_rate; |
271 | u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1]; | 271 | u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1]; |
272 | 272 | ||
273 | /* | 273 | /* |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 6f3e4be97631..21951bac1ef7 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -46,13 +46,20 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr, | |||
46 | struct ieee80211_local *local = tx->local; | 46 | struct ieee80211_local *local = tx->local; |
47 | struct ieee80211_supported_band *sband; | 47 | struct ieee80211_supported_band *sband; |
48 | struct ieee80211_hdr *hdr; | 48 | struct ieee80211_hdr *hdr; |
49 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | ||
50 | |||
51 | /* assume HW handles this */ | ||
52 | if (info->control.rates[0].flags & IEEE80211_TX_RC_MCS) | ||
53 | return 0; | ||
54 | |||
55 | /* uh huh? */ | ||
56 | if (WARN_ON_ONCE(info->control.rates[0].idx < 0)) | ||
57 | return 0; | ||
49 | 58 | ||
50 | sband = local->hw.wiphy->bands[tx->channel->band]; | 59 | sband = local->hw.wiphy->bands[tx->channel->band]; |
51 | txrate = &sband->bitrates[tx->rate_idx]; | 60 | txrate = &sband->bitrates[info->control.rates[0].idx]; |
52 | 61 | ||
53 | erp = 0; | 62 | erp = txrate->flags & IEEE80211_RATE_ERP_G; |
54 | if (tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) | ||
55 | erp = txrate->flags & IEEE80211_RATE_ERP_G; | ||
56 | 63 | ||
57 | /* | 64 | /* |
58 | * data and mgmt (except PS Poll): | 65 | * data and mgmt (except PS Poll): |
@@ -437,140 +444,154 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | |||
437 | static ieee80211_tx_result debug_noinline | 444 | static ieee80211_tx_result debug_noinline |
438 | ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | 445 | ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) |
439 | { | 446 | { |
440 | struct rate_selection rsel; | ||
441 | struct ieee80211_supported_band *sband; | ||
442 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | 447 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); |
448 | struct ieee80211_hdr *hdr = (void *)tx->skb->data; | ||
449 | struct ieee80211_supported_band *sband; | ||
450 | struct ieee80211_rate *rate; | ||
451 | int i, len; | ||
452 | bool inval = false, rts = false, short_preamble = false; | ||
453 | struct ieee80211_tx_rate_control txrc; | ||
443 | 454 | ||
444 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; | 455 | memset(&txrc, 0, sizeof(txrc)); |
445 | 456 | ||
446 | if (likely(tx->rate_idx < 0)) { | 457 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; |
447 | rate_control_get_rate(tx->sdata, sband, tx->sta, | ||
448 | tx->skb, &rsel); | ||
449 | if (tx->sta) | ||
450 | tx->sta->last_txrate_idx = rsel.rate_idx; | ||
451 | tx->rate_idx = rsel.rate_idx; | ||
452 | if (unlikely(rsel.probe_idx >= 0)) { | ||
453 | info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; | ||
454 | tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG; | ||
455 | info->control.retries[0].rate_idx = tx->rate_idx; | ||
456 | info->control.retries[0].limit = tx->local->hw.max_altrate_tries; | ||
457 | tx->rate_idx = rsel.probe_idx; | ||
458 | } else if (info->control.retries[0].limit == 0) | ||
459 | info->control.retries[0].rate_idx = -1; | ||
460 | |||
461 | if (unlikely(tx->rate_idx < 0)) | ||
462 | return TX_DROP; | ||
463 | } else | ||
464 | info->control.retries[0].rate_idx = -1; | ||
465 | 458 | ||
466 | if (tx->sdata->vif.bss_conf.use_cts_prot && | 459 | len = min_t(int, tx->skb->len + FCS_LEN, |
467 | (tx->flags & IEEE80211_TX_FRAGMENTED) && (rsel.nonerp_idx >= 0)) { | 460 | tx->local->fragmentation_threshold); |
468 | tx->last_frag_rate_idx = tx->rate_idx; | 461 | |
469 | if (rsel.probe_idx >= 0) | 462 | /* set up the tx rate control struct we give the RC algo */ |
470 | tx->flags &= ~IEEE80211_TX_PROBE_LAST_FRAG; | 463 | txrc.hw = local_to_hw(tx->local); |
471 | else | 464 | txrc.sband = sband; |
472 | tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG; | 465 | txrc.bss_conf = &tx->sdata->vif.bss_conf; |
473 | tx->rate_idx = rsel.nonerp_idx; | 466 | txrc.skb = tx->skb; |
474 | info->tx_rate_idx = rsel.nonerp_idx; | 467 | txrc.reported_rate.idx = -1; |
475 | info->flags &= ~IEEE80211_TX_CTL_RATE_CTRL_PROBE; | 468 | txrc.max_rate_idx = tx->sdata->max_ratectrl_rateidx; |
476 | } else { | 469 | |
477 | tx->last_frag_rate_idx = tx->rate_idx; | 470 | /* set up RTS protection if desired */ |
478 | info->tx_rate_idx = tx->rate_idx; | 471 | if (tx->local->rts_threshold < IEEE80211_MAX_RTS_THRESHOLD && |
472 | len > tx->local->rts_threshold) { | ||
473 | txrc.rts = rts = true; | ||
479 | } | 474 | } |
480 | info->tx_rate_idx = tx->rate_idx; | ||
481 | 475 | ||
482 | return TX_CONTINUE; | 476 | /* |
483 | } | 477 | * Use short preamble if the BSS can handle it, but not for |
478 | * management frames unless we know the receiver can handle | ||
479 | * that -- the management frame might be to a station that | ||
480 | * just wants a probe response. | ||
481 | */ | ||
482 | if (tx->sdata->vif.bss_conf.use_short_preamble && | ||
483 | (ieee80211_is_data(hdr->frame_control) || | ||
484 | (tx->sta && test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE)))) | ||
485 | txrc.short_preamble = short_preamble = true; | ||
484 | 486 | ||
485 | static ieee80211_tx_result debug_noinline | ||
486 | ieee80211_tx_h_misc(struct ieee80211_tx_data *tx) | ||
487 | { | ||
488 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; | ||
489 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | ||
490 | struct ieee80211_supported_band *sband; | ||
491 | 487 | ||
492 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; | 488 | rate_control_get_rate(tx->sdata, tx->sta, &txrc); |
489 | |||
490 | if (unlikely(info->control.rates[0].idx < 0)) | ||
491 | return TX_DROP; | ||
492 | |||
493 | if (txrc.reported_rate.idx < 0) | ||
494 | txrc.reported_rate = info->control.rates[0]; | ||
493 | 495 | ||
494 | if (tx->sta) | 496 | if (tx->sta) |
495 | info->control.sta = &tx->sta->sta; | 497 | tx->sta->last_tx_rate = txrc.reported_rate; |
496 | 498 | ||
497 | if (!info->control.retry_limit) { | 499 | if (unlikely(!info->control.rates[0].count)) |
498 | if (!is_multicast_ether_addr(hdr->addr1)) { | 500 | info->control.rates[0].count = 1; |
499 | int len = min_t(int, tx->skb->len + FCS_LEN, | ||
500 | tx->local->fragmentation_threshold); | ||
501 | if (len > tx->local->rts_threshold | ||
502 | && tx->local->rts_threshold < | ||
503 | IEEE80211_MAX_RTS_THRESHOLD) { | ||
504 | info->flags |= IEEE80211_TX_CTL_USE_RTS_CTS; | ||
505 | info->flags |= | ||
506 | IEEE80211_TX_CTL_LONG_RETRY_LIMIT; | ||
507 | info->control.retry_limit = | ||
508 | tx->local->hw.conf.long_frame_max_tx_count - 1; | ||
509 | } else { | ||
510 | info->control.retry_limit = | ||
511 | tx->local->hw.conf.short_frame_max_tx_count - 1; | ||
512 | } | ||
513 | } else { | ||
514 | info->control.retry_limit = 1; | ||
515 | } | ||
516 | } | ||
517 | 501 | ||
518 | if (tx->flags & IEEE80211_TX_FRAGMENTED) { | 502 | if (is_multicast_ether_addr(hdr->addr1)) { |
519 | /* Do not use multiple retry rates when sending fragmented | 503 | /* |
520 | * frames. | 504 | * XXX: verify the rate is in the basic rateset |
521 | * TODO: The last fragment could still use multiple retry | 505 | */ |
522 | * rates. */ | 506 | return TX_CONTINUE; |
523 | info->control.retries[0].rate_idx = -1; | ||
524 | } | 507 | } |
525 | 508 | ||
526 | /* Use CTS protection for unicast frames sent using extended rates if | 509 | /* |
527 | * there are associated non-ERP stations and RTS/CTS is not configured | 510 | * set up the RTS/CTS rate as the fastest basic rate |
528 | * for the frame. */ | 511 | * that is not faster than the data rate |
529 | if ((tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) && | 512 | * |
530 | (sband->bitrates[tx->rate_idx].flags & IEEE80211_RATE_ERP_G) && | 513 | * XXX: Should this check all retry rates? |
531 | (tx->flags & IEEE80211_TX_UNICAST) && | 514 | */ |
532 | tx->sdata->vif.bss_conf.use_cts_prot && | 515 | if (!(info->control.rates[0].flags & IEEE80211_TX_RC_MCS)) { |
533 | !(info->flags & IEEE80211_TX_CTL_USE_RTS_CTS)) | 516 | s8 baserate = 0; |
534 | info->flags |= IEEE80211_TX_CTL_USE_CTS_PROTECT; | 517 | |
535 | 518 | rate = &sband->bitrates[info->control.rates[0].idx]; | |
536 | /* Transmit data frames using short preambles if the driver supports | 519 | |
537 | * short preambles at the selected rate and short preambles are | 520 | for (i = 0; i < sband->n_bitrates; i++) { |
538 | * available on the network at the current point in time. */ | 521 | /* must be a basic rate */ |
539 | if (ieee80211_is_data(hdr->frame_control) && | 522 | if (!(tx->sdata->vif.bss_conf.basic_rates & BIT(i))) |
540 | (sband->bitrates[tx->rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE) && | 523 | continue; |
541 | tx->sdata->vif.bss_conf.use_short_preamble && | 524 | /* must not be faster than the data rate */ |
542 | (!tx->sta || test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE))) { | 525 | if (sband->bitrates[i].bitrate > rate->bitrate) |
543 | info->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE; | 526 | continue; |
527 | /* maximum */ | ||
528 | if (sband->bitrates[baserate].bitrate < | ||
529 | sband->bitrates[i].bitrate) | ||
530 | baserate = i; | ||
531 | } | ||
532 | |||
533 | info->control.rts_cts_rate_idx = baserate; | ||
544 | } | 534 | } |
545 | 535 | ||
546 | if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) || | 536 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { |
547 | (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) { | 537 | /* |
548 | struct ieee80211_rate *rate; | 538 | * make sure there's no valid rate following |
549 | s8 baserate = -1; | 539 | * an invalid one, just in case drivers don't |
550 | int idx; | 540 | * take the API seriously to stop at -1. |
541 | */ | ||
542 | if (inval) { | ||
543 | info->control.rates[i].idx = -1; | ||
544 | continue; | ||
545 | } | ||
546 | if (info->control.rates[i].idx < 0) { | ||
547 | inval = true; | ||
548 | continue; | ||
549 | } | ||
551 | 550 | ||
552 | /* Do not use multiple retry rates when using RTS/CTS */ | 551 | /* |
553 | info->control.retries[0].rate_idx = -1; | 552 | * For now assume MCS is already set up correctly, this |
553 | * needs to be fixed. | ||
554 | */ | ||
555 | if (info->control.rates[i].flags & IEEE80211_TX_RC_MCS) { | ||
556 | WARN_ON(info->control.rates[i].idx > 76); | ||
557 | continue; | ||
558 | } | ||
554 | 559 | ||
555 | /* Use min(data rate, max base rate) as CTS/RTS rate */ | 560 | /* set up RTS protection if desired */ |
556 | rate = &sband->bitrates[tx->rate_idx]; | 561 | if (rts) |
562 | info->control.rates[i].flags |= | ||
563 | IEEE80211_TX_RC_USE_RTS_CTS; | ||
557 | 564 | ||
558 | for (idx = 0; idx < sband->n_bitrates; idx++) { | 565 | /* RC is busted */ |
559 | if (sband->bitrates[idx].bitrate > rate->bitrate) | 566 | if (WARN_ON(info->control.rates[i].idx >= |
560 | continue; | 567 | sband->n_bitrates)) { |
561 | if (tx->sdata->vif.bss_conf.basic_rates & BIT(idx) && | 568 | info->control.rates[i].idx = -1; |
562 | (baserate < 0 || | 569 | continue; |
563 | (sband->bitrates[baserate].bitrate | ||
564 | < sband->bitrates[idx].bitrate))) | ||
565 | baserate = idx; | ||
566 | } | 570 | } |
567 | 571 | ||
568 | if (baserate >= 0) | 572 | rate = &sband->bitrates[info->control.rates[i].idx]; |
569 | info->control.rts_cts_rate_idx = baserate; | 573 | |
570 | else | 574 | /* set up short preamble */ |
571 | info->control.rts_cts_rate_idx = 0; | 575 | if (short_preamble && |
576 | rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) | ||
577 | info->control.rates[i].flags |= | ||
578 | IEEE80211_TX_RC_USE_SHORT_PREAMBLE; | ||
579 | |||
580 | /* set up G protection */ | ||
581 | if (!rts && tx->sdata->vif.bss_conf.use_cts_prot && | ||
582 | rate->flags & IEEE80211_RATE_ERP_G) | ||
583 | info->control.rates[i].flags |= | ||
584 | IEEE80211_TX_RC_USE_CTS_PROTECT; | ||
572 | } | 585 | } |
573 | 586 | ||
587 | return TX_CONTINUE; | ||
588 | } | ||
589 | |||
590 | static ieee80211_tx_result debug_noinline | ||
591 | ieee80211_tx_h_misc(struct ieee80211_tx_data *tx) | ||
592 | { | ||
593 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | ||
594 | |||
574 | if (tx->sta) | 595 | if (tx->sta) |
575 | info->control.sta = &tx->sta->sta; | 596 | info->control.sta = &tx->sta->sta; |
576 | 597 | ||
@@ -678,6 +699,7 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) | |||
678 | left = payload_len - per_fragm; | 699 | left = payload_len - per_fragm; |
679 | for (i = 0; i < num_fragm - 1; i++) { | 700 | for (i = 0; i < num_fragm - 1; i++) { |
680 | struct ieee80211_hdr *fhdr; | 701 | struct ieee80211_hdr *fhdr; |
702 | struct ieee80211_tx_info *info; | ||
681 | size_t copylen; | 703 | size_t copylen; |
682 | 704 | ||
683 | if (left <= 0) | 705 | if (left <= 0) |
@@ -692,20 +714,45 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) | |||
692 | IEEE80211_ENCRYPT_TAILROOM); | 714 | IEEE80211_ENCRYPT_TAILROOM); |
693 | if (!frag) | 715 | if (!frag) |
694 | goto fail; | 716 | goto fail; |
717 | |||
695 | /* Make sure that all fragments use the same priority so | 718 | /* Make sure that all fragments use the same priority so |
696 | * that they end up using the same TX queue */ | 719 | * that they end up using the same TX queue */ |
697 | frag->priority = first->priority; | 720 | frag->priority = first->priority; |
721 | |||
698 | skb_reserve(frag, tx->local->tx_headroom + | 722 | skb_reserve(frag, tx->local->tx_headroom + |
699 | IEEE80211_ENCRYPT_HEADROOM); | 723 | IEEE80211_ENCRYPT_HEADROOM); |
724 | |||
725 | /* copy TX information */ | ||
726 | info = IEEE80211_SKB_CB(frag); | ||
727 | memcpy(info, first->cb, sizeof(frag->cb)); | ||
728 | |||
729 | /* copy/fill in 802.11 header */ | ||
700 | fhdr = (struct ieee80211_hdr *) skb_put(frag, hdrlen); | 730 | fhdr = (struct ieee80211_hdr *) skb_put(frag, hdrlen); |
701 | memcpy(fhdr, first->data, hdrlen); | 731 | memcpy(fhdr, first->data, hdrlen); |
702 | if (i == num_fragm - 2) | ||
703 | fhdr->frame_control &= cpu_to_le16(~IEEE80211_FCTL_MOREFRAGS); | ||
704 | fhdr->seq_ctrl = cpu_to_le16(seq | ((i + 1) & IEEE80211_SCTL_FRAG)); | 732 | fhdr->seq_ctrl = cpu_to_le16(seq | ((i + 1) & IEEE80211_SCTL_FRAG)); |
733 | |||
734 | if (i == num_fragm - 2) { | ||
735 | /* clear MOREFRAGS bit for the last fragment */ | ||
736 | fhdr->frame_control &= cpu_to_le16(~IEEE80211_FCTL_MOREFRAGS); | ||
737 | } else { | ||
738 | /* | ||
739 | * No multi-rate retries for fragmented frames, that | ||
740 | * would completely throw off the NAV at other STAs. | ||
741 | */ | ||
742 | info->control.rates[1].idx = -1; | ||
743 | info->control.rates[2].idx = -1; | ||
744 | info->control.rates[3].idx = -1; | ||
745 | info->control.rates[4].idx = -1; | ||
746 | BUILD_BUG_ON(IEEE80211_TX_MAX_RATES != 5); | ||
747 | info->flags &= ~IEEE80211_TX_CTL_RATE_CTRL_PROBE; | ||
748 | } | ||
749 | |||
750 | /* copy data */ | ||
705 | copylen = left > per_fragm ? per_fragm : left; | 751 | copylen = left > per_fragm ? per_fragm : left; |
706 | memcpy(skb_put(frag, copylen), pos, copylen); | 752 | memcpy(skb_put(frag, copylen), pos, copylen); |
707 | memcpy(frag->cb, first->cb, sizeof(frag->cb)); | 753 | |
708 | skb_copy_queue_mapping(frag, first); | 754 | skb_copy_queue_mapping(frag, first); |
755 | |||
709 | frag->do_not_encrypt = first->do_not_encrypt; | 756 | frag->do_not_encrypt = first->do_not_encrypt; |
710 | 757 | ||
711 | pos += copylen; | 758 | pos += copylen; |
@@ -765,12 +812,10 @@ ieee80211_tx_h_calculate_duration(struct ieee80211_tx_data *tx) | |||
765 | tx->extra_frag[0]->len); | 812 | tx->extra_frag[0]->len); |
766 | 813 | ||
767 | for (i = 0; i < tx->num_extra_frag; i++) { | 814 | for (i = 0; i < tx->num_extra_frag; i++) { |
768 | if (i + 1 < tx->num_extra_frag) { | 815 | if (i + 1 < tx->num_extra_frag) |
769 | next_len = tx->extra_frag[i + 1]->len; | 816 | next_len = tx->extra_frag[i + 1]->len; |
770 | } else { | 817 | else |
771 | next_len = 0; | 818 | next_len = 0; |
772 | tx->rate_idx = tx->last_frag_rate_idx; | ||
773 | } | ||
774 | 819 | ||
775 | hdr = (struct ieee80211_hdr *)tx->extra_frag[i]->data; | 820 | hdr = (struct ieee80211_hdr *)tx->extra_frag[i]->data; |
776 | hdr->duration_id = ieee80211_duration(tx, 0, next_len); | 821 | hdr->duration_id = ieee80211_duration(tx, 0, next_len); |
@@ -823,7 +868,6 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
823 | (struct ieee80211_radiotap_header *) skb->data; | 868 | (struct ieee80211_radiotap_header *) skb->data; |
824 | struct ieee80211_supported_band *sband; | 869 | struct ieee80211_supported_band *sband; |
825 | int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len); | 870 | int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len); |
826 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
827 | 871 | ||
828 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; | 872 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; |
829 | 873 | ||
@@ -837,8 +881,6 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
837 | */ | 881 | */ |
838 | 882 | ||
839 | while (!ret) { | 883 | while (!ret) { |
840 | int i, target_rate; | ||
841 | |||
842 | ret = ieee80211_radiotap_iterator_next(&iterator); | 884 | ret = ieee80211_radiotap_iterator_next(&iterator); |
843 | 885 | ||
844 | if (ret) | 886 | if (ret) |
@@ -852,38 +894,6 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
852 | * get_unaligned((type *)iterator.this_arg) to dereference | 894 | * get_unaligned((type *)iterator.this_arg) to dereference |
853 | * iterator.this_arg for type "type" safely on all arches. | 895 | * iterator.this_arg for type "type" safely on all arches. |
854 | */ | 896 | */ |
855 | case IEEE80211_RADIOTAP_RATE: | ||
856 | /* | ||
857 | * radiotap rate u8 is in 500kbps units eg, 0x02=1Mbps | ||
858 | * ieee80211 rate int is in 100kbps units eg, 0x0a=1Mbps | ||
859 | */ | ||
860 | target_rate = (*iterator.this_arg) * 5; | ||
861 | for (i = 0; i < sband->n_bitrates; i++) { | ||
862 | struct ieee80211_rate *r; | ||
863 | |||
864 | r = &sband->bitrates[i]; | ||
865 | |||
866 | if (r->bitrate == target_rate) { | ||
867 | tx->rate_idx = i; | ||
868 | break; | ||
869 | } | ||
870 | } | ||
871 | break; | ||
872 | |||
873 | case IEEE80211_RADIOTAP_ANTENNA: | ||
874 | /* | ||
875 | * radiotap uses 0 for 1st ant, mac80211 is 1 for | ||
876 | * 1st ant | ||
877 | */ | ||
878 | info->antenna_sel_tx = (*iterator.this_arg) + 1; | ||
879 | break; | ||
880 | |||
881 | #if 0 | ||
882 | case IEEE80211_RADIOTAP_DBM_TX_POWER: | ||
883 | control->power_level = *iterator.this_arg; | ||
884 | break; | ||
885 | #endif | ||
886 | |||
887 | case IEEE80211_RADIOTAP_FLAGS: | 897 | case IEEE80211_RADIOTAP_FLAGS: |
888 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS) { | 898 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS) { |
889 | /* | 899 | /* |
@@ -949,8 +959,6 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx, | |||
949 | tx->local = local; | 959 | tx->local = local; |
950 | tx->sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 960 | tx->sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
951 | tx->channel = local->hw.conf.channel; | 961 | tx->channel = local->hw.conf.channel; |
952 | tx->rate_idx = -1; | ||
953 | tx->last_frag_rate_idx = -1; | ||
954 | /* | 962 | /* |
955 | * Set this flag (used below to indicate "automatic fragmentation"), | 963 | * Set this flag (used below to indicate "automatic fragmentation"), |
956 | * it will be cleared/left by radiotap as desired. | 964 | * it will be cleared/left by radiotap as desired. |
@@ -1051,23 +1059,11 @@ static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb, | |||
1051 | if (!tx->extra_frag[i]) | 1059 | if (!tx->extra_frag[i]) |
1052 | continue; | 1060 | continue; |
1053 | info = IEEE80211_SKB_CB(tx->extra_frag[i]); | 1061 | info = IEEE80211_SKB_CB(tx->extra_frag[i]); |
1054 | info->flags &= ~(IEEE80211_TX_CTL_USE_RTS_CTS | | 1062 | info->flags &= ~(IEEE80211_TX_CTL_CLEAR_PS_FILT | |
1055 | IEEE80211_TX_CTL_USE_CTS_PROTECT | | ||
1056 | IEEE80211_TX_CTL_CLEAR_PS_FILT | | ||
1057 | IEEE80211_TX_CTL_FIRST_FRAGMENT); | 1063 | IEEE80211_TX_CTL_FIRST_FRAGMENT); |
1058 | if (netif_subqueue_stopped(local->mdev, | 1064 | if (netif_subqueue_stopped(local->mdev, |
1059 | tx->extra_frag[i])) | 1065 | tx->extra_frag[i])) |
1060 | return IEEE80211_TX_FRAG_AGAIN; | 1066 | return IEEE80211_TX_FRAG_AGAIN; |
1061 | if (i == tx->num_extra_frag) { | ||
1062 | info->tx_rate_idx = tx->last_frag_rate_idx; | ||
1063 | |||
1064 | if (tx->flags & IEEE80211_TX_PROBE_LAST_FRAG) | ||
1065 | info->flags |= | ||
1066 | IEEE80211_TX_CTL_RATE_CTRL_PROBE; | ||
1067 | else | ||
1068 | info->flags &= | ||
1069 | ~IEEE80211_TX_CTL_RATE_CTRL_PROBE; | ||
1070 | } | ||
1071 | 1067 | ||
1072 | ret = local->ops->tx(local_to_hw(local), | 1068 | ret = local->ops->tx(local_to_hw(local), |
1073 | tx->extra_frag[i]); | 1069 | tx->extra_frag[i]); |
@@ -1204,9 +1200,6 @@ retry: | |||
1204 | store->skb = skb; | 1200 | store->skb = skb; |
1205 | store->extra_frag = tx.extra_frag; | 1201 | store->extra_frag = tx.extra_frag; |
1206 | store->num_extra_frag = tx.num_extra_frag; | 1202 | store->num_extra_frag = tx.num_extra_frag; |
1207 | store->last_frag_rate_idx = tx.last_frag_rate_idx; | ||
1208 | store->last_frag_rate_ctrl_probe = | ||
1209 | !!(tx.flags & IEEE80211_TX_PROBE_LAST_FRAG); | ||
1210 | } | 1203 | } |
1211 | out: | 1204 | out: |
1212 | rcu_read_unlock(); | 1205 | rcu_read_unlock(); |
@@ -1763,10 +1756,7 @@ void ieee80211_tx_pending(unsigned long data) | |||
1763 | store = &local->pending_packet[i]; | 1756 | store = &local->pending_packet[i]; |
1764 | tx.extra_frag = store->extra_frag; | 1757 | tx.extra_frag = store->extra_frag; |
1765 | tx.num_extra_frag = store->num_extra_frag; | 1758 | tx.num_extra_frag = store->num_extra_frag; |
1766 | tx.last_frag_rate_idx = store->last_frag_rate_idx; | ||
1767 | tx.flags = 0; | 1759 | tx.flags = 0; |
1768 | if (store->last_frag_rate_ctrl_probe) | ||
1769 | tx.flags |= IEEE80211_TX_PROBE_LAST_FRAG; | ||
1770 | ret = __ieee80211_tx(local, store->skb, &tx); | 1760 | ret = __ieee80211_tx(local, store->skb, &tx); |
1771 | if (ret) { | 1761 | if (ret) { |
1772 | if (ret == IEEE80211_TX_FRAG_AGAIN) | 1762 | if (ret == IEEE80211_TX_FRAG_AGAIN) |
@@ -1854,7 +1844,6 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1854 | struct ieee80211_sub_if_data *sdata = NULL; | 1844 | struct ieee80211_sub_if_data *sdata = NULL; |
1855 | struct ieee80211_if_ap *ap = NULL; | 1845 | struct ieee80211_if_ap *ap = NULL; |
1856 | struct ieee80211_if_sta *ifsta = NULL; | 1846 | struct ieee80211_if_sta *ifsta = NULL; |
1857 | struct rate_selection rsel; | ||
1858 | struct beacon_data *beacon; | 1847 | struct beacon_data *beacon; |
1859 | struct ieee80211_supported_band *sband; | 1848 | struct ieee80211_supported_band *sband; |
1860 | enum ieee80211_band band = local->hw.conf.channel->band; | 1849 | enum ieee80211_band band = local->hw.conf.channel->band; |
@@ -1958,32 +1947,23 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1958 | skb->do_not_encrypt = 1; | 1947 | skb->do_not_encrypt = 1; |
1959 | 1948 | ||
1960 | info->band = band; | 1949 | info->band = band; |
1961 | rate_control_get_rate(sdata, sband, NULL, skb, &rsel); | 1950 | /* |
1962 | 1951 | * XXX: For now, always use the lowest rate | |
1963 | if (unlikely(rsel.rate_idx < 0)) { | 1952 | */ |
1964 | if (net_ratelimit()) { | 1953 | info->control.rates[0].idx = 0; |
1965 | printk(KERN_DEBUG "%s: ieee80211_beacon_get: " | 1954 | info->control.rates[0].count = 1; |
1966 | "no rate found\n", | 1955 | info->control.rates[1].idx = -1; |
1967 | wiphy_name(local->hw.wiphy)); | 1956 | info->control.rates[2].idx = -1; |
1968 | } | 1957 | info->control.rates[3].idx = -1; |
1969 | dev_kfree_skb_any(skb); | 1958 | info->control.rates[4].idx = -1; |
1970 | skb = NULL; | 1959 | BUILD_BUG_ON(IEEE80211_TX_MAX_RATES != 5); |
1971 | goto out; | ||
1972 | } | ||
1973 | 1960 | ||
1974 | info->control.vif = vif; | 1961 | info->control.vif = vif; |
1975 | info->tx_rate_idx = rsel.rate_idx; | ||
1976 | 1962 | ||
1977 | info->flags |= IEEE80211_TX_CTL_NO_ACK; | 1963 | info->flags |= IEEE80211_TX_CTL_NO_ACK; |
1978 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; | 1964 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; |
1979 | info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; | 1965 | info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; |
1980 | if (sdata->vif.bss_conf.use_short_preamble && | 1966 | out: |
1981 | sband->bitrates[rsel.rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE) | ||
1982 | info->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE; | ||
1983 | |||
1984 | info->control.retry_limit = 1; | ||
1985 | |||
1986 | out: | ||
1987 | rcu_read_unlock(); | 1967 | rcu_read_unlock(); |
1988 | return skb; | 1968 | return skb; |
1989 | } | 1969 | } |
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c index f7e442f80a17..31d2e74a1bc0 100644 --- a/net/mac80211/wext.c +++ b/net/mac80211/wext.c | |||
@@ -636,8 +636,8 @@ static int ieee80211_ioctl_giwrate(struct net_device *dev, | |||
636 | 636 | ||
637 | sta = sta_info_get(local, sdata->u.sta.bssid); | 637 | sta = sta_info_get(local, sdata->u.sta.bssid); |
638 | 638 | ||
639 | if (sta && sta->last_txrate_idx < sband->n_bitrates) | 639 | if (sta && !(sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)) |
640 | rate->value = sband->bitrates[sta->last_txrate_idx].bitrate; | 640 | rate->value = sband->bitrates[sta->last_tx_rate.idx].bitrate; |
641 | else | 641 | else |
642 | rate->value = 0; | 642 | rate->value = 0; |
643 | 643 | ||