aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43
diff options
context:
space:
mode:
authorRafał Miłecki <zajec5@gmail.com>2011-02-25 06:34:11 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-02-25 15:33:39 -0500
commit3311abbbbff1719bbbc8208761e4a75f095f383c (patch)
treed399365a2c7a48d92abc3c230a732199cc810099 /drivers/net/wireless/b43
parent850bedcc10377629ea88c96c07f8e1d0a99cf4ca (diff)
b43: fill PHY ctl word1 in TX header for N-PHY
This patch fixes tramissing on OFDM rates for PHYs 1 and 2. There is still something wrong with PHYs 3+. Tests has shown decreasing of performance on CCK rates by 1-2%, we have to live with that. Additionaly this noticeably reduces amount of PHY errors. They were mostly produced by auto-switching to higher rate for better performanced, which resulted in no transmit at all and PHY errors. Signed-off-by: Rafał Miłecki <zajec5@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/b43')
-rw-r--r--drivers/net/wireless/b43/xmit.c73
-rw-r--r--drivers/net/wireless/b43/xmit.h6
2 files changed, 79 insertions, 0 deletions
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index ad605bcdd40e..e5be381c17bc 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -32,6 +32,36 @@
32#include "dma.h" 32#include "dma.h"
33#include "pio.h" 33#include "pio.h"
34 34
35static const struct b43_tx_legacy_rate_phy_ctl_entry b43_tx_legacy_rate_phy_ctl[] = {
36 { B43_CCK_RATE_1MB, 0x0, 0x0 },
37 { B43_CCK_RATE_2MB, 0x0, 0x1 },
38 { B43_CCK_RATE_5MB, 0x0, 0x2 },
39 { B43_CCK_RATE_11MB, 0x0, 0x3 },
40 { B43_OFDM_RATE_6MB, B43_TXH_PHY1_CRATE_1_2, B43_TXH_PHY1_MODUL_BPSK },
41 { B43_OFDM_RATE_9MB, B43_TXH_PHY1_CRATE_3_4, B43_TXH_PHY1_MODUL_BPSK },
42 { B43_OFDM_RATE_12MB, B43_TXH_PHY1_CRATE_1_2, B43_TXH_PHY1_MODUL_QPSK },
43 { B43_OFDM_RATE_18MB, B43_TXH_PHY1_CRATE_3_4, B43_TXH_PHY1_MODUL_QPSK },
44 { B43_OFDM_RATE_24MB, B43_TXH_PHY1_CRATE_1_2, B43_TXH_PHY1_MODUL_QAM16 },
45 { B43_OFDM_RATE_36MB, B43_TXH_PHY1_CRATE_3_4, B43_TXH_PHY1_MODUL_QAM16 },
46 { B43_OFDM_RATE_48MB, B43_TXH_PHY1_CRATE_2_3, B43_TXH_PHY1_MODUL_QAM64 },
47 { B43_OFDM_RATE_54MB, B43_TXH_PHY1_CRATE_3_4, B43_TXH_PHY1_MODUL_QAM64 },
48};
49
50static const struct b43_tx_legacy_rate_phy_ctl_entry *
51b43_tx_legacy_rate_phy_ctl_ent(u8 bitrate)
52{
53 const struct b43_tx_legacy_rate_phy_ctl_entry *e;
54 unsigned int i;
55
56 for (i = 0; i < ARRAY_SIZE(b43_tx_legacy_rate_phy_ctl); i++) {
57 e = &(b43_tx_legacy_rate_phy_ctl[i]);
58 if (e->bitrate == bitrate)
59 return e;
60 }
61
62 B43_WARN_ON(1);
63 return NULL;
64}
35 65
36/* Extract the bitrate index out of a CCK PLCP header. */ 66/* Extract the bitrate index out of a CCK PLCP header. */
37static int b43_plcp_get_bitrate_idx_cck(struct b43_plcp_hdr6 *plcp) 67static int b43_plcp_get_bitrate_idx_cck(struct b43_plcp_hdr6 *plcp)
@@ -145,6 +175,34 @@ void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp,
145 } 175 }
146} 176}
147 177
178static u16 b43_generate_tx_phy_ctl1(struct b43_wldev *dev, u8 bitrate)
179{
180 const struct b43_phy *phy = &dev->phy;
181 const struct b43_tx_legacy_rate_phy_ctl_entry *e;
182 u16 control = 0;
183 u16 bw;
184
185 if (phy->type == B43_PHYTYPE_LP)
186 bw = B43_TXH_PHY1_BW_20;
187 else /* FIXME */
188 bw = B43_TXH_PHY1_BW_20;
189
190 if (0) { /* FIXME: MIMO */
191 } else if (b43_is_cck_rate(bitrate) && phy->type != B43_PHYTYPE_LP) {
192 control = bw;
193 } else {
194 control = bw;
195 e = b43_tx_legacy_rate_phy_ctl_ent(bitrate);
196 if (e) {
197 control |= e->coding_rate;
198 control |= e->modulation;
199 }
200 control |= B43_TXH_PHY1_MODE_SISO;
201 }
202
203 return control;
204}
205
148static u8 b43_calc_fallback_rate(u8 bitrate) 206static u8 b43_calc_fallback_rate(u8 bitrate)
149{ 207{
150 switch (bitrate) { 208 switch (bitrate) {
@@ -437,6 +495,14 @@ int b43_generate_txhdr(struct b43_wldev *dev,
437 extra_ft |= B43_TXH_EFT_RTSFB_OFDM; 495 extra_ft |= B43_TXH_EFT_RTSFB_OFDM;
438 else 496 else
439 extra_ft |= B43_TXH_EFT_RTSFB_CCK; 497 extra_ft |= B43_TXH_EFT_RTSFB_CCK;
498
499 if (rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS &&
500 phy->type == B43_PHYTYPE_N) {
501 txhdr->phy_ctl1_rts = cpu_to_le16(
502 b43_generate_tx_phy_ctl1(dev, rts_rate));
503 txhdr->phy_ctl1_rts_fb = cpu_to_le16(
504 b43_generate_tx_phy_ctl1(dev, rts_rate_fb));
505 }
440 } 506 }
441 507
442 /* Magic cookie */ 508 /* Magic cookie */
@@ -445,6 +511,13 @@ int b43_generate_txhdr(struct b43_wldev *dev,
445 else 511 else
446 txhdr->new_format.cookie = cpu_to_le16(cookie); 512 txhdr->new_format.cookie = cpu_to_le16(cookie);
447 513
514 if (phy->type == B43_PHYTYPE_N) {
515 txhdr->phy_ctl1 =
516 cpu_to_le16(b43_generate_tx_phy_ctl1(dev, rate));
517 txhdr->phy_ctl1_fb =
518 cpu_to_le16(b43_generate_tx_phy_ctl1(dev, rate_fb));
519 }
520
448 /* Apply the bitfields */ 521 /* Apply the bitfields */
449 txhdr->mac_ctl = cpu_to_le32(mac_ctl); 522 txhdr->mac_ctl = cpu_to_le32(mac_ctl);
450 txhdr->phy_ctl = cpu_to_le16(phy_ctl); 523 txhdr->phy_ctl = cpu_to_le16(phy_ctl);
diff --git a/drivers/net/wireless/b43/xmit.h b/drivers/net/wireless/b43/xmit.h
index d4cf9b390af3..42debb5cd6fa 100644
--- a/drivers/net/wireless/b43/xmit.h
+++ b/drivers/net/wireless/b43/xmit.h
@@ -73,6 +73,12 @@ struct b43_txhdr {
73 } __packed; 73 } __packed;
74} __packed; 74} __packed;
75 75
76struct b43_tx_legacy_rate_phy_ctl_entry {
77 u8 bitrate;
78 u16 coding_rate;
79 u16 modulation;
80};
81
76/* MAC TX control */ 82/* MAC TX control */
77#define B43_TXH_MAC_USEFBR 0x10000000 /* Use fallback rate for this AMPDU */ 83#define B43_TXH_MAC_USEFBR 0x10000000 /* Use fallback rate for this AMPDU */
78#define B43_TXH_MAC_KEYIDX 0x0FF00000 /* Security key index */ 84#define B43_TXH_MAC_KEYIDX 0x0FF00000 /* Security key index */