aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/adm8211.c21
-rw-r--r--drivers/net/wireless/ath5k/base.c34
-rw-r--r--drivers/net/wireless/ath9k/main.c18
-rw-r--r--drivers/net/wireless/ath9k/rc.c40
-rw-r--r--drivers/net/wireless/ath9k/xmit.c28
-rw-r--r--drivers/net/wireless/b43/dma.c4
-rw-r--r--drivers/net/wireless/b43/main.c2
-rw-r--r--drivers/net/wireless/b43/pio.c3
-rw-r--r--drivers/net/wireless/b43/xmit.c60
-rw-r--r--drivers/net/wireless/b43/xmit.h5
-rw-r--r--drivers/net/wireless/b43legacy/dma.c46
-rw-r--r--drivers/net/wireless/b43legacy/main.c2
-rw-r--r--drivers/net/wireless/b43legacy/pio.c31
-rw-r--r--drivers/net/wireless/b43legacy/xmit.c26
-rw-r--r--drivers/net/wireless/b43legacy/xmit.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c57
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c65
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c37
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c19
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c5
-rw-r--r--drivers/net/wireless/libertas_tf/main.c4
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c12
-rw-r--r--drivers/net/wireless/p54/p54common.c26
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c14
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c14
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c22
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h9
-rw-r--r--drivers/net/wireless/rtl8180_dev.c28
-rw-r--r--drivers/net/wireless/rtl8187_dev.c18
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c32
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c2
-rw-r--r--include/net/mac80211.h254
-rw-r--r--net/mac80211/ieee80211_i.h8
-rw-r--r--net/mac80211/main.c54
-rw-r--r--net/mac80211/mesh_hwmp.c6
-rw-r--r--net/mac80211/rate.c52
-rw-r--r--net/mac80211/rate.h5
-rw-r--r--net/mac80211/rc80211_minstrel.c72
-rw-r--r--net/mac80211/rc80211_pid.h1
-rw-r--r--net/mac80211/rc80211_pid_algo.c27
-rw-r--r--net/mac80211/rc80211_pid_debugfs.c5
-rw-r--r--net/mac80211/sta_info.h4
-rw-r--r--net/mac80211/tx.c378
-rw-r--r--net/mac80211/wext.c4
47 files changed, 889 insertions, 685 deletions
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c
index 9a1e0c514c0..b96ebfe4ef3 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)
pci_unmap_single(priv->pdev, info->mapping,
info->skb->len, PCI_DMA_TODEVICE);
- memset(&txi->status, 0, sizeof(txi->status));
+ ieee80211_tx_info_clear_status(txi);
+
skb_pull(skb, sizeof(struct adm8211_tx_hdr));
memcpy(skb_push(skb, info->hdrlen), skb->cb, info->hdrlen);
- if (!(txi->flags & IEEE80211_TX_CTL_NO_ACK)) {
- if (status & TDES0_STATUS_ES)
- txi->status.excessive_retries = 1;
- else
- txi->flags |= IEEE80211_TX_STAT_ACK;
- }
+ if (!(txi->flags & IEEE80211_TX_CTL_NO_ACK) &&
+ !(status & TDES0_STATUS_ES))
+ txi->flags |= IEEE80211_TX_STAT_ACK;
+
ieee80211_tx_status_irqsafe(dev, skb);
info->skb = NULL;
@@ -1691,8 +1690,10 @@ static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
struct ieee80211_hdr *hdr;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_rate *txrate = ieee80211_get_tx_rate(dev, info);
+ u8 rc_flags;
- short_preamble = !!(txrate->flags & IEEE80211_TX_CTL_SHORT_PREAMBLE);
+ rc_flags = info->control.rates[0].flags;
+ short_preamble = !!(rc_flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE);
plcp_signal = txrate->bitrate;
hdr = (struct ieee80211_hdr *)skb->data;
@@ -1724,10 +1725,10 @@ static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
if (short_preamble)
txhdr->header_control |= cpu_to_le16(ADM8211_TXHDRCTL_SHORT_PREAMBLE);
- if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS)
+ if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS)
txhdr->header_control |= cpu_to_le16(ADM8211_TXHDRCTL_ENABLE_RTS);
- txhdr->retry_limit = info->control.retry_limit;
+ txhdr->retry_limit = info->control.rates[0].count;
adm8211_tx_raw(dev, skb, plcp_signal, hdrlen);
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index 44401f6f578..3773d983ea6 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,
/* set up multi-rate retry capabilities */
if (sc->ah->ah_version == AR5K_AR5212) {
- hw->max_altrates = 3;
- hw->max_altrate_tries = 11;
+ hw->max_rates = 4;
+ hw->max_rate_tries = 11;
}
/* Finish private driver data initialization */
@@ -1181,7 +1181,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL,
(sc->power_level * 2),
ieee80211_get_tx_rate(sc->hw, info)->hw_value,
- info->control.retry_limit, keyidx, 0, flags, 0, 0);
+ info->control.rates[0].count, keyidx, 0, flags, 0, 0);
if (ret)
goto err_unmap;
@@ -1193,7 +1193,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
break;
mrr_rate[i] = rate->hw_value;
- mrr_tries[i] = info->control.retries[i].limit;
+ mrr_tries[i] = info->control.rates[i + 1].count;
}
ah->ah_setup_mrr_tx_desc(ah, ds,
@@ -1849,30 +1849,26 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
pci_unmap_single(sc->pdev, bf->skbaddr, skb->len,
PCI_DMA_TODEVICE);
- memset(&info->status, 0, sizeof(info->status));
- info->tx_rate_idx = ath5k_hw_to_driver_rix(sc,
- ts.ts_rate[ts.ts_final_idx]);
- info->status.retry_count = ts.ts_longretry;
-
+ ieee80211_tx_info_clear_status(info);
for (i = 0; i < 4; i++) {
- struct ieee80211_tx_altrate *r =
- &info->status.retries[i];
+ struct ieee80211_tx_rate *r =
+ &info->status.rates[i];
if (ts.ts_rate[i]) {
- r->rate_idx = ath5k_hw_to_driver_rix(sc, ts.ts_rate[i]);
- r->limit = ts.ts_retry[i];
+ r->idx = ath5k_hw_to_driver_rix(sc, ts.ts_rate[i]);
+ r->count = ts.ts_retry[i];
} else {
- r->rate_idx = -1;
- r->limit = 0;
+ r->idx = -1;
+ r->count = 0;
}
}
- info->status.excessive_retries = 0;
+ /* count the successful attempt as well */
+ info->status.rates[ts.ts_final_idx].count++;
+
if (unlikely(ts.ts_status)) {
sc->ll_stats.dot11ACKFailureCount++;
- if (ts.ts_status & AR5K_TXERR_XRETRY)
- info->status.excessive_retries = 1;
- else if (ts.ts_status & AR5K_TXERR_FILT)
+ if (ts.ts_status & AR5K_TXERR_FILT)
info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
} else {
info->flags |= IEEE80211_TX_STAT_ACK;
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
index 32acaf7ff62..a7656a3ea1b 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,
DPRINTF(sc, ATH_DBG_XMIT,
"%s: TX complete: skb: %p\n", __func__, skb);
+ ieee80211_tx_info_clear_status(tx_info);
if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK ||
tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) {
- /* free driver's private data area of tx_info */
- if (tx_info->driver_data[0] != NULL)
- kfree(tx_info->driver_data[0]);
- tx_info->driver_data[0] = NULL;
+ /* free driver's private data area of tx_info, XXX: HACK! */
+ if (tx_info->control.vif != NULL)
+ kfree(tx_info->control.vif);
+ tx_info->control.vif = NULL;
}
if (tx_status->flags & ATH_TX_BAR) {
@@ -470,17 +471,12 @@ void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
tx_status->flags &= ~ATH_TX_BAR;
}
- if (tx_status->flags & (ATH_TX_ERROR | ATH_TX_XRETRY)) {
- if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) {
- /* Frame was not ACKed, but an ACK was expected */
- tx_info->status.excessive_retries = 1;
- }
- } else {
+ if (!(tx_status->flags & (ATH_TX_ERROR | ATH_TX_XRETRY))) {
/* Frame was ACKed */
tx_info->flags |= IEEE80211_TX_STAT_ACK;
}
- tx_info->status.retry_count = tx_status->retries;
+ tx_info->status.rates[0].count = tx_status->retries + 1;
ieee80211_tx_status(hw, skb);
if (an)
diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c
index 9b252603096..6afafeddeda 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,
hdr = (struct ieee80211_hdr *)skb->data;
fc = hdr->frame_control;
- tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0];
+ /* XXX: UGLY HACK!! */
+ tx_info_priv = (struct ath_tx_info_priv *)tx_info->control.vif;
spin_lock_bh(&sc->node_lock);
an = ath_node_find(sc, hdr->addr1);
spin_unlock_bh(&sc->node_lock);
- if (!an || !priv_sta || !ieee80211_is_data(fc)) {
- if (tx_info->driver_data[0] != NULL) {
- kfree(tx_info->driver_data[0]);
- tx_info->driver_data[0] = NULL;
- }
+ if (tx_info_priv == NULL)
return;
- }
- if (tx_info->driver_data[0] != NULL) {
+
+ if (an && priv_sta && ieee80211_is_data(fc))
ath_rate_tx_complete(sc, an, priv_sta, tx_info_priv);
- kfree(tx_info->driver_data[0]);
- tx_info->driver_data[0] = NULL;
- }
+
+ kfree(tx_info_priv);
+ tx_info->control.vif = NULL;
}
static void ath_tx_aggr_resp(struct ath_softc *sc,
@@ -1927,10 +1924,11 @@ static void ath_tx_aggr_resp(struct ath_softc *sc,
}
}
-static void ath_get_rate(void *priv, struct ieee80211_supported_band *sband,
- struct ieee80211_sta *sta, void *priv_sta,
- struct sk_buff *skb, struct rate_selection *sel)
+static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
+ struct ieee80211_tx_rate_control *txrc)
{
+ struct ieee80211_supported_band *sband = txrc->sband;
+ struct sk_buff *skb = txrc->skb;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct ath_softc *sc = priv;
struct ieee80211_hw *hw = sc->hw;
@@ -1945,17 +1943,17 @@ static void ath_get_rate(void *priv, struct ieee80211_supported_band *sband,
DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__);
- /* allocate driver private area of tx_info */
- tx_info->driver_data[0] = kzalloc(sizeof(*tx_info_priv), GFP_ATOMIC);
- ASSERT(tx_info->driver_data[0] != NULL);
- tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0];
+ /* allocate driver private area of tx_info, XXX: UGLY HACK! */
+ tx_info->control.vif = kzalloc(sizeof(*tx_info_priv), GFP_ATOMIC);
+ tx_info_priv = (struct ath_tx_info_priv *)tx_info->control.vif;
+ ASSERT(tx_info_priv != NULL);
lowest_idx = rate_lowest_index(sband, sta);
tx_info_priv->min_rate = (sband->bitrates[lowest_idx].bitrate * 2) / 10;
/* lowest rate for management and multicast/broadcast frames */
if (!ieee80211_is_data(fc) ||
is_multicast_ether_addr(hdr->addr1) || !sta) {
- sel->rate_idx = lowest_idx;
+ tx_info->control.rates[0].idx = lowest_idx;
return;
}
@@ -1966,8 +1964,10 @@ static void ath_get_rate(void *priv, struct ieee80211_supported_band *sband,
tx_info_priv->rcs,
&is_probe,
false);
+#if 0
if (is_probe)
sel->probe_idx = ath_rc_priv->tx_ratectrl.probe_rate;
+#endif
/* Ratecontrol sometimes returns invalid rate index */
if (tx_info_priv->rcs[0].rix != 0xff)
@@ -1975,7 +1975,7 @@ static void ath_get_rate(void *priv, struct ieee80211_supported_band *sband,
else
tx_info_priv->rcs[0].rix = ath_rc_priv->prev_data_rix;
- sel->rate_idx = tx_info_priv->rcs[0].rix;
+ tx_info->control.rates[0].idx = tx_info_priv->rcs[0].rix;
/* Check if aggregation has to be enabled for this tid */
diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c
index ba818cc2fb5..9fa395418a6 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)
hdr = (struct ieee80211_hdr *)skb->data;
fc = hdr->frame_control;
- tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0];
+
+ /* XXX: HACK! */
+ tx_info_priv = (struct ath_tx_info_priv *)tx_info->control.vif;
if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc)) {
txctl->use_minrate = 1;
@@ -288,13 +290,16 @@ static int ath_tx_prepare(struct ath_softc *sc,
if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
txctl->flags |= ATH9K_TXDESC_NOACK;
- if (tx_info->flags & IEEE80211_TX_CTL_USE_RTS_CTS)
+
+ if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
txctl->flags |= ATH9K_TXDESC_RTSENA;
/*
* Setup for rate calculations.
*/
- tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0];
+
+ /* XXX: HACK! */
+ tx_info_priv = (struct ath_tx_info_priv *)tx_info->control.vif;
rcs = tx_info_priv->rcs;
if (ieee80211_is_data(fc) && !txctl->use_minrate) {
@@ -855,7 +860,9 @@ static int ath_tx_send_normal(struct ath_softc *sc,
skb = (struct sk_buff *)bf->bf_mpdu;
tx_info = IEEE80211_SKB_CB(skb);
- tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0];
+
+ /* XXX: HACK! */
+ tx_info_priv = (struct ath_tx_info_priv *)tx_info->control.vif;
memcpy(bf->bf_rcs, tx_info_priv->rcs, 4 * sizeof(tx_info_priv->rcs[0]));
/* 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)
}
skb = bf->bf_mpdu;
tx_info = IEEE80211_SKB_CB(skb);
- tx_info_priv = (struct ath_tx_info_priv *)
- tx_info->driver_data[0];
+
+ /* XXX: HACK! */
+ tx_info_priv = (struct ath_tx_info_priv *) tx_info->control.vif;
if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT)
tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 &&
@@ -1431,7 +1439,8 @@ static int ath_tx_send_ampdu(struct ath_softc *sc,
skb = (struct sk_buff *)bf->bf_mpdu;
tx_info = IEEE80211_SKB_CB(skb);
- tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0];
+ /* XXX: HACK! */
+ tx_info_priv = (struct ath_tx_info_priv *)tx_info->control.vif;
memcpy(bf->bf_rcs, tx_info_priv->rcs, 4 * sizeof(tx_info_priv->rcs[0]));
/* Add sub-frame to BAW */
@@ -1466,7 +1475,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc,
skb = (struct sk_buff *)bf->bf_mpdu;
tx_info = IEEE80211_SKB_CB(skb);
tx_info_priv = (struct ath_tx_info_priv *)
- tx_info->driver_data[0];
+ tx_info->control.vif; /* XXX: HACK! */
memcpy(bf->bf_rcs,
tx_info_priv->rcs, 4 * sizeof(tx_info_priv->rcs[0]));
@@ -1927,7 +1936,8 @@ static int ath_tx_start_dma(struct ath_softc *sc,
bf->bf_flags = txctl->flags;
bf->bf_keytype = txctl->keytype;
- tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0];
+ /* XXX: HACK! */
+ tx_info_priv = (struct ath_tx_info_priv *)tx_info->control.vif;
rcs = tx_info_priv->rcs;
bf->bf_rcs[0] = rcs[0];
bf->bf_rcs[1] = rcs[1];
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index 098f886976f..6d65a02b705 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,
info = IEEE80211_SKB_CB(meta->skb);
- memset(&info->status, 0, sizeof(info->status));
-
/*
* Call back to inform the ieee80211 subsystem about
* the status of the transmission.
*/
- frame_succeed = b43_fill_txstatus_report(info, status);
+ frame_succeed = b43_fill_txstatus_report(dev, info, status);
#ifdef CONFIG_B43_DEBUG
if (frame_succeed)
ring->nr_succeed_tx_packets++;
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 9aeeb6553a9..2a599fb772d 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)
BIT(NL80211_IFTYPE_ADHOC);
hw->queues = b43_modparam_qos ? 4 : 1;
- hw->max_altrates = 1;
+ hw->max_rates = 2;
SET_IEEE80211_DEV(hw, dev->dev);
if (is_valid_ether_addr(sprom->et1mac))
SET_IEEE80211_PERM_ADDR(hw, sprom->et1mac);
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c
index 40159126759..1036bef8c4c 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,
spin_lock(&q->lock); /* IRQs are already disabled. */
info = IEEE80211_SKB_CB(pack->skb);
- memset(&info->status, 0, sizeof(info->status));
- b43_fill_txstatus_report(info, status);
+ b43_fill_txstatus_report(dev, info, status);
total_len = pack->skb->len + b43_txhdr_size(dev);
total_len = roundup(total_len, 4);
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index 2fabcf8f047..adba89b816d 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,
u8 *_txhdr,
const unsigned char *fragment_data,
unsigned int fragment_len,
- const struct ieee80211_tx_info *info,
+ struct ieee80211_tx_info *info,
u16 cookie)
{
struct b43_txhdr *txhdr = (struct b43_txhdr *)_txhdr;
@@ -202,6 +202,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
u16 phy_ctl = 0;
u8 extra_ft = 0;
struct ieee80211_rate *txrate;
+ struct ieee80211_tx_rate *rates;
memset(txhdr, 0, sizeof(*txhdr));
@@ -291,7 +292,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
phy_ctl |= B43_TXH_PHY_ENC_OFDM;
else
phy_ctl |= B43_TXH_PHY_ENC_CCK;
- if (info->flags & IEEE80211_TX_CTL_SHORT_PREAMBLE)
+ if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
phy_ctl |= B43_TXH_PHY_SHORTPRMBL;
switch (b43_ieee80211_antenna_sanitize(dev, info->antenna_sel_tx)) {
@@ -314,6 +315,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
B43_WARN_ON(1);
}
+ rates = info->control.rates;
/* MAC control */
if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
mac_ctl |= B43_TXH_MAC_ACK;
@@ -324,12 +326,22 @@ int b43_generate_txhdr(struct b43_wldev *dev,
mac_ctl |= B43_TXH_MAC_STMSDU;
if (phy->type == B43_PHYTYPE_A)
mac_ctl |= B43_TXH_MAC_5GHZ;
- if (info->flags & IEEE80211_TX_CTL_LONG_RETRY_LIMIT)
+
+ /* Overwrite rates[0].count to make the retry calculation
+ * in the tx status easier. need the actual retry limit to
+ * detect whether the fallback rate was used.
+ */
+ if ((rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
+ (rates[0].count <= dev->wl->hw->conf.long_frame_max_tx_count)) {
+ rates[0].count = dev->wl->hw->conf.long_frame_max_tx_count;
mac_ctl |= B43_TXH_MAC_LONGFRAME;
+ } else {
+ rates[0].count = dev->wl->hw->conf.short_frame_max_tx_count;
+ }
/* Generate the RTS or CTS-to-self frame */
- if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) ||
- (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) {
+ if ((rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
+ (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) {
unsigned int len;
struct ieee80211_hdr *hdr;
int rts_rate, rts_rate_fb;
@@ -344,7 +356,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
rts_rate_fb = b43_calc_fallback_rate(rts_rate);
rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb);
- if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) {
+ if (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
struct ieee80211_cts *cts;
if (b43_is_old_txhdr_format(dev)) {
@@ -687,10 +699,18 @@ void b43_handle_txstatus(struct b43_wldev *dev,
/* Fill out the mac80211 TXstatus report based on the b43-specific
* txstatus report data. This returns a boolean whether the frame was
* successfully transmitted. */
-bool b43_fill_txstatus_report(struct ieee80211_tx_info *report,
+bool b43_fill_txstatus_report(struct b43_wldev *dev,
+ struct ieee80211_tx_info *report,
const struct b43_txstatus *status)
{
bool frame_success = 1;
+ int retry_limit;
+
+ /* preserve the confiured retry limit before clearing the status
+ * The xmit function has overwritten the rc's value with the actual
+ * retry limit done by the hardware */
+ retry_limit = report->status.rates[0].count;
+ ieee80211_tx_info_clear_status(report);
if (status->acked) {
/* The frame was ACKed. */
@@ -700,14 +720,32 @@ bool b43_fill_txstatus_report(struct ieee80211_tx_info *report,
if (!(report->flags & IEEE80211_TX_CTL_NO_ACK)) {
/* ...but we expected an ACK. */
frame_success = 0;
- report->status.excessive_retries = 1;
}
}
if (status->frame_count == 0) {
/* The frame was not transmitted at all. */
- report->status.retry_count = 0;
- } else
- report->status.retry_count = status->frame_count - 1;
+ report->status.rates[0].count = 0;
+ } else if (status->rts_count > dev->wl->hw->conf.short_frame_max_tx_count) {
+ /*
+ * If the short retries (RTS, not data frame) have exceeded
+ * the limit, the hw will not have tried the selected rate,
+ * but will have used the fallback rate instead.
+ * Don't let the rate control count attempts for the selected
+ * rate in this case, otherwise the statistics will be off.
+ */
+ report->status.rates[0].count = 0;
+ report->status.rates[1].count = status->frame_count;
+ } else {
+ if (status->frame_count > retry_limit) {
+ report->status.rates[0].count = retry_limit;
+ report->status.rates[1].count = status->frame_count -
+ retry_limit;
+
+ } else {
+ report->status.rates[0].count = status->frame_count;
+ report->status.rates[1].idx = -1;
+ }
+ }
return frame_success;
}
diff --git a/drivers/net/wireless/b43/xmit.h b/drivers/net/wireless/b43/xmit.h
index 0215faf4754..4fb2a190f7a 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,
u8 * txhdr,
const unsigned char *fragment_data,
unsigned int fragment_len,
- const struct ieee80211_tx_info *txctl, u16 cookie);
+ struct ieee80211_tx_info *txctl, u16 cookie);
/* Transmit Status */
struct b43_txstatus {
@@ -294,7 +294,8 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr);
void b43_handle_txstatus(struct b43_wldev *dev,
const struct b43_txstatus *status);
-bool b43_fill_txstatus_report(struct ieee80211_tx_info *report,
+bool b43_fill_txstatus_report(struct b43_wldev *dev,
+ struct ieee80211_tx_info *report,
const struct b43_txstatus *status);
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 fb6819e40f3..308c2647f00 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,
struct b43legacy_dmaring *ring;
struct b43legacy_dmadesc_generic *desc;
struct b43legacy_dmadesc_meta *meta;
+ int retry_limit;
int slot;
ring = parse_cookie(dev, status->cookie, &slot);
@@ -1437,25 +1438,42 @@ void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev,
struct ieee80211_tx_info *info;
BUG_ON(!meta->skb);
info = IEEE80211_SKB_CB(meta->skb);
- /* Call back to inform the ieee80211 subsystem about the
- * status of the transmission.
- * Some fields of txstat are already filled in dma_tx().
- */
- memset(&info->status, 0, sizeof(info->status));
+ /* preserve the confiured retry limit before clearing the status
+ * The xmit function has overwritten the rc's value with the actual
+ * retry limit done by the hardware */
+ retry_limit = info->status.rates[0].count;
+ ieee80211_tx_info_clear_status(info);
- if (status->acked) {
+ if (status->acked)
info->flags |= IEEE80211_TX_STAT_ACK;
+
+ if (status->rts_count > dev->wl->hw->conf.short_frame_max_tx_count) {
+ /*
+ * If the short retries (RTS, not data frame) have exceeded
+ * the limit, the hw will not have tried the selected rate,
+ * but will have used the fallback rate instead.
+ * Don't let the rate control count attempts for the selected
+ * rate in this case, otherwise the statistics will be off.
+ */
+ info->status.rates[0].count = 0;
+ info->status.rates[1].count = status->frame_count;
} else {
- if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
- info->status.excessive_retries = 1;
+ if (status->frame_count > retry_limit) {
+ info->status.rates[0].count = retry_limit;
+ info->status.rates[1].count = status->frame_count -
+ retry_limit;
+
+ } else {
+ info->status.rates[0].count = status->frame_count;
+ info->status.rates[1].idx = -1;
+ }
}
- if (status->frame_count == 0) {
- /* The frame was not transmitted at all. */
- info->status.retry_count = 0;
- } else
- info->status.retry_count = status->frame_count
- - 1;
+
+ /* Call back to inform the ieee80211 subsystem about the
+ * status of the transmission.
+ * Some fields of txstat are already filled in dma_tx().
+ */
ieee80211_tx_status_irqsafe(dev->wl->hw, meta->skb);
/* skb is freed by ieee80211_tx_status_irqsafe() */
meta->skb = NULL;
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 78e46365f69..9edbdf9cb50 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)
BIT(NL80211_IFTYPE_WDS) |
BIT(NL80211_IFTYPE_ADHOC);
hw->queues = 1; /* FIXME: hardware has more queues */
- hw->max_altrates = 1;
+ hw->max_rates = 2;
SET_IEEE80211_DEV(hw, dev->dev);
if (is_valid_ether_addr(sprom->et1mac))