aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43/xmit.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-01-24 13:38:38 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-02-29 15:19:32 -0500
commit8318d78a44d49ac1edf2bdec7299de3617c4232e (patch)
treed434634418edd7399737801615d247be06616fdd /drivers/net/wireless/b43/xmit.c
parent10b6b80145cc93887dd8aab99bfffa375e9add31 (diff)
cfg80211 API for channels/bitrates, mac80211 and driver conversion
This patch creates new cfg80211 wiphy API for channel and bitrate registration and converts mac80211 and drivers to the new API. The old mac80211 API is completely ripped out. All drivers (except ath5k) are updated to the new API, in many cases I expect that optimisations can be done. Along with the regulatory code I've also ripped out the IEEE80211_HW_DEFAULT_REG_DOMAIN_CONFIGURED flag, I believe it to be unnecessary if the hardware simply gives us whatever channels it wants to support and we then enable/disable them as required, which is pretty much required for travelling. Additionally, the patch adds proper "basic" rate handling for STA mode interface, AP mode interface will have to have new API added to allow userspace to set the basic rate set, currently it'll be empty... However, the basic rate handling will need to be moved to the BSS conf stuff. I do expect there to be bugs in this, especially wrt. transmit power handling where I'm basically clueless about how it should work. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/b43/xmit.c')
-rw-r--r--drivers/net/wireless/b43/xmit.c81
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. */
36static u8 b43_plcp_get_bitrate_cck(struct b43_plcp_hdr6 *plcp) 36static 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. */
53static u8 b43_plcp_get_bitrate_ofdm(struct b43_plcp_hdr6 *plcp) 53static 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
77u8 b43_plcp_get_ratecode_cck(const u8 bitrate) 79u8 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);