aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43/xmit.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/b43/xmit.c')
-rw-r--r--drivers/net/wireless/b43/xmit.c64
1 files changed, 51 insertions, 13 deletions
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index 2fabcf8f0474..eae9b8052658 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -46,7 +46,6 @@ static int b43_plcp_get_bitrate_idx_cck(struct b43_plcp_hdr6 *plcp)
46 case 0x6E: 46 case 0x6E:
47 return 3; 47 return 3;
48 } 48 }
49 B43_WARN_ON(1);
50 return -1; 49 return -1;
51} 50}
52 51
@@ -73,7 +72,6 @@ static u8 b43_plcp_get_bitrate_idx_ofdm(struct b43_plcp_hdr6 *plcp, bool aphy)
73 case 0xC: 72 case 0xC:
74 return base + 7; 73 return base + 7;
75 } 74 }
76 B43_WARN_ON(1);
77 return -1; 75 return -1;
78} 76}
79 77
@@ -185,7 +183,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
185 u8 *_txhdr, 183 u8 *_txhdr,
186 const unsigned char *fragment_data, 184 const unsigned char *fragment_data,
187 unsigned int fragment_len, 185 unsigned int fragment_len,
188 const struct ieee80211_tx_info *info, 186 struct ieee80211_tx_info *info,
189 u16 cookie) 187 u16 cookie)
190{ 188{
191 struct b43_txhdr *txhdr = (struct b43_txhdr *)_txhdr; 189 struct b43_txhdr *txhdr = (struct b43_txhdr *)_txhdr;
@@ -202,6 +200,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
202 u16 phy_ctl = 0; 200 u16 phy_ctl = 0;
203 u8 extra_ft = 0; 201 u8 extra_ft = 0;
204 struct ieee80211_rate *txrate; 202 struct ieee80211_rate *txrate;
203 struct ieee80211_tx_rate *rates;
205 204
206 memset(txhdr, 0, sizeof(*txhdr)); 205 memset(txhdr, 0, sizeof(*txhdr));
207 206
@@ -291,7 +290,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
291 phy_ctl |= B43_TXH_PHY_ENC_OFDM; 290 phy_ctl |= B43_TXH_PHY_ENC_OFDM;
292 else 291 else
293 phy_ctl |= B43_TXH_PHY_ENC_CCK; 292 phy_ctl |= B43_TXH_PHY_ENC_CCK;
294 if (info->flags & IEEE80211_TX_CTL_SHORT_PREAMBLE) 293 if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
295 phy_ctl |= B43_TXH_PHY_SHORTPRMBL; 294 phy_ctl |= B43_TXH_PHY_SHORTPRMBL;
296 295
297 switch (b43_ieee80211_antenna_sanitize(dev, info->antenna_sel_tx)) { 296 switch (b43_ieee80211_antenna_sanitize(dev, info->antenna_sel_tx)) {
@@ -314,6 +313,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
314 B43_WARN_ON(1); 313 B43_WARN_ON(1);
315 } 314 }
316 315
316 rates = info->control.rates;
317 /* MAC control */ 317 /* MAC control */
318 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) 318 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
319 mac_ctl |= B43_TXH_MAC_ACK; 319 mac_ctl |= B43_TXH_MAC_ACK;
@@ -324,12 +324,22 @@ int b43_generate_txhdr(struct b43_wldev *dev,
324 mac_ctl |= B43_TXH_MAC_STMSDU; 324 mac_ctl |= B43_TXH_MAC_STMSDU;
325 if (phy->type == B43_PHYTYPE_A) 325 if (phy->type == B43_PHYTYPE_A)
326 mac_ctl |= B43_TXH_MAC_5GHZ; 326 mac_ctl |= B43_TXH_MAC_5GHZ;
327 if (info->flags & IEEE80211_TX_CTL_LONG_RETRY_LIMIT) 327
328 /* Overwrite rates[0].count to make the retry calculation
329 * in the tx status easier. need the actual retry limit to
330 * detect whether the fallback rate was used.
331 */
332 if ((rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
333 (rates[0].count <= dev->wl->hw->conf.long_frame_max_tx_count)) {
334 rates[0].count = dev->wl->hw->conf.long_frame_max_tx_count;
328 mac_ctl |= B43_TXH_MAC_LONGFRAME; 335 mac_ctl |= B43_TXH_MAC_LONGFRAME;
336 } else {
337 rates[0].count = dev->wl->hw->conf.short_frame_max_tx_count;
338 }
329 339
330 /* Generate the RTS or CTS-to-self frame */ 340 /* Generate the RTS or CTS-to-self frame */
331 if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) || 341 if ((rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
332 (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) { 342 (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) {
333 unsigned int len; 343 unsigned int len;
334 struct ieee80211_hdr *hdr; 344 struct ieee80211_hdr *hdr;
335 int rts_rate, rts_rate_fb; 345 int rts_rate, rts_rate_fb;
@@ -344,7 +354,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
344 rts_rate_fb = b43_calc_fallback_rate(rts_rate); 354 rts_rate_fb = b43_calc_fallback_rate(rts_rate);
345 rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb); 355 rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb);
346 356
347 if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) { 357 if (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
348 struct ieee80211_cts *cts; 358 struct ieee80211_cts *cts;
349 359
350 if (b43_is_old_txhdr_format(dev)) { 360 if (b43_is_old_txhdr_format(dev)) {
@@ -596,6 +606,8 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
596 phytype == B43_PHYTYPE_A); 606 phytype == B43_PHYTYPE_A);
597 else 607 else
598 status.rate_idx = b43_plcp_get_bitrate_idx_cck(plcp); 608 status.rate_idx = b43_plcp_get_bitrate_idx_cck(plcp);
609 if (unlikely(status.rate_idx == -1))
610 goto drop;
599 status.antenna = !!(phystat0 & B43_RX_PHYST0_ANT); 611 status.antenna = !!(phystat0 & B43_RX_PHYST0_ANT);
600 612
601 /* 613 /*
@@ -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. */
690bool b43_fill_txstatus_report(struct ieee80211_tx_info *report, 702bool 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}