diff options
Diffstat (limited to 'drivers/net/wireless/b43/xmit.c')
-rw-r--r-- | drivers/net/wireless/b43/xmit.c | 81 |
1 files changed, 44 insertions, 37 deletions
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index 7caa26eb4105..4014b6c8272b 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c | |||
@@ -32,46 +32,48 @@ | |||
32 | #include "dma.h" | 32 | #include "dma.h" |
33 | 33 | ||
34 | 34 | ||
35 | /* Extract the bitrate out of a CCK PLCP header. */ | 35 | /* Extract the bitrate index out of a CCK PLCP header. */ |
36 | static u8 b43_plcp_get_bitrate_cck(struct b43_plcp_hdr6 *plcp) | 36 | static int b43_plcp_get_bitrate_idx_cck(struct b43_plcp_hdr6 *plcp) |
37 | { | 37 | { |
38 | switch (plcp->raw[0]) { | 38 | switch (plcp->raw[0]) { |
39 | case 0x0A: | 39 | case 0x0A: |
40 | return B43_CCK_RATE_1MB; | 40 | return 0; |
41 | case 0x14: | 41 | case 0x14: |
42 | return B43_CCK_RATE_2MB; | 42 | return 1; |
43 | case 0x37: | 43 | case 0x37: |
44 | return B43_CCK_RATE_5MB; | 44 | return 2; |
45 | case 0x6E: | 45 | case 0x6E: |
46 | return B43_CCK_RATE_11MB; | 46 | return 3; |
47 | } | 47 | } |
48 | B43_WARN_ON(1); | 48 | B43_WARN_ON(1); |
49 | return 0; | 49 | return -1; |
50 | } | 50 | } |
51 | 51 | ||
52 | /* Extract the bitrate out of an OFDM PLCP header. */ | 52 | /* Extract the bitrate index out of an OFDM PLCP header. */ |
53 | static u8 b43_plcp_get_bitrate_ofdm(struct b43_plcp_hdr6 *plcp) | 53 | static u8 b43_plcp_get_bitrate_idx_ofdm(struct b43_plcp_hdr6 *plcp, bool aphy) |
54 | { | 54 | { |
55 | int base = aphy ? 0 : 4; | ||
56 | |||
55 | switch (plcp->raw[0] & 0xF) { | 57 | switch (plcp->raw[0] & 0xF) { |
56 | case 0xB: | 58 | case 0xB: |
57 | return B43_OFDM_RATE_6MB; | 59 | return base + 0; |
58 | case 0xF: | 60 | case 0xF: |
59 | return B43_OFDM_RATE_9MB; | 61 | return base + 1; |
60 | case 0xA: | 62 | case 0xA: |
61 | return B43_OFDM_RATE_12MB; | 63 | return base + 2; |
62 | case 0xE: | 64 | case 0xE: |
63 | return B43_OFDM_RATE_18MB; | 65 | return base + 3; |
64 | case 0x9: | 66 | case 0x9: |
65 | return B43_OFDM_RATE_24MB; | 67 | return base + 4; |
66 | case 0xD: | 68 | case 0xD: |
67 | return B43_OFDM_RATE_36MB; | 69 | return base + 5; |
68 | case 0x8: | 70 | case 0x8: |
69 | return B43_OFDM_RATE_48MB; | 71 | return base + 6; |
70 | case 0xC: | 72 | case 0xC: |
71 | return B43_OFDM_RATE_54MB; | 73 | return base + 7; |
72 | } | 74 | } |
73 | B43_WARN_ON(1); | 75 | B43_WARN_ON(1); |
74 | return 0; | 76 | return -1; |
75 | } | 77 | } |
76 | 78 | ||
77 | u8 b43_plcp_get_ratecode_cck(const u8 bitrate) | 79 | u8 b43_plcp_get_ratecode_cck(const u8 bitrate) |
@@ -191,6 +193,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
191 | (const struct ieee80211_hdr *)fragment_data; | 193 | (const struct ieee80211_hdr *)fragment_data; |
192 | int use_encryption = (!(txctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)); | 194 | int use_encryption = (!(txctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)); |
193 | u16 fctl = le16_to_cpu(wlhdr->frame_control); | 195 | u16 fctl = le16_to_cpu(wlhdr->frame_control); |
196 | struct ieee80211_rate *fbrate; | ||
194 | u8 rate, rate_fb; | 197 | u8 rate, rate_fb; |
195 | int rate_ofdm, rate_fb_ofdm; | 198 | int rate_ofdm, rate_fb_ofdm; |
196 | unsigned int plcp_fragment_len; | 199 | unsigned int plcp_fragment_len; |
@@ -200,9 +203,11 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
200 | 203 | ||
201 | memset(txhdr, 0, sizeof(*txhdr)); | 204 | memset(txhdr, 0, sizeof(*txhdr)); |
202 | 205 | ||
203 | rate = txctl->tx_rate; | 206 | WARN_ON(!txctl->tx_rate); |
207 | rate = txctl->tx_rate ? txctl->tx_rate->hw_value : B43_CCK_RATE_1MB; | ||
204 | rate_ofdm = b43_is_ofdm_rate(rate); | 208 | rate_ofdm = b43_is_ofdm_rate(rate); |
205 | rate_fb = (txctl->alt_retry_rate == -1) ? rate : txctl->alt_retry_rate; | 209 | fbrate = txctl->alt_retry_rate ? : txctl->tx_rate; |
210 | rate_fb = fbrate->hw_value; | ||
206 | rate_fb_ofdm = b43_is_ofdm_rate(rate_fb); | 211 | rate_fb_ofdm = b43_is_ofdm_rate(rate_fb); |
207 | 212 | ||
208 | if (rate_ofdm) | 213 | if (rate_ofdm) |
@@ -221,11 +226,10 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
221 | * use the original dur_id field. */ | 226 | * use the original dur_id field. */ |
222 | txhdr->dur_fb = wlhdr->duration_id; | 227 | txhdr->dur_fb = wlhdr->duration_id; |
223 | } else { | 228 | } else { |
224 | int fbrate_base100kbps = B43_RATE_TO_BASE100KBPS(rate_fb); | ||
225 | txhdr->dur_fb = ieee80211_generic_frame_duration(dev->wl->hw, | 229 | txhdr->dur_fb = ieee80211_generic_frame_duration(dev->wl->hw, |
226 | txctl->vif, | 230 | txctl->vif, |
227 | fragment_len, | 231 | fragment_len, |
228 | fbrate_base100kbps); | 232 | fbrate); |
229 | } | 233 | } |
230 | 234 | ||
231 | plcp_fragment_len = fragment_len + FCS_LEN; | 235 | plcp_fragment_len = fragment_len + FCS_LEN; |
@@ -287,7 +291,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
287 | phy_ctl |= B43_TXH_PHY_ENC_OFDM; | 291 | phy_ctl |= B43_TXH_PHY_ENC_OFDM; |
288 | else | 292 | else |
289 | phy_ctl |= B43_TXH_PHY_ENC_CCK; | 293 | phy_ctl |= B43_TXH_PHY_ENC_CCK; |
290 | if (dev->short_preamble) | 294 | if (txctl->flags & IEEE80211_TXCTL_SHORT_PREAMBLE) |
291 | phy_ctl |= B43_TXH_PHY_SHORTPRMBL; | 295 | phy_ctl |= B43_TXH_PHY_SHORTPRMBL; |
292 | 296 | ||
293 | switch (b43_ieee80211_antenna_sanitize(dev, txctl->antenna_sel_tx)) { | 297 | switch (b43_ieee80211_antenna_sanitize(dev, txctl->antenna_sel_tx)) { |
@@ -332,7 +336,8 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
332 | int rts_rate_ofdm, rts_rate_fb_ofdm; | 336 | int rts_rate_ofdm, rts_rate_fb_ofdm; |
333 | struct b43_plcp_hdr6 *plcp; | 337 | struct b43_plcp_hdr6 *plcp; |
334 | 338 | ||
335 | rts_rate = txctl->rts_cts_rate; | 339 | WARN_ON(!txctl->rts_cts_rate); |
340 | rts_rate = txctl->rts_cts_rate ? txctl->rts_cts_rate->hw_value : B43_CCK_RATE_1MB; | ||
336 | rts_rate_ofdm = b43_is_ofdm_rate(rts_rate); | 341 | rts_rate_ofdm = b43_is_ofdm_rate(rts_rate); |
337 | rts_rate_fb = b43_calc_fallback_rate(rts_rate); | 342 | rts_rate_fb = b43_calc_fallback_rate(rts_rate); |
338 | rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb); | 343 | rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb); |
@@ -506,6 +511,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) | |||
506 | u16 phystat0, phystat3, chanstat, mactime; | 511 | u16 phystat0, phystat3, chanstat, mactime; |
507 | u32 macstat; | 512 | u32 macstat; |
508 | u16 chanid; | 513 | u16 chanid; |
514 | u16 phytype; | ||
509 | u8 jssi; | 515 | u8 jssi; |
510 | int padding; | 516 | int padding; |
511 | 517 | ||
@@ -518,6 +524,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) | |||
518 | macstat = le32_to_cpu(rxhdr->mac_status); | 524 | macstat = le32_to_cpu(rxhdr->mac_status); |
519 | mactime = le16_to_cpu(rxhdr->mac_time); | 525 | mactime = le16_to_cpu(rxhdr->mac_time); |
520 | chanstat = le16_to_cpu(rxhdr->channel); | 526 | chanstat = le16_to_cpu(rxhdr->channel); |
527 | phytype = chanstat & B43_RX_CHAN_PHYTYPE; | ||
521 | 528 | ||
522 | if (macstat & B43_RX_MAC_FCSERR) | 529 | if (macstat & B43_RX_MAC_FCSERR) |
523 | dev->wl->ieee_stats.dot11FCSErrorCount++; | 530 | dev->wl->ieee_stats.dot11FCSErrorCount++; |
@@ -575,9 +582,10 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) | |||
575 | /* the next line looks wrong, but is what mac80211 wants */ | 582 | /* the next line looks wrong, but is what mac80211 wants */ |
576 | status.signal = (jssi * 100) / B43_RX_MAX_SSI; | 583 | status.signal = (jssi * 100) / B43_RX_MAX_SSI; |
577 | if (phystat0 & B43_RX_PHYST0_OFDM) | 584 | if (phystat0 & B43_RX_PHYST0_OFDM) |
578 | status.rate = b43_plcp_get_bitrate_ofdm(plcp); | 585 | status.rate_idx = b43_plcp_get_bitrate_idx_ofdm(plcp, |
586 | phytype == B43_PHYTYPE_A); | ||
579 | else | 587 | else |
580 | status.rate = b43_plcp_get_bitrate_cck(plcp); | 588 | status.rate_idx = b43_plcp_get_bitrate_idx_cck(plcp); |
581 | status.antenna = !!(phystat0 & B43_RX_PHYST0_ANT); | 589 | status.antenna = !!(phystat0 & B43_RX_PHYST0_ANT); |
582 | 590 | ||
583 | /* | 591 | /* |
@@ -601,29 +609,28 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) | |||
601 | chanid = (chanstat & B43_RX_CHAN_ID) >> B43_RX_CHAN_ID_SHIFT; | 609 | chanid = (chanstat & B43_RX_CHAN_ID) >> B43_RX_CHAN_ID_SHIFT; |
602 | switch (chanstat & B43_RX_CHAN_PHYTYPE) { | 610 | switch (chanstat & B43_RX_CHAN_PHYTYPE) { |
603 | case B43_PHYTYPE_A: | 611 | case B43_PHYTYPE_A: |
604 | status.phymode = MODE_IEEE80211A; | 612 | status.band = IEEE80211_BAND_5GHZ; |
605 | B43_WARN_ON(1); | 613 | B43_WARN_ON(1); |
606 | /* FIXME: We don't really know which value the "chanid" contains. | 614 | /* FIXME: We don't really know which value the "chanid" contains. |
607 | * So the following assignment might be wrong. */ | 615 | * So the following assignment might be wrong. */ |
608 | status.channel = chanid; | 616 | status.freq = b43_channel_to_freq_5ghz(chanid); |
609 | status.freq = b43_channel_to_freq_5ghz(status.channel); | ||
610 | break; | 617 | break; |
611 | case B43_PHYTYPE_G: | 618 | case B43_PHYTYPE_G: |
612 | status.phymode = MODE_IEEE80211G; | 619 | status.band = IEEE80211_BAND_2GHZ; |
613 | /* chanid is the radio channel cookie value as used | 620 | /* chanid is the radio channel cookie value as used |
614 | * to tune the radio. */ | 621 | * to tune the radio. */ |
615 | status.freq = chanid + 2400; | 622 | status.freq = chanid + 2400; |
616 | status.channel = b43_freq_to_channel_2ghz(status.freq); | ||
617 | break; | 623 | break; |
618 | case B43_PHYTYPE_N: | 624 | case B43_PHYTYPE_N: |
619 | status.phymode = 0xDEAD /*FIXME MODE_IEEE80211N*/; | ||
620 | /* chanid is the SHM channel cookie. Which is the plain | 625 | /* chanid is the SHM channel cookie. Which is the plain |
621 | * channel number in b43. */ | 626 | * channel number in b43. */ |
622 | status.channel = chanid; | 627 | if (chanstat & B43_RX_CHAN_5GHZ) { |
623 | if (chanstat & B43_RX_CHAN_5GHZ) | 628 | status.band = IEEE80211_BAND_5GHZ; |
624 | status.freq = b43_freq_to_channel_5ghz(status.freq); | 629 | status.freq = b43_freq_to_channel_5ghz(chanid); |
625 | else | 630 | } else { |
626 | status.freq = b43_freq_to_channel_2ghz(status.freq); | 631 | status.band = IEEE80211_BAND_2GHZ; |
632 | status.freq = b43_freq_to_channel_2ghz(chanid); | ||
633 | } | ||
627 | break; | 634 | break; |
628 | default: | 635 | default: |
629 | B43_WARN_ON(1); | 636 | B43_WARN_ON(1); |