1 backport b43 patches from wireless testing
3 This brings b43 up to wireless-testing/master master-2014-07-29-1
5 --- a/drivers/net/wireless/b43/main.c
6 +++ b/drivers/net/wireless/b43/main.c
7 @@ -122,7 +122,11 @@ static const struct bcma_device_id b43_b
8 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x11, BCMA_ANY_CLASS),
9 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x17, BCMA_ANY_CLASS),
10 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x18, BCMA_ANY_CLASS),
11 + BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1C, BCMA_ANY_CLASS),
12 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1D, BCMA_ANY_CLASS),
13 + BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1E, BCMA_ANY_CLASS),
14 + BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x28, BCMA_ANY_CLASS),
15 + BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x2A, BCMA_ANY_CLASS),
18 MODULE_DEVICE_TABLE(bcma, b43_bcma_tbl);
19 @@ -206,6 +210,9 @@ static struct ieee80211_channel b43_2ghz
24 +/* No support for the last 3 channels (12, 13, 14) */
25 +#define b43_2ghz_chantable_limited_size 11
28 #define CHAN4G(_channel, _flags) { \
29 @@ -283,6 +290,14 @@ static struct ieee80211_channel b43_5ghz
33 +static struct ieee80211_channel b43_5ghz_nphy_chantable_limited[] = {
34 + CHAN5G(36, 0), CHAN5G(40, 0),
35 + CHAN5G(44, 0), CHAN5G(48, 0),
36 + CHAN5G(149, 0), CHAN5G(153, 0),
37 + CHAN5G(157, 0), CHAN5G(161, 0),
41 static struct ieee80211_channel b43_5ghz_aphy_chantable[] = {
42 CHAN5G(34, 0), CHAN5G(36, 0),
43 CHAN5G(38, 0), CHAN5G(40, 0),
44 @@ -315,6 +330,14 @@ static struct ieee80211_supported_band b
45 .n_bitrates = b43_a_ratetable_size,
48 +static struct ieee80211_supported_band b43_band_5GHz_nphy_limited = {
49 + .band = IEEE80211_BAND_5GHZ,
50 + .channels = b43_5ghz_nphy_chantable_limited,
51 + .n_channels = ARRAY_SIZE(b43_5ghz_nphy_chantable_limited),
52 + .bitrates = b43_a_ratetable,
53 + .n_bitrates = b43_a_ratetable_size,
56 static struct ieee80211_supported_band b43_band_5GHz_aphy = {
57 .band = IEEE80211_BAND_5GHZ,
58 .channels = b43_5ghz_aphy_chantable,
59 @@ -331,6 +354,14 @@ static struct ieee80211_supported_band b
60 .n_bitrates = b43_g_ratetable_size,
63 +static struct ieee80211_supported_band b43_band_2ghz_limited = {
64 + .band = IEEE80211_BAND_2GHZ,
65 + .channels = b43_2ghz_chantable,
66 + .n_channels = b43_2ghz_chantable_limited_size,
67 + .bitrates = b43_g_ratetable,
68 + .n_bitrates = b43_g_ratetable_size,
71 static void b43_wireless_core_exit(struct b43_wldev *dev);
72 static int b43_wireless_core_init(struct b43_wldev *dev);
73 static struct b43_wldev * b43_wireless_core_stop(struct b43_wldev *dev);
74 @@ -2201,52 +2232,82 @@ err_format:
78 +/* http://bcm-v4.sipsolutions.net/802.11/Init/Firmware */
79 static int b43_try_request_fw(struct b43_request_fw_context *ctx)
81 struct b43_wldev *dev = ctx->dev;
82 struct b43_firmware *fw = &ctx->dev->fw;
83 + struct b43_phy *phy = &dev->phy;
84 const u8 rev = ctx->dev->dev->core_rev;
89 - /* Files for HT and LCN were found by trying one by one */
92 - if ((rev >= 5) && (rev <= 10)) {
93 - filename = "ucode5";
94 - } else if ((rev >= 11) && (rev <= 12)) {
95 - filename = "ucode11";
96 - } else if (rev == 13) {
97 - filename = "ucode13";
98 - } else if (rev == 14) {
99 - filename = "ucode14";
100 - } else if (rev == 15) {
104 + if (phy->type == B43_PHYTYPE_AC)
105 + filename = "ucode42";
108 + if (phy->type == B43_PHYTYPE_AC)
109 + filename = "ucode40";
112 + if (phy->type == B43_PHYTYPE_LCN40)
113 + filename = "ucode33_lcn40";
116 + if (phy->type == B43_PHYTYPE_N)
117 + filename = "ucode30_mimo";
120 + if (phy->type == B43_PHYTYPE_HT)
121 + filename = "ucode29_mimo";
124 + if (phy->type == B43_PHYTYPE_HT)
125 + filename = "ucode26_mimo";
129 + if (phy->type == B43_PHYTYPE_N)
130 + filename = "ucode25_mimo";
131 + else if (phy->type == B43_PHYTYPE_LCN)
132 + filename = "ucode25_lcn";
135 + if (phy->type == B43_PHYTYPE_LCN)
136 + filename = "ucode24_lcn";
139 + if (phy->type == B43_PHYTYPE_N)
140 + filename = "ucode16_mimo";
143 + if (phy->type == B43_PHYTYPE_N)
144 + filename = "ucode16_mimo";
145 + else if (phy->type == B43_PHYTYPE_LP)
146 + filename = "ucode16_lp";
149 filename = "ucode15";
151 - switch (dev->phy.type) {
152 - case B43_PHYTYPE_N:
154 - filename = "ucode16_mimo";
158 - case B43_PHYTYPE_HT:
160 - filename = "ucode29_mimo";
164 - case B43_PHYTYPE_LCN:
166 - filename = "ucode24_mimo";
175 + filename = "ucode14";
178 + filename = "ucode13";
181 + filename = "ucode11";
184 + filename = "ucode5";
189 err = b43_do_request_fw(ctx, filename, &fw->ucode, true);
192 @@ -2268,117 +2329,121 @@ static int b43_try_request_fw(struct b43
197 switch (dev->phy.type) {
198 - case B43_PHYTYPE_A:
199 - if ((rev >= 5) && (rev <= 10)) {
200 - tmshigh = ssb_read32(dev->dev->sdev, SSB_TMSHIGH);
201 - if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY)
202 - filename = "a0g1initvals5";
204 - filename = "a0g0initvals5";
206 - goto err_no_initvals;
209 - if ((rev >= 5) && (rev <= 10))
210 - filename = "b0g0initvals5";
211 - else if (rev >= 13)
213 filename = "b0g0initvals13";
215 - goto err_no_initvals;
216 + else if (rev >= 5 && rev <= 10)
217 + filename = "b0g0initvals5";
222 + filename = "n16initvals30";
223 + else if (rev == 28 || rev == 25)
224 + filename = "n0initvals25";
225 + else if (rev == 24)
226 + filename = "n0initvals24";
227 + else if (rev == 23)
228 + filename = "n0initvals16"; /* What about n0initvals22? */
229 + else if (rev >= 16 && rev <= 18)
230 filename = "n0initvals16";
231 - else if ((rev >= 11) && (rev <= 12))
232 + else if (rev >= 11 && rev <= 12)
233 filename = "n0initvals11";
235 - goto err_no_initvals;
239 - filename = "lp0initvals13";
240 + if (rev >= 16 && rev <= 18)
241 + filename = "lp0initvals16";
242 + else if (rev == 15)
243 + filename = "lp0initvals15";
245 filename = "lp0initvals14";
246 - else if (rev >= 15)
247 - filename = "lp0initvals15";
249 - goto err_no_initvals;
250 + else if (rev == 13)
251 + filename = "lp0initvals13";
255 filename = "ht0initvals29";
257 - goto err_no_initvals;
258 + else if (rev == 26)
259 + filename = "ht0initvals26";
261 case B43_PHYTYPE_LCN:
263 filename = "lcn0initvals24";
265 - goto err_no_initvals;
268 - goto err_no_initvals;
269 + case B43_PHYTYPE_LCN40:
271 + filename = "lcn400initvals33";
273 + case B43_PHYTYPE_AC:
275 + filename = "ac1initvals42";
276 + else if (rev == 40)
277 + filename = "ac0initvals40";
281 + goto err_no_initvals;
282 err = b43_do_request_fw(ctx, filename, &fw->initvals, false);
286 /* Get bandswitch initvals */
288 switch (dev->phy.type) {
289 - case B43_PHYTYPE_A:
290 - if ((rev >= 5) && (rev <= 10)) {
291 - tmshigh = ssb_read32(dev->dev->sdev, SSB_TMSHIGH);
292 - if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY)
293 - filename = "a0g1bsinitvals5";
295 - filename = "a0g0bsinitvals5";
296 - } else if (rev >= 11)
299 - goto err_no_initvals;
302 - if ((rev >= 5) && (rev <= 10))
304 + filename = "b0g0bsinitvals13";
305 + else if (rev >= 5 && rev <= 10)
306 filename = "b0g0bsinitvals5";
307 - else if (rev >= 11)
310 - goto err_no_initvals;
315 + filename = "n16bsinitvals30";
316 + else if (rev == 28 || rev == 25)
317 + filename = "n0bsinitvals25";
318 + else if (rev == 24)
319 + filename = "n0bsinitvals24";
320 + else if (rev == 23)
321 + filename = "n0bsinitvals16"; /* What about n0bsinitvals22? */
322 + else if (rev >= 16 && rev <= 18)
323 filename = "n0bsinitvals16";
324 - else if ((rev >= 11) && (rev <= 12))
325 + else if (rev >= 11 && rev <= 12)
326 filename = "n0bsinitvals11";
328 - goto err_no_initvals;
332 - filename = "lp0bsinitvals13";
333 + if (rev >= 16 && rev <= 18)
334 + filename = "lp0bsinitvals16";
335 + else if (rev == 15)
336 + filename = "lp0bsinitvals15";
338 filename = "lp0bsinitvals14";
339 - else if (rev >= 15)
340 - filename = "lp0bsinitvals15";
342 - goto err_no_initvals;
343 + else if (rev == 13)
344 + filename = "lp0bsinitvals13";
348 filename = "ht0bsinitvals29";
350 - goto err_no_initvals;
351 + else if (rev == 26)
352 + filename = "ht0bsinitvals26";
354 case B43_PHYTYPE_LCN:
356 filename = "lcn0bsinitvals24";
358 - goto err_no_initvals;
361 - goto err_no_initvals;
362 + case B43_PHYTYPE_LCN40:
364 + filename = "lcn400bsinitvals33";
366 + case B43_PHYTYPE_AC:
368 + filename = "ac1bsinitvals42";
369 + else if (rev == 40)
370 + filename = "ac0bsinitvals40";
374 + goto err_no_initvals;
375 err = b43_do_request_fw(ctx, filename, &fw->initvals_band, false);
378 @@ -2915,6 +2980,46 @@ void b43_mac_phy_clock_set(struct b43_wl
382 +/* brcms_b_switch_macfreq */
383 +void b43_mac_switch_freq(struct b43_wldev *dev, u8 spurmode)
385 + u16 chip_id = dev->dev->chip_id;
387 + if (chip_id == BCMA_CHIP_ID_BCM43131 ||
388 + chip_id == BCMA_CHIP_ID_BCM43217 ||
389 + chip_id == BCMA_CHIP_ID_BCM43222 ||
390 + chip_id == BCMA_CHIP_ID_BCM43224 ||
391 + chip_id == BCMA_CHIP_ID_BCM43225 ||
392 + chip_id == BCMA_CHIP_ID_BCM43227 ||
393 + chip_id == BCMA_CHIP_ID_BCM43228) {
394 + switch (spurmode) {
395 + case 2: /* 126 Mhz */
396 + b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x2082);
397 + b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
399 + case 1: /* 123 Mhz */
400 + b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x5341);
401 + b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
403 + default: /* 120 Mhz */
404 + b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x8889);
405 + b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
408 + } else if (dev->phy.type == B43_PHYTYPE_LCN) {
409 + switch (spurmode) {
410 + case 1: /* 82 Mhz */
411 + b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x7CE0);
412 + b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0xC);
414 + default: /* 80 Mhz */
415 + b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0xCCCD);
416 + b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0xC);
422 static void b43_adjust_opmode(struct b43_wldev *dev)
424 struct b43_wl *wl = dev->wl;
425 @@ -3742,7 +3847,9 @@ static int b43_switch_band(struct b43_wl
426 b43dbg(dev->wl, "Switching to %s GHz band\n",
427 band_to_string(chan->band));
429 - b43_software_rfkill(dev, true);
430 + /* Some new devices don't need disabling radio for band switching */
431 + if (!(phy->type == B43_PHYTYPE_N && phy->rev >= 3))
432 + b43_software_rfkill(dev, true);
435 b43_phy_put_into_reset(dev);
436 @@ -3796,38 +3903,29 @@ static void b43_set_retry_limits(struct
437 static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
439 struct b43_wl *wl = hw_to_b43_wl(hw);
440 - struct b43_wldev *dev;
441 - struct b43_phy *phy;
442 + struct b43_wldev *dev = wl->current_dev;
443 + struct b43_phy *phy = &dev->phy;
444 struct ieee80211_conf *conf = &hw->conf;
447 - bool reload_bss = false;
449 mutex_lock(&wl->mutex);
451 - dev = wl->current_dev;
453 b43_mac_suspend(dev);
455 - /* Switch the band (if necessary). This might change the active core. */
456 - err = b43_switch_band(dev, conf->chandef.chan);
458 - goto out_unlock_mutex;
459 + if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
460 + phy->chandef = &conf->chandef;
461 + phy->channel = conf->chandef.chan->hw_value;
463 - /* Need to reload all settings if the core changed */
464 - if (dev != wl->current_dev) {
465 - dev = wl->current_dev;
469 + /* Switch the band (if necessary). */
470 + err = b43_switch_band(dev, conf->chandef.chan);
472 + goto out_mac_enable;
476 - if (conf_is_ht(conf))
478 - (conf_is_ht40_minus(conf) || conf_is_ht40_plus(conf));
480 - phy->is_40mhz = false;
481 + /* Switch to the requested channel.
482 + * The firmware takes care of races with the TX handler.
484 + b43_switch_channel(dev, phy->channel);
487 if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
488 b43_set_retry_limits(dev, conf->short_frame_max_tx_count,
489 @@ -3836,11 +3934,6 @@ static int b43_op_config(struct ieee8021
493 - /* Switch to the requested channel.
494 - * The firmware takes care of races with the TX handler. */
495 - if (conf->chandef.chan->hw_value != phy->channel)
496 - b43_switch_channel(dev, conf->chandef.chan->hw_value);
498 dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_MONITOR);
500 /* Adjust the desired TX power level. */
501 @@ -3876,12 +3969,8 @@ static int b43_op_config(struct ieee8021
506 mutex_unlock(&wl->mutex);
508 - if (wl->vif && reload_bss)
509 - b43_op_bss_info_changed(hw, wl->vif, &wl->vif->bss_conf, ~0);
514 @@ -4307,13 +4396,15 @@ static char *b43_phy_name(struct b43_wld
515 static int b43_phy_versioning(struct b43_wldev *dev)
517 struct b43_phy *phy = &dev->phy;
518 + const u8 core_rev = dev->dev->core_rev;
530 /* Get PHY versioning */
531 @@ -4321,23 +4412,23 @@ static int b43_phy_versioning(struct b43
532 analog_type = (tmp & B43_PHYVER_ANALOG) >> B43_PHYVER_ANALOG_SHIFT;
533 phy_type = (tmp & B43_PHYVER_TYPE) >> B43_PHYVER_TYPE_SHIFT;
534 phy_rev = (tmp & B43_PHYVER_VERSION);
536 + /* LCNXN is continuation of N which run out of revisions */
537 + if (phy_type == B43_PHYTYPE_LCNXN) {
538 + phy_type = B43_PHYTYPE_N;
543 - case B43_PHYTYPE_A:
547 - case B43_PHYTYPE_B:
548 - if (phy_rev != 2 && phy_rev != 4 && phy_rev != 6
552 +#ifdef CPTCFG_B43_PHY_G
558 #ifdef CPTCFG_B43_PHY_N
565 @@ -4372,7 +4463,17 @@ static int b43_phy_versioning(struct b43
566 analog_type, phy_type, b43_phy_name(dev, phy_type), phy_rev);
568 /* Get RADIO versioning */
569 - if (dev->dev->core_rev >= 24) {
570 + if (core_rev == 40 || core_rev == 42) {
571 + radio_manuf = 0x17F;
573 + b43_write16(dev, B43_MMIO_RADIO24_CONTROL, 0);
574 + radio_rev = b43_read16(dev, B43_MMIO_RADIO24_DATA);
576 + b43_write16(dev, B43_MMIO_RADIO24_CONTROL, 1);
577 + radio_id = b43_read16(dev, B43_MMIO_RADIO24_DATA);
579 + radio_ver = 0; /* Is there version somewhere? */
580 + } else if (core_rev >= 24) {
583 for (tmp = 0; tmp < 3; tmp++) {
584 @@ -4380,12 +4481,10 @@ static int b43_phy_versioning(struct b43
585 radio24[tmp] = b43_read16(dev, B43_MMIO_RADIO24_DATA);
588 - /* Broadcom uses "id" for our "ver" and has separated "ver" */
589 - /* radio_ver = (radio24[0] & 0xF0) >> 4; */
592 - radio_ver = (radio24[2] << 8) | radio24[1];
593 + radio_id = (radio24[2] << 8) | radio24[1];
594 radio_rev = (radio24[0] & 0xF);
595 + radio_ver = (radio24[0] & 0xF0) >> 4;
597 if (dev->dev->chip_id == 0x4317) {
598 if (dev->dev->chip_rev == 0)
599 @@ -4404,15 +4503,16 @@ static int b43_phy_versioning(struct b43
602 radio_manuf = (tmp & 0x00000FFF);
603 - radio_ver = (tmp & 0x0FFFF000) >> 12;
604 + radio_id = (tmp & 0x0FFFF000) >> 12;
605 radio_rev = (tmp & 0xF0000000) >> 28;
606 + radio_ver = 0; /* Probably not available on old hw */
609 if (radio_manuf != 0x17F /* Broadcom */)
613 - if (radio_ver != 0x2060)
614 + if (radio_id != 0x2060)
618 @@ -4420,43 +4520,49 @@ static int b43_phy_versioning(struct b43
622 - if ((radio_ver & 0xFFF0) != 0x2050)
623 + if ((radio_id & 0xFFF0) != 0x2050)
627 - if (radio_ver != 0x2050)
628 + if (radio_id != 0x2050)
632 - if (radio_ver != 0x2055 && radio_ver != 0x2056)
633 + if (radio_id != 0x2055 && radio_id != 0x2056 &&
634 + radio_id != 0x2057)
636 + if (radio_id == 0x2057 &&
637 + !(radio_rev == 9 || radio_rev == 14))
641 - if (radio_ver != 0x2062 && radio_ver != 0x2063)
642 + if (radio_id != 0x2062 && radio_id != 0x2063)
646 - if (radio_ver != 0x2059)
647 + if (radio_id != 0x2059)
650 case B43_PHYTYPE_LCN:
651 - if (radio_ver != 0x2064)
652 + if (radio_id != 0x2064)
659 - b43err(dev->wl, "FOUND UNSUPPORTED RADIO "
660 - "(Manuf 0x%X, Version 0x%X, Revision %u)\n",
661 - radio_manuf, radio_ver, radio_rev);
663 + "FOUND UNSUPPORTED RADIO (Manuf 0x%X, ID 0x%X, Revision %u, Version %u)\n",
664 + radio_manuf, radio_id, radio_rev, radio_ver);
667 - b43dbg(dev->wl, "Found Radio: Manuf 0x%X, Version 0x%X, Revision %u\n",
668 - radio_manuf, radio_ver, radio_rev);
670 + "Found Radio: Manuf 0x%X, ID 0x%X, Revision %u, Version %u\n",
671 + radio_manuf, radio_id, radio_rev, radio_ver);
673 + /* FIXME: b43 treats "id" as "ver" and ignores the real "ver" */
674 phy->radio_manuf = radio_manuf;
675 - phy->radio_ver = radio_ver;
676 + phy->radio_ver = radio_id;
677 phy->radio_rev = radio_rev;
679 phy->analog = analog_type;
680 @@ -5064,12 +5170,24 @@ static int b43_setup_bands(struct b43_wl
681 bool have_2ghz_phy, bool have_5ghz_phy)
683 struct ieee80211_hw *hw = dev->wl->hw;
684 + struct b43_phy *phy = &dev->phy;
688 + /* We don't support all 2 GHz channels on some devices */
689 + limited_2g = phy->radio_ver == 0x2057 &&
690 + (phy->radio_rev == 9 || phy->radio_rev == 14);
691 + limited_5g = phy->radio_ver == 0x2057 &&
692 + phy->radio_rev == 9;
695 - hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &b43_band_2GHz;
696 + hw->wiphy->bands[IEEE80211_BAND_2GHZ] = limited_2g ?
697 + &b43_band_2ghz_limited : &b43_band_2GHz;
698 if (dev->phy.type == B43_PHYTYPE_N) {
700 - hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &b43_band_5GHz_nphy;
701 + hw->wiphy->bands[IEEE80211_BAND_5GHZ] = limited_5g ?
702 + &b43_band_5GHz_nphy_limited :
703 + &b43_band_5GHz_nphy;
706 hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &b43_band_5GHz_aphy;
707 @@ -5164,6 +5282,7 @@ static void b43_supported_bands(struct b
708 static int b43_wireless_core_attach(struct b43_wldev *dev)
710 struct b43_wl *wl = dev->wl;
711 + struct b43_phy *phy = &dev->phy;
714 bool have_2ghz_phy = false, have_5ghz_phy = false;
715 @@ -5181,6 +5300,8 @@ static int b43_wireless_core_attach(stru
719 + phy->do_full_init = true;
721 /* Try to guess supported bands for the first init needs */
722 switch (dev->dev->bus_type) {
723 #ifdef CPTCFG_B43_BCMA
724 @@ -5214,14 +5335,15 @@ static int b43_wireless_core_attach(stru
725 b43_supported_bands(dev, &have_2ghz_phy, &have_5ghz_phy);
727 /* We don't support 5 GHz on some PHYs yet */
728 - switch (dev->phy.type) {
729 - case B43_PHYTYPE_A:
730 - case B43_PHYTYPE_G:
731 - case B43_PHYTYPE_N:
732 - case B43_PHYTYPE_LP:
733 - case B43_PHYTYPE_HT:
734 - b43warn(wl, "5 GHz band is unsupported on this PHY\n");
735 - have_5ghz_phy = false;
736 + if (have_5ghz_phy) {
737 + switch (dev->phy.type) {
738 + case B43_PHYTYPE_A:
739 + case B43_PHYTYPE_G:
740 + case B43_PHYTYPE_LP:
741 + case B43_PHYTYPE_HT:
742 + b43warn(wl, "5 GHz band is unsupported on this PHY\n");
743 + have_5ghz_phy = false;
747 if (!have_2ghz_phy && !have_5ghz_phy) {
748 --- a/drivers/net/wireless/b43/main.h
749 +++ b/drivers/net/wireless/b43/main.h
750 @@ -99,6 +99,7 @@ void b43_power_saving_ctl_bits(struct b4
751 void b43_mac_suspend(struct b43_wldev *dev);
752 void b43_mac_enable(struct b43_wldev *dev);
753 void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on);
754 +void b43_mac_switch_freq(struct b43_wldev *dev, u8 spurmode);
757 struct b43_request_fw_context;
758 --- a/drivers/net/wireless/b43/phy_common.c
759 +++ b/drivers/net/wireless/b43/phy_common.c
760 @@ -45,11 +45,10 @@ int b43_phy_allocate(struct b43_wldev *d
764 - case B43_PHYTYPE_A:
765 - phy->ops = &b43_phyops_a;
768 +#ifdef CPTCFG_B43_PHY_G
769 phy->ops = &b43_phyops_g;
773 #ifdef CPTCFG_B43_PHY_N
774 @@ -94,18 +93,25 @@ int b43_phy_init(struct b43_wldev *dev)
775 const struct b43_phy_operations *ops = phy->ops;
778 - phy->channel = ops->get_default_chan(dev);
779 + /* During PHY init we need to use some channel. On the first init this
780 + * function is called *before* b43_op_config, so our pointer is NULL.
782 + if (!phy->chandef) {
783 + phy->chandef = &dev->wl->hw->conf.chandef;
784 + phy->channel = phy->chandef->chan->hw_value;
787 phy->ops->switch_analog(dev, true);
788 b43_software_rfkill(dev, false);
790 err = ops->init(dev);
792 b43err(dev->wl, "PHY init failed\n");
795 - /* Make sure to switch hardware and firmware (SHM) to
796 - * the default channel. */
797 - err = b43_switch_channel(dev, ops->get_default_chan(dev));
798 + phy->do_full_init = false;
800 + err = b43_switch_channel(dev, phy->channel);
802 b43err(dev->wl, "PHY init: Channel switch to default failed\n");
804 @@ -114,6 +120,7 @@ int b43_phy_init(struct b43_wldev *dev)
808 + phy->do_full_init = true;
812 @@ -127,6 +134,7 @@ void b43_phy_exit(struct b43_wldev *dev)
813 const struct b43_phy_operations *ops = dev->phy.ops;
815 b43_software_rfkill(dev, true);
816 + dev->phy.do_full_init = true;
820 @@ -403,9 +411,6 @@ int b43_switch_channel(struct b43_wldev
821 u16 channelcookie, savedcookie;
824 - if (new_channel == B43_DEFAULT_CHANNEL)
825 - new_channel = phy->ops->get_default_chan(dev);
827 /* First we set the channel radio code to prevent the
828 * firmware from sending ghost packets.
830 @@ -423,7 +428,6 @@ int b43_switch_channel(struct b43_wldev
832 goto err_restore_cookie;
834 - dev->phy.channel = new_channel;
835 /* Wait for the radio to tune to the channel and stabilize. */
838 @@ -542,10 +546,9 @@ void b43_phyop_switch_analog_generic(str
842 -bool b43_channel_type_is_40mhz(enum nl80211_channel_type channel_type)
843 +bool b43_is_40mhz(struct b43_wldev *dev)
845 - return (channel_type == NL80211_CHAN_HT40MINUS ||
846 - channel_type == NL80211_CHAN_HT40PLUS);
847 + return dev->phy.chandef->width == NL80211_CHAN_WIDTH_40;
850 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/BmacPhyClkFgc */
851 --- a/drivers/net/wireless/b43/phy_common.h
852 +++ b/drivers/net/wireless/b43/phy_common.h
853 @@ -228,12 +228,12 @@ struct b43_phy {
860 /* Is GMODE (2 GHz mode) bit enabled? */
863 + /* After power reset full init has to be performed */
869 @@ -264,9 +264,8 @@ struct b43_phy {
870 unsigned long next_txpwr_check_time;
872 /* Current channel */
873 + struct cfg80211_chan_def *chandef;
874 unsigned int channel;
876 - enum nl80211_channel_type channel_type;
878 /* PHY TX errors counter. */
880 @@ -397,10 +396,6 @@ void b43_phy_take_out_of_reset(struct b4
881 * b43_switch_channel - Switch to another channel
883 int b43_switch_channel(struct b43_wldev *dev, unsigned int new_channel);
885 - * B43_DEFAULT_CHANNEL - Switch to the default channel.
887 -#define B43_DEFAULT_CHANNEL UINT_MAX
890 * b43_software_rfkill - Turn the radio ON or OFF in software.
891 @@ -451,7 +446,7 @@ int b43_phy_shm_tssi_read(struct b43_wld
893 void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on);
895 -bool b43_channel_type_is_40mhz(enum nl80211_channel_type channel_type);
896 +bool b43_is_40mhz(struct b43_wldev *dev);
898 void b43_phy_force_clock(struct b43_wldev *dev, bool force);
900 --- a/drivers/net/wireless/b43/phy_lcn.c
901 +++ b/drivers/net/wireless/b43/phy_lcn.c
902 @@ -54,39 +54,6 @@ enum lcn_sense_type {
906 -/* In theory it's PHY common function, move if needed */
907 -/* brcms_b_switch_macfreq */
908 -static void b43_phy_switch_macfreq(struct b43_wldev *dev, u8 spurmode)
910 - if (dev->dev->chip_id == 43224 || dev->dev->chip_id == 43225) {
911 - switch (spurmode) {
912 - case 2: /* 126 Mhz */
913 - b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x2082);
914 - b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
916 - case 1: /* 123 Mhz */
917 - b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x5341);
918 - b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
920 - default: /* 120 Mhz */
921 - b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x8889);
922 - b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
925 - } else if (dev->phy.type == B43_PHYTYPE_LCN) {
926 - switch (spurmode) {
927 - case 1: /* 82 Mhz */
928 - b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x7CE0);
929 - b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0xC);
931 - default: /* 80 Mhz */
932 - b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0xCCCD);
933 - b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0xC);
939 /**************************************************
941 **************************************************/
942 @@ -609,7 +576,7 @@ static void b43_phy_lcn_txrx_spur_avoida
943 b43_phy_write(dev, 0x93b, ((0 << 13) + 23));
944 b43_phy_write(dev, 0x93c, ((0 << 13) + 1989));
946 - b43_phy_switch_macfreq(dev, enable);
947 + b43_mac_switch_freq(dev, enable);
950 /**************************************************
951 --- a/drivers/net/wireless/b43/phy_n.c
952 +++ b/drivers/net/wireless/b43/phy_n.c
956 struct nphy_txgains {
961 @@ -43,6 +44,7 @@ struct nphy_txgains {
964 struct nphy_iqcal_params {
969 @@ -69,6 +71,14 @@ enum b43_nphy_rf_sequence {
970 B43_RFSEQ_UPDATE_GAINU,
973 +enum n_rf_ctl_over_cmd {
974 + N_RF_CTL_OVER_CMD_RXRF_PU = 0,
975 + N_RF_CTL_OVER_CMD_RX_PU = 1,
976 + N_RF_CTL_OVER_CMD_TX_PU = 2,
977 + N_RF_CTL_OVER_CMD_RX_GAIN = 3,
978 + N_RF_CTL_OVER_CMD_TX_GAIN = 4,
981 enum n_intc_override {
982 N_INTC_OVERRIDE_OFF = 0,
983 N_INTC_OVERRIDE_TRSW = 1,
984 @@ -140,11 +150,19 @@ ok:
985 b43_phy_write(dev, B43_NPHY_RFSEQMODE, seq_mode);
988 +static void b43_nphy_rf_ctl_override_rev19(struct b43_wldev *dev, u16 field,
989 + u16 value, u8 core, bool off,
995 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverrideRev7 */
996 static void b43_nphy_rf_ctl_override_rev7(struct b43_wldev *dev, u16 field,
997 u16 value, u8 core, bool off,
1000 + struct b43_phy *phy = &dev->phy;
1001 const struct nphy_rf_control_override_rev7 *e;
1002 u16 en_addrs[3][2] = {
1003 { 0x0E7, 0x0EC }, { 0x342, 0x343 }, { 0x346, 0x347 }
1004 @@ -154,6 +172,11 @@ static void b43_nphy_rf_ctl_override_rev
1008 + if (phy->rev >= 19 || phy->rev < 3) {
1013 /* Remember: we can get NULL! */
1014 e = b43_nphy_get_rf_ctl_over_rev7(dev, field, override);
1016 @@ -181,6 +204,50 @@ static void b43_nphy_rf_ctl_override_rev
1020 +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverideOneToMany */
1021 +static void b43_nphy_rf_ctl_override_one_to_many(struct b43_wldev *dev,
1022 + enum n_rf_ctl_over_cmd cmd,
1023 + u16 value, u8 core, bool off)
1025 + struct b43_phy *phy = &dev->phy;
1028 + B43_WARN_ON(phy->rev < 7);
1031 + case N_RF_CTL_OVER_CMD_RXRF_PU:
1032 + b43_nphy_rf_ctl_override_rev7(dev, 0x20, value, core, off, 1);
1033 + b43_nphy_rf_ctl_override_rev7(dev, 0x10, value, core, off, 1);
1034 + b43_nphy_rf_ctl_override_rev7(dev, 0x08, value, core, off, 1);
1036 + case N_RF_CTL_OVER_CMD_RX_PU:
1037 + b43_nphy_rf_ctl_override_rev7(dev, 0x4, value, core, off, 1);
1038 + b43_nphy_rf_ctl_override_rev7(dev, 0x2, value, core, off, 1);
1039 + b43_nphy_rf_ctl_override_rev7(dev, 0x1, value, core, off, 1);
1040 + b43_nphy_rf_ctl_override_rev7(dev, 0x2, value, core, off, 2);
1041 + b43_nphy_rf_ctl_override_rev7(dev, 0x0800, 0, core, off, 1);
1043 + case N_RF_CTL_OVER_CMD_TX_PU:
1044 + b43_nphy_rf_ctl_override_rev7(dev, 0x4, value, core, off, 0);
1045 + b43_nphy_rf_ctl_override_rev7(dev, 0x2, value, core, off, 1);
1046 + b43_nphy_rf_ctl_override_rev7(dev, 0x1, value, core, off, 2);
1047 + b43_nphy_rf_ctl_override_rev7(dev, 0x0800, 1, core, off, 1);
1049 + case N_RF_CTL_OVER_CMD_RX_GAIN:
1050 + tmp = value & 0xFF;
1051 + b43_nphy_rf_ctl_override_rev7(dev, 0x0800, tmp, core, off, 0);
1053 + b43_nphy_rf_ctl_override_rev7(dev, 0x6000, tmp, core, off, 0);
1055 + case N_RF_CTL_OVER_CMD_TX_GAIN:
1056 + tmp = value & 0x7FFF;
1057 + b43_nphy_rf_ctl_override_rev7(dev, 0x1000, tmp, core, off, 0);
1058 + tmp = value >> 14;
1059 + b43_nphy_rf_ctl_override_rev7(dev, 0x4000, tmp, core, off, 0);
1064 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverride */
1065 static void b43_nphy_rf_ctl_override(struct b43_wldev *dev, u16 field,
1066 u16 value, u8 core, bool off)
1067 @@ -264,6 +331,8 @@ static void b43_nphy_rf_ctl_intc_overrid
1068 u16 reg, tmp, tmp2, val;
1071 + /* TODO: What about rev19+? Revs 3+ and 7+ are a bit similar */
1073 for (core = 0; core < 2; core++) {
1074 if ((core_sel == 1 && core != 0) ||
1075 (core_sel == 2 && core != 1))
1076 @@ -274,6 +343,7 @@ static void b43_nphy_rf_ctl_intc_overrid
1077 switch (intc_override) {
1078 case N_INTC_OVERRIDE_OFF:
1079 b43_phy_write(dev, reg, 0);
1080 + b43_phy_mask(dev, 0x2ff, ~0x2000);
1081 b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
1083 case N_INTC_OVERRIDE_TRSW:
1084 @@ -505,6 +575,14 @@ static void b43_nphy_stay_in_carrier_sea
1088 +/* http://bcm-v4.sipsolutions.net/PHY/N/Read_Lpf_Bw_Ctl */
1089 +static u16 b43_nphy_read_lpf_ctl(struct b43_wldev *dev, u16 offset)
1092 + offset = b43_is_40mhz(dev) ? 0x159 : 0x154;
1093 + return b43_ntab_read(dev, B43_NTAB16(7, offset)) & 0x7;
1096 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/AdjustLnaGainTbl */
1097 static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev)
1099 @@ -590,44 +668,270 @@ static void b43_nphy_set_rf_sequence(str
1101 **************************************************/
1103 -/* http://bcm-v4.sipsolutions.net/PHY/radio2057_rcal */
1104 +static void b43_radio_2057_chantab_upload(struct b43_wldev *dev,
1105 + const struct b43_nphy_chantabent_rev7 *e_r7,
1106 + const struct b43_nphy_chantabent_rev7_2g *e_r7_2g)
1109 + b43_radio_write(dev, R2057_VCOCAL_COUNTVAL0, e_r7_2g->radio_vcocal_countval0);
1110 + b43_radio_write(dev, R2057_VCOCAL_COUNTVAL1, e_r7_2g->radio_vcocal_countval1);
1111 + b43_radio_write(dev, R2057_RFPLL_REFMASTER_SPAREXTALSIZE, e_r7_2g->radio_rfpll_refmaster_sparextalsize);
1112 + b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_R1, e_r7_2g->radio_rfpll_loopfilter_r1);
1113 + b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C2, e_r7_2g->radio_rfpll_loopfilter_c2);
1114 + b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C1, e_r7_2g->radio_rfpll_loopfilter_c1);
1115 + b43_radio_write(dev, R2057_CP_KPD_IDAC, e_r7_2g->radio_cp_kpd_idac);
1116 + b43_radio_write(dev, R2057_RFPLL_MMD0, e_r7_2g->radio_rfpll_mmd0);
1117 + b43_radio_write(dev, R2057_RFPLL_MMD1, e_r7_2g->radio_rfpll_mmd1);
1118 + b43_radio_write(dev, R2057_VCOBUF_TUNE, e_r7_2g->radio_vcobuf_tune);
1119 + b43_radio_write(dev, R2057_LOGEN_MX2G_TUNE, e_r7_2g->radio_logen_mx2g_tune);
1120 + b43_radio_write(dev, R2057_LOGEN_INDBUF2G_TUNE, e_r7_2g->radio_logen_indbuf2g_tune);
1121 + b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE0, e_r7_2g->radio_txmix2g_tune_boost_pu_core0);
1122 + b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE0, e_r7_2g->radio_pad2g_tune_pus_core0);
1123 + b43_radio_write(dev, R2057_LNA2G_TUNE_CORE0, e_r7_2g->radio_lna2g_tune_core0);
1124 + b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE1, e_r7_2g->radio_txmix2g_tune_boost_pu_core1);
1125 + b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE1, e_r7_2g->radio_pad2g_tune_pus_core1);
1126 + b43_radio_write(dev, R2057_LNA2G_TUNE_CORE1, e_r7_2g->radio_lna2g_tune_core1);
1129 + b43_radio_write(dev, R2057_VCOCAL_COUNTVAL0, e_r7->radio_vcocal_countval0);
1130 + b43_radio_write(dev, R2057_VCOCAL_COUNTVAL1, e_r7->radio_vcocal_countval1);
1131 + b43_radio_write(dev, R2057_RFPLL_REFMASTER_SPAREXTALSIZE, e_r7->radio_rfpll_refmaster_sparextalsize);
1132 + b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_R1, e_r7->radio_rfpll_loopfilter_r1);
1133 + b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C2, e_r7->radio_rfpll_loopfilter_c2);
1134 + b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C1, e_r7->radio_rfpll_loopfilter_c1);
1135 + b43_radio_write(dev, R2057_CP_KPD_IDAC, e_r7->radio_cp_kpd_idac);
1136 + b43_radio_write(dev, R2057_RFPLL_MMD0, e_r7->radio_rfpll_mmd0);
1137 + b43_radio_write(dev, R2057_RFPLL_MMD1, e_r7->radio_rfpll_mmd1);
1138 + b43_radio_write(dev, R2057_VCOBUF_TUNE, e_r7->radio_vcobuf_tune);
1139 + b43_radio_write(dev, R2057_LOGEN_MX2G_TUNE, e_r7->radio_logen_mx2g_tune);
1140 + b43_radio_write(dev, R2057_LOGEN_MX5G_TUNE, e_r7->radio_logen_mx5g_tune);
1141 + b43_radio_write(dev, R2057_LOGEN_INDBUF2G_TUNE, e_r7->radio_logen_indbuf2g_tune);
1142 + b43_radio_write(dev, R2057_LOGEN_INDBUF5G_TUNE, e_r7->radio_logen_indbuf5g_tune);
1143 + b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE0, e_r7->radio_txmix2g_tune_boost_pu_core0);
1144 + b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE0, e_r7->radio_pad2g_tune_pus_core0);
1145 + b43_radio_write(dev, R2057_PGA_BOOST_TUNE_CORE0, e_r7->radio_pga_boost_tune_core0);
1146 + b43_radio_write(dev, R2057_TXMIX5G_BOOST_TUNE_CORE0, e_r7->radio_txmix5g_boost_tune_core0);
1147 + b43_radio_write(dev, R2057_PAD5G_TUNE_MISC_PUS_CORE0, e_r7->radio_pad5g_tune_misc_pus_core0);
1148 + b43_radio_write(dev, R2057_LNA2G_TUNE_CORE0, e_r7->radio_lna2g_tune_core0);
1149 + b43_radio_write(dev, R2057_LNA5G_TUNE_CORE0, e_r7->radio_lna5g_tune_core0);
1150 + b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE1, e_r7->radio_txmix2g_tune_boost_pu_core1);
1151 + b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE1, e_r7->radio_pad2g_tune_pus_core1);
1152 + b43_radio_write(dev, R2057_PGA_BOOST_TUNE_CORE1, e_r7->radio_pga_boost_tune_core1);
1153 + b43_radio_write(dev, R2057_TXMIX5G_BOOST_TUNE_CORE1, e_r7->radio_txmix5g_boost_tune_core1);
1154 + b43_radio_write(dev, R2057_PAD5G_TUNE_MISC_PUS_CORE1, e_r7->radio_pad5g_tune_misc_pus_core1);
1155 + b43_radio_write(dev, R2057_LNA2G_TUNE_CORE1, e_r7->radio_lna2g_tune_core1);
1156 + b43_radio_write(dev, R2057_LNA5G_TUNE_CORE1, e_r7->radio_lna5g_tune_core1);
1160 +static void b43_radio_2057_setup(struct b43_wldev *dev,
1161 + const struct b43_nphy_chantabent_rev7 *tabent_r7,
1162 + const struct b43_nphy_chantabent_rev7_2g *tabent_r7_2g)
1164 + struct b43_phy *phy = &dev->phy;
1166 + b43_radio_2057_chantab_upload(dev, tabent_r7, tabent_r7_2g);
1168 + switch (phy->radio_rev) {
1171 + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
1172 + b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_R1, 0x3f);
1173 + b43_radio_write(dev, R2057_CP_KPD_IDAC, 0x3f);
1174 + b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C1, 0x8);
1175 + b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C2, 0x8);
1177 + b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_R1, 0x1f);
1178 + b43_radio_write(dev, R2057_CP_KPD_IDAC, 0x3f);
1179 + b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C1, 0x8);
1180 + b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C2, 0x8);
1183 + case 9: /* e.g. PHY rev 16 */
1184 + b43_radio_write(dev, R2057_LOGEN_PTAT_RESETS, 0x20);
1185 + b43_radio_write(dev, R2057_VCOBUF_IDACS, 0x18);
1186 + if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
1187 + b43_radio_write(dev, R2057_LOGEN_PTAT_RESETS, 0x38);
1188 + b43_radio_write(dev, R2057_VCOBUF_IDACS, 0x0f);
1190 + if (b43_is_40mhz(dev)) {
1193 + b43_radio_write(dev,
1194 + R2057_PAD_BIAS_FILTER_BWS_CORE0,
1196 + b43_radio_write(dev,
1197 + R2057_PAD_BIAS_FILTER_BWS_CORE1,
1202 + case 14: /* 2 GHz only */
1203 + b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_R1, 0x1b);
1204 + b43_radio_write(dev, R2057_CP_KPD_IDAC, 0x3f);
1205 + b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C1, 0x1f);
1206 + b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C2, 0x1f);
1210 + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
1211 + u16 txmix2g_tune_boost_pu = 0;
1212 + u16 pad2g_tune_pus = 0;
1214 + if (b43_nphy_ipa(dev)) {
1215 + switch (phy->radio_rev) {
1217 + txmix2g_tune_boost_pu = 0x0041;
1221 + txmix2g_tune_boost_pu = 0x21;
1222 + pad2g_tune_pus = 0x23;
1227 + if (txmix2g_tune_boost_pu)
1228 + b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE0,
1229 + txmix2g_tune_boost_pu);
1230 + if (pad2g_tune_pus)
1231 + b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE0,
1233 + if (txmix2g_tune_boost_pu)
1234 + b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE1,
1235 + txmix2g_tune_boost_pu);
1236 + if (pad2g_tune_pus)
1237 + b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE1,
1241 + usleep_range(50, 100);
1243 + /* VCO calibration */
1244 + b43_radio_mask(dev, R2057_RFPLL_MISC_EN, ~0x01);
1245 + b43_radio_mask(dev, R2057_RFPLL_MISC_CAL_RESETN, ~0x04);
1246 + b43_radio_set(dev, R2057_RFPLL_MISC_CAL_RESETN, 0x4);
1247 + b43_radio_set(dev, R2057_RFPLL_MISC_EN, 0x01);
1248 + usleep_range(300, 600);
1251 +/* Calibrate resistors in LPF of PLL?
1252 + * http://bcm-v4.sipsolutions.net/PHY/radio205x_rcal
1254 static u8 b43_radio_2057_rcal(struct b43_wldev *dev)
1256 struct b43_phy *phy = &dev->phy;
1257 + u16 saved_regs_phy[12];
1258 + u16 saved_regs_phy_rf[6];
1259 + u16 saved_regs_radio[2] = { };
1260 + static const u16 phy_to_store[] = {
1261 + B43_NPHY_RFCTL_RSSIO1, B43_NPHY_RFCTL_RSSIO2,
1262 + B43_NPHY_RFCTL_LUT_TRSW_LO1, B43_NPHY_RFCTL_LUT_TRSW_LO2,
1263 + B43_NPHY_RFCTL_RXG1, B43_NPHY_RFCTL_RXG2,
1264 + B43_NPHY_RFCTL_TXG1, B43_NPHY_RFCTL_TXG2,
1265 + B43_NPHY_REV7_RF_CTL_MISC_REG3, B43_NPHY_REV7_RF_CTL_MISC_REG4,
1266 + B43_NPHY_REV7_RF_CTL_MISC_REG5, B43_NPHY_REV7_RF_CTL_MISC_REG6,
1268 + static const u16 phy_to_store_rf[] = {
1269 + B43_NPHY_REV3_RFCTL_OVER0, B43_NPHY_REV3_RFCTL_OVER1,
1270 + B43_NPHY_REV7_RF_CTL_OVER3, B43_NPHY_REV7_RF_CTL_OVER4,
1271 + B43_NPHY_REV7_RF_CTL_OVER5, B43_NPHY_REV7_RF_CTL_OVER6,
1276 - if (phy->radio_rev == 5) {
1277 - b43_phy_mask(dev, 0x342, ~0x2);
1279 + for (i = 0; i < ARRAY_SIZE(phy_to_store); i++)
1280 + saved_regs_phy[i] = b43_phy_read(dev, phy_to_store[i]);
1281 + for (i = 0; i < ARRAY_SIZE(phy_to_store_rf); i++)
1282 + saved_regs_phy_rf[i] = b43_phy_read(dev, phy_to_store_rf[i]);
1285 + for (i = 0; i < ARRAY_SIZE(phy_to_store); i++)
1286 + b43_phy_write(dev, phy_to_store[i], 0);
1287 + b43_phy_write(dev, B43_NPHY_REV3_RFCTL_OVER0, 0x07ff);
1288 + b43_phy_write(dev, B43_NPHY_REV3_RFCTL_OVER1, 0x07ff);
1289 + b43_phy_write(dev, B43_NPHY_REV7_RF_CTL_OVER3, 0x07ff);
1290 + b43_phy_write(dev, B43_NPHY_REV7_RF_CTL_OVER4, 0x07ff);
1291 + b43_phy_write(dev, B43_NPHY_REV7_RF_CTL_OVER5, 0x007f);
1292 + b43_phy_write(dev, B43_NPHY_REV7_RF_CTL_OVER6, 0x007f);
1294 + switch (phy->radio_rev) {
1296 + b43_phy_mask(dev, B43_NPHY_REV7_RF_CTL_OVER3, ~0x2);
1298 b43_radio_set(dev, R2057_IQTEST_SEL_PU, 0x1);
1299 - b43_radio_maskset(dev, 0x1ca, ~0x2, 0x1);
1300 + b43_radio_maskset(dev, R2057v7_IQTEST_SEL_PU2, ~0x2, 0x1);
1303 + b43_phy_set(dev, B43_NPHY_REV7_RF_CTL_OVER3, 0x2);
1304 + b43_phy_set(dev, B43_NPHY_REV7_RF_CTL_MISC_REG3, 0x2);
1305 + saved_regs_radio[0] = b43_radio_read(dev, R2057_IQTEST_SEL_PU);
1306 + b43_radio_write(dev, R2057_IQTEST_SEL_PU, 0x11);
1309 + saved_regs_radio[0] = b43_radio_read(dev, R2057_IQTEST_SEL_PU);
1310 + saved_regs_radio[1] = b43_radio_read(dev, R2057v7_IQTEST_SEL_PU2);
1311 + b43_phy_set(dev, B43_NPHY_REV7_RF_CTL_MISC_REG3, 0x2);
1312 + b43_phy_set(dev, B43_NPHY_REV7_RF_CTL_OVER3, 0x2);
1313 + b43_radio_write(dev, R2057v7_IQTEST_SEL_PU2, 0x2);
1314 + b43_radio_write(dev, R2057_IQTEST_SEL_PU, 0x1);
1319 b43_radio_set(dev, R2057_RCAL_CONFIG, 0x1);
1321 - b43_radio_set(dev, R2057_RCAL_CONFIG, 0x3);
1322 - if (!b43_radio_wait_value(dev, R2057_RCCAL_N1_1, 1, 1, 100, 1000000)) {
1325 + b43_radio_set(dev, R2057_RCAL_CONFIG, 0x2);
1326 + usleep_range(100, 200);
1329 + b43_radio_mask(dev, R2057_RCAL_CONFIG, ~0x2);
1331 + /* Wait and check for result */
1332 + if (!b43_radio_wait_value(dev, R2057_RCAL_STATUS, 1, 1, 100, 1000000)) {
1333 b43err(dev->wl, "Radio 0x2057 rcal timeout\n");
1336 - b43_radio_mask(dev, R2057_RCAL_CONFIG, ~0x2);
1337 tmp = b43_radio_read(dev, R2057_RCAL_STATUS) & 0x3E;
1340 b43_radio_mask(dev, R2057_RCAL_CONFIG, ~0x1);
1342 - if (phy->radio_rev == 5) {
1343 - b43_radio_mask(dev, R2057_IPA2G_CASCONV_CORE0, ~0x1);
1344 - b43_radio_mask(dev, 0x1ca, ~0x2);
1346 - if (phy->radio_rev <= 4 || phy->radio_rev == 6) {
1348 + for (i = 0; i < ARRAY_SIZE(phy_to_store_rf); i++)
1349 + b43_phy_write(dev, phy_to_store_rf[i], saved_regs_phy_rf[i]);
1350 + for (i = 0; i < ARRAY_SIZE(phy_to_store); i++)
1351 + b43_phy_write(dev, phy_to_store[i], saved_regs_phy[i]);
1353 + switch (phy->radio_rev) {
1356 b43_radio_maskset(dev, R2057_TEMPSENSE_CONFIG, ~0x3C, tmp);
1357 b43_radio_maskset(dev, R2057_BANDGAP_RCAL_TRIM, ~0xF0,
1361 + b43_radio_mask(dev, R2057_IPA2G_CASCONV_CORE0, ~0x1);
1362 + b43_radio_mask(dev, R2057v7_IQTEST_SEL_PU2, ~0x2);
1365 + b43_radio_write(dev, R2057_IQTEST_SEL_PU, saved_regs_radio[0]);
1368 + b43_radio_write(dev, R2057_IQTEST_SEL_PU, saved_regs_radio[0]);
1369 + b43_radio_write(dev, R2057v7_IQTEST_SEL_PU2, saved_regs_radio[1]);
1376 -/* http://bcm-v4.sipsolutions.net/PHY/radio2057_rccal */
1377 +/* Calibrate the internal RC oscillator?
1378 + * http://bcm-v4.sipsolutions.net/PHY/radio2057_rccal
1380 static u16 b43_radio_2057_rccal(struct b43_wldev *dev)
1382 struct b43_phy *phy = &dev->phy;
1383 @@ -635,49 +939,76 @@ static u16 b43_radio_2057_rccal(struct b
1384 phy->radio_rev == 6);
1389 b43_radio_write(dev, R2057_RCCAL_MASTER, 0x61);
1390 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xC0);
1392 - b43_radio_write(dev, 0x1AE, 0x61);
1393 - b43_radio_write(dev, R2057_RCCAL_TRC0, 0xE1);
1394 + b43_radio_write(dev, R2057v7_RCCAL_MASTER, 0x61);
1395 + b43_radio_write(dev, R2057_RCCAL_TRC0, 0xE9);
1397 b43_radio_write(dev, R2057_RCCAL_X1, 0x6E);
1399 + /* Start, wait, stop */
1400 b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x55);
1401 - if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 1, 1, 500,
1402 + if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 2, 2, 500,
1404 b43dbg(dev->wl, "Radio 0x2057 rccal timeout\n");
1405 + usleep_range(35, 70);
1406 b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x15);
1407 + usleep_range(70, 140);
1411 b43_radio_write(dev, R2057_RCCAL_MASTER, 0x69);
1412 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xB0);
1414 - b43_radio_write(dev, 0x1AE, 0x69);
1415 + b43_radio_write(dev, R2057v7_RCCAL_MASTER, 0x69);
1416 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xD5);
1418 b43_radio_write(dev, R2057_RCCAL_X1, 0x6E);
1420 + /* Start, wait, stop */
1421 + usleep_range(35, 70);
1422 b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x55);
1423 - if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 1, 1, 500,
1424 + usleep_range(70, 140);
1425 + if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 2, 2, 500,
1427 b43dbg(dev->wl, "Radio 0x2057 rccal timeout\n");
1428 + usleep_range(35, 70);
1429 b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x15);
1430 + usleep_range(70, 140);
1434 b43_radio_write(dev, R2057_RCCAL_MASTER, 0x73);
1435 b43_radio_write(dev, R2057_RCCAL_X1, 0x28);
1436 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xB0);
1438 - b43_radio_write(dev, 0x1AE, 0x73);
1439 + b43_radio_write(dev, R2057v7_RCCAL_MASTER, 0x73);
1440 b43_radio_write(dev, R2057_RCCAL_X1, 0x6E);
1441 b43_radio_write(dev, R2057_RCCAL_TRC0, 0x99);
1444 + /* Start, wait, stop */
1445 + usleep_range(35, 70);
1446 b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x55);
1447 - if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 1, 1, 500,
1448 + usleep_range(70, 140);
1449 + if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 2, 2, 500,
1451 b43err(dev->wl, "Radio 0x2057 rcal timeout\n");
1454 tmp = b43_radio_read(dev, R2057_RCCAL_DONE_OSCCAP);
1455 + usleep_range(35, 70);
1456 b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x15);
1457 + usleep_range(70, 140);
1460 + b43_radio_mask(dev, R2057_RCCAL_MASTER, ~0x1);
1462 + b43_radio_mask(dev, R2057v7_RCCAL_MASTER, ~0x1);
1467 @@ -694,19 +1025,20 @@ static void b43_radio_2057_init_post(str
1469 b43_radio_set(dev, R2057_XTALPUOVR_PINCTRL, 0x1);
1471 + if (0) /* FIXME: Is this BCM43217 specific? */
1472 + b43_radio_set(dev, R2057_XTALPUOVR_PINCTRL, 0x2);
1474 b43_radio_set(dev, R2057_RFPLL_MISC_CAL_RESETN, 0x78);
1475 b43_radio_set(dev, R2057_XTAL_CONFIG2, 0x80);
1477 b43_radio_mask(dev, R2057_RFPLL_MISC_CAL_RESETN, ~0x78);
1478 b43_radio_mask(dev, R2057_XTAL_CONFIG2, ~0x80);
1480 - if (dev->phy.n->init_por) {
1481 + if (dev->phy.do_full_init) {
1482 b43_radio_2057_rcal(dev);
1483 b43_radio_2057_rccal(dev);
1485 b43_radio_mask(dev, R2057_RFPLL_MASTER, ~0x8);
1487 - dev->phy.n->init_por = false;
1490 /* http://bcm-v4.sipsolutions.net/802.11/Radio/2057/Init */
1491 @@ -800,6 +1132,7 @@ static void b43_chantab_radio_2056_uploa
1492 static void b43_radio_2056_setup(struct b43_wldev *dev,
1493 const struct b43_nphy_channeltab_entry_rev3 *e)
1495 + struct b43_phy *phy = &dev->phy;
1496 struct ssb_sprom *sprom = dev->dev->bus_sprom;
1497 enum ieee80211_band band = b43_current_band(dev->wl);
1499 @@ -897,7 +1230,7 @@ static void b43_radio_2056_setup(struct
1500 offset | B2056_TX_MIXG_BOOST_TUNE,
1503 - bias = dev->phy.is_40mhz ? 0x40 : 0x20;
1504 + bias = b43_is_40mhz(dev) ? 0x40 : 0x20;
1505 b43_radio_write(dev,
1506 offset | B2056_TX_INTPAG_IMAIN_STAT,
1508 @@ -911,7 +1244,7 @@ static void b43_radio_2056_setup(struct
1509 b43_radio_write(dev, offset | B2056_TX_PA_SPARE1, 0xee);
1511 } else if (dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ) {
1512 - u16 freq = dev->phy.channel_freq;
1513 + u16 freq = phy->chandef->chan->center_freq;
1517 @@ -1028,7 +1361,7 @@ static void b43_radio_init2056_post(stru
1518 b43_radio_mask(dev, B2056_SYN_COM_RESET, ~0x2);
1519 b43_radio_mask(dev, B2056_SYN_PLL_MAST2, ~0xFC);
1520 b43_radio_mask(dev, B2056_SYN_RCCAL_CTRL0, ~0x1);
1521 - if (dev->phy.n->init_por)
1522 + if (dev->phy.do_full_init)
1523 b43_radio_2056_rcal(dev);
1526 @@ -1041,8 +1374,6 @@ static void b43_radio_init2056(struct b4
1527 b43_radio_init2056_pre(dev);
1528 b2056_upload_inittabs(dev, 0, 0);
1529 b43_radio_init2056_post(dev);
1531 - dev->phy.n->init_por = false;
1534 /**************************************************
1535 @@ -1214,8 +1545,7 @@ static u16 b43_nphy_gen_load_samples(str
1536 u16 bw, len, rot, angle;
1537 struct b43_c32 *samples;
1540 - bw = (dev->phy.is_40mhz) ? 40 : 20;
1541 + bw = b43_is_40mhz(dev) ? 40 : 20;
1545 @@ -1224,7 +1554,7 @@ static u16 b43_nphy_gen_load_samples(str
1549 - if (dev->phy.is_40mhz)
1550 + if (b43_is_40mhz(dev))
1554 @@ -1252,8 +1582,10 @@ static u16 b43_nphy_gen_load_samples(str
1556 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RunSamples */
1557 static void b43_nphy_run_samples(struct b43_wldev *dev, u16 samps, u16 loops,
1558 - u16 wait, bool iqmode, bool dac_test)
1559 + u16 wait, bool iqmode, bool dac_test,
1560 + bool modify_bbmult)
1562 + struct b43_phy *phy = &dev->phy;
1563 struct b43_phy_n *nphy = dev->phy.n;
1566 @@ -1261,17 +1593,35 @@ static void b43_nphy_run_samples(struct
1568 b43_nphy_stay_in_carrier_search(dev, true);
1570 + if (phy->rev >= 7) {
1571 + bool lpf_bw3, lpf_bw4;
1573 + lpf_bw3 = b43_phy_read(dev, B43_NPHY_REV7_RF_CTL_OVER3) & 0x80;
1574 + lpf_bw4 = b43_phy_read(dev, B43_NPHY_REV7_RF_CTL_OVER4) & 0x80;
1576 + if (lpf_bw3 || lpf_bw4) {
1579 + u16 value = b43_nphy_read_lpf_ctl(dev, 0);
1580 + if (phy->rev >= 19)
1581 + b43_nphy_rf_ctl_override_rev19(dev, 0x80, value,
1584 + b43_nphy_rf_ctl_override_rev7(dev, 0x80, value,
1586 + nphy->lpf_bw_overrode_for_sample_play = true;
1590 if ((nphy->bb_mult_save & 0x80000000) == 0) {
1591 tmp = b43_ntab_read(dev, B43_NTAB16(15, 87));
1592 nphy->bb_mult_save = (tmp & 0xFFFF) | 0x80000000;
1595 - /* TODO: add modify_bbmult argument */
1596 - if (!dev->phy.is_40mhz)
1600 - b43_ntab_write(dev, B43_NTAB16(15, 87), tmp);
1601 + if (modify_bbmult) {
1602 + tmp = !b43_is_40mhz(dev) ? 0x6464 : 0x4747;
1603 + b43_ntab_write(dev, B43_NTAB16(15, 87), tmp);
1606 b43_phy_write(dev, B43_NPHY_SAMP_DEPCNT, (samps - 1));
1608 @@ -1289,10 +1639,8 @@ static void b43_nphy_run_samples(struct
1609 b43_phy_mask(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x7FFF);
1610 b43_phy_set(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8000);
1613 - b43_phy_write(dev, B43_NPHY_SAMP_CMD, 5);
1615 - b43_phy_write(dev, B43_NPHY_SAMP_CMD, 1);
1616 + tmp = dac_test ? 5 : 1;
1617 + b43_phy_write(dev, B43_NPHY_SAMP_CMD, tmp);
1619 for (i = 0; i < 100; i++) {
1620 if (!(b43_phy_read(dev, B43_NPHY_RFSEQST) & 1)) {
1621 @@ -1392,6 +1740,12 @@ static void b43_nphy_scale_offset_rssi(s
1625 +static void b43_nphy_rssi_select_rev19(struct b43_wldev *dev, u8 code,
1626 + enum n_rssi_type rssi_type)
1631 static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code,
1632 enum n_rssi_type rssi_type)
1634 @@ -1461,13 +1815,15 @@ static void b43_nphy_rev3_rssi_select(st
1635 enum ieee80211_band band =
1636 b43_current_band(dev->wl);
1638 - if (b43_nphy_ipa(dev))
1639 - val = (band == IEEE80211_BAND_5GHZ) ? 0xC : 0xE;
1642 - reg = (i == 0) ? 0x2000 : 0x3000;
1643 - reg |= B2055_PADDRV;
1644 - b43_radio_write(dev, reg, val);
1645 + if (dev->phy.rev < 7) {
1646 + if (b43_nphy_ipa(dev))
1647 + val = (band == IEEE80211_BAND_5GHZ) ? 0xC : 0xE;
1650 + reg = (i == 0) ? B2056_TX0 : B2056_TX1;
1651 + reg |= B2056_TX_TX_SSI_MUX;
1652 + b43_radio_write(dev, reg, val);
1656 B43_NPHY_AFECTL_OVER1 :
1657 @@ -1554,7 +1910,9 @@ static void b43_nphy_rev2_rssi_select(st
1658 static void b43_nphy_rssi_select(struct b43_wldev *dev, u8 code,
1659 enum n_rssi_type type)
1661 - if (dev->phy.rev >= 3)
1662 + if (dev->phy.rev >= 19)
1663 + b43_nphy_rssi_select_rev19(dev, code, type);
1664 + else if (dev->phy.rev >= 3)
1665 b43_nphy_rev3_rssi_select(dev, code, type);
1667 b43_nphy_rev2_rssi_select(dev, code, type);
1668 @@ -1598,6 +1956,8 @@ static int b43_nphy_poll_rssi(struct b43
1669 u16 save_regs_phy[9];
1672 + /* TODO: rev7+ is treated like rev3+, what about rev19+? */
1674 if (dev->phy.rev >= 3) {
1675 save_regs_phy[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
1676 save_regs_phy[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
1677 @@ -1679,6 +2039,7 @@ static int b43_nphy_poll_rssi(struct b43
1678 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */
1679 static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
1681 + struct b43_phy *phy = &dev->phy;
1682 struct b43_phy_n *nphy = dev->phy.n;
1684 u16 saved_regs_phy_rfctl[2];
1685 @@ -1696,12 +2057,14 @@ static void b43_nphy_rev3_rssi_cal(struc
1686 B43_NPHY_AFECTL_OVER1, B43_NPHY_AFECTL_OVER,
1687 B43_NPHY_AFECTL_C1, B43_NPHY_AFECTL_C2,
1688 B43_NPHY_TXF_40CO_B1S1, B43_NPHY_RFCTL_OVER,
1689 - 0x342, 0x343, 0x346, 0x347,
1690 + B43_NPHY_REV7_RF_CTL_OVER3, B43_NPHY_REV7_RF_CTL_OVER4,
1691 + B43_NPHY_REV7_RF_CTL_OVER5, B43_NPHY_REV7_RF_CTL_OVER6,
1693 B43_NPHY_TXF_40CO_B1S0, B43_NPHY_TXF_40CO_B32S1,
1695 B43_NPHY_RFCTL_LUT_TRSW_UP1, B43_NPHY_RFCTL_LUT_TRSW_UP2,
1696 - 0x340, 0x341, 0x344, 0x345,
1697 + B43_NPHY_REV7_RF_CTL_MISC_REG3, B43_NPHY_REV7_RF_CTL_MISC_REG4,
1698 + B43_NPHY_REV7_RF_CTL_MISC_REG5, B43_NPHY_REV7_RF_CTL_MISC_REG6,
1699 B43_NPHY_RFCTL_RSSIO1, B43_NPHY_RFCTL_RSSIO2
1702 @@ -1748,9 +2111,24 @@ static void b43_nphy_rev3_rssi_cal(struc
1703 b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_TRSW, 1, 7);
1705 if (dev->phy.rev >= 7) {
1707 + b43_nphy_rf_ctl_override_one_to_many(dev,
1708 + N_RF_CTL_OVER_CMD_RXRF_PU,
1710 + b43_nphy_rf_ctl_override_one_to_many(dev,
1711 + N_RF_CTL_OVER_CMD_RX_PU,
1713 + b43_nphy_rf_ctl_override_rev7(dev, 0x80, 1, 0, false, 0);
1714 + b43_nphy_rf_ctl_override_rev7(dev, 0x40, 1, 0, false, 0);
1715 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
1716 + b43_nphy_rf_ctl_override_rev7(dev, 0x20, 0, 0, false,
1718 + b43_nphy_rf_ctl_override_rev7(dev, 0x10, 1, 0, false,
1721 + b43_nphy_rf_ctl_override_rev7(dev, 0x10, 0, 0, false,
1723 + b43_nphy_rf_ctl_override_rev7(dev, 0x20, 1, 0, false,
1727 b43_nphy_rf_ctl_override(dev, 0x1, 0, 0, false);
1728 @@ -1779,7 +2157,10 @@ static void b43_nphy_rev3_rssi_cal(struc
1729 /* Grab RSSI results for every possible VCM */
1730 for (vcm = 0; vcm < 8; vcm++) {
1731 if (dev->phy.rev >= 7)
1733 + b43_radio_maskset(dev,
1734 + core ? R2057_NB_MASTER_CORE1 :
1735 + R2057_NB_MASTER_CORE0,
1736 + ~R2057_VCM_MASK, vcm);
1738 b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC,
1740 @@ -1810,7 +2191,10 @@ static void b43_nphy_rev3_rssi_cal(struc
1742 /* Select the best VCM */
1743 if (dev->phy.rev >= 7)
1745 + b43_radio_maskset(dev,
1746 + core ? R2057_NB_MASTER_CORE1 :
1747 + R2057_NB_MASTER_CORE0,
1748 + ~R2057_VCM_MASK, vcm);
1750 b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC,
1751 0xE3, vcm_final << 2);
1752 @@ -1880,6 +2264,10 @@ static void b43_nphy_rev3_rssi_cal(struc
1753 rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G;
1755 if (dev->phy.rev >= 7) {
1756 + rssical_radio_regs[0] = b43_radio_read(dev,
1757 + R2057_NB_MASTER_CORE0);
1758 + rssical_radio_regs[1] = b43_radio_read(dev,
1759 + R2057_NB_MASTER_CORE1);
1761 rssical_radio_regs[0] = b43_radio_read(dev, B2056_RX0 |
1762 B2056_RX_RSSI_MISC);
1763 @@ -1901,9 +2289,9 @@ static void b43_nphy_rev3_rssi_cal(struc
1765 /* Remember for which channel we store configuration */
1766 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
1767 - nphy->rssical_chanspec_2G.center_freq = dev->phy.channel_freq;
1768 + nphy->rssical_chanspec_2G.center_freq = phy->chandef->chan->center_freq;
1770 - nphy->rssical_chanspec_5G.center_freq = dev->phy.channel_freq;
1771 + nphy->rssical_chanspec_5G.center_freq = phy->chandef->chan->center_freq;
1773 /* End of calibration, restore configuration */
1774 b43_nphy_classifier(dev, 7, class);
1775 @@ -2080,7 +2468,9 @@ static void b43_nphy_rev2_rssi_cal(struc
1777 static void b43_nphy_rssi_cal(struct b43_wldev *dev)
1779 - if (dev->phy.rev >= 3) {
1780 + if (dev->phy.rev >= 19) {
1782 + } else if (dev->phy.rev >= 3) {
1783 b43_nphy_rev3_rssi_cal(dev);
1785 b43_nphy_rev2_rssi_cal(dev, N_RSSI_NB);
1786 @@ -2093,7 +2483,21 @@ static void b43_nphy_rssi_cal(struct b43
1788 **************************************************/
1790 -static void b43_nphy_gain_ctl_workarounds_rev3plus(struct b43_wldev *dev)
1791 +static void b43_nphy_gain_ctl_workarounds_rev19(struct b43_wldev *dev)
1796 +static void b43_nphy_gain_ctl_workarounds_rev7(struct b43_wldev *dev)
1798 + struct b43_phy *phy = &dev->phy;
1800 + switch (phy->rev) {
1805 +static void b43_nphy_gain_ctl_workarounds_rev3(struct b43_wldev *dev)
1807 struct ssb_sprom *sprom = dev->dev->bus_sprom;
1809 @@ -2196,7 +2600,7 @@ static void b43_nphy_gain_ctl_workaround
1810 b43_phy_write(dev, B43_NPHY_C1_NBCLIPTHRES, 0x84);
1811 b43_phy_write(dev, B43_NPHY_C2_NBCLIPTHRES, 0x84);
1813 - if (!dev->phy.is_40mhz) {
1814 + if (!b43_is_40mhz(dev)) {
1815 /* Set dwell lengths */
1816 b43_phy_write(dev, B43_NPHY_CLIP1_NBDWELL_LEN, 0x002B);
1817 b43_phy_write(dev, B43_NPHY_CLIP2_NBDWELL_LEN, 0x002B);
1818 @@ -2210,7 +2614,7 @@ static void b43_nphy_gain_ctl_workaround
1819 b43_phy_maskset(dev, B43_NPHY_C2_CLIPWBTHRES,
1820 ~B43_NPHY_C2_CLIPWBTHRES_CLIP2, 21);
1822 - if (!dev->phy.is_40mhz) {
1823 + if (!b43_is_40mhz(dev)) {
1824 b43_phy_maskset(dev, B43_NPHY_C1_CGAINI,
1825 ~B43_NPHY_C1_CGAINI_GAINBKOFF, 0x1);
1826 b43_phy_maskset(dev, B43_NPHY_C2_CGAINI,
1827 @@ -2225,12 +2629,12 @@ static void b43_nphy_gain_ctl_workaround
1829 if (nphy->gain_boost) {
1830 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ &&
1831 - dev->phy.is_40mhz)
1832 + b43_is_40mhz(dev))
1837 - code = dev->phy.is_40mhz ? 6 : 7;
1838 + code = b43_is_40mhz(dev) ? 6 : 7;
1841 /* Set HPVGA2 index */
1842 @@ -2290,46 +2694,54 @@ static void b43_nphy_gain_ctl_workaround
1843 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */
1844 static void b43_nphy_gain_ctl_workarounds(struct b43_wldev *dev)
1846 - if (dev->phy.rev >= 7)
1848 + if (dev->phy.rev >= 19)
1849 + b43_nphy_gain_ctl_workarounds_rev19(dev);
1850 + else if (dev->phy.rev >= 7)
1851 + b43_nphy_gain_ctl_workarounds_rev7(dev);
1852 else if (dev->phy.rev >= 3)
1853 - b43_nphy_gain_ctl_workarounds_rev3plus(dev);
1854 + b43_nphy_gain_ctl_workarounds_rev3(dev);
1856 b43_nphy_gain_ctl_workarounds_rev1_2(dev);
1859 -/* http://bcm-v4.sipsolutions.net/PHY/N/Read_Lpf_Bw_Ctl */
1860 -static u16 b43_nphy_read_lpf_ctl(struct b43_wldev *dev, u16 offset)
1863 - offset = (dev->phy.is_40mhz) ? 0x159 : 0x154;
1864 - return b43_ntab_read(dev, B43_NTAB16(7, offset)) & 0x7;
1867 static void b43_nphy_workarounds_rev7plus(struct b43_wldev *dev)
1869 struct ssb_sprom *sprom = dev->dev->bus_sprom;
1870 struct b43_phy *phy = &dev->phy;
1873 + u8 tx2rx_events[7] = { 4, 3, 5, 2, 1, 8, 31, };
1874 + u8 tx2rx_delays[7] = { 8, 4, 4, 4, 4, 6, 1, };
1876 u8 rx2tx_events_ipa[9] = { 0x0, 0x1, 0x2, 0x8, 0x5, 0x6, 0xF, 0x3,
1878 u8 rx2tx_delays_ipa[9] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 };
1880 - u16 ntab7_15e_16e[] = { 0x10f, 0x10f };
1881 + static const u16 ntab7_15e_16e[] = { 0, 0x10f, 0x10f };
1882 u8 ntab7_138_146[] = { 0x11, 0x11 };
1883 u8 ntab7_133[] = { 0x77, 0x11, 0x11 };
1885 - u16 lpf_20, lpf_40, lpf_11b;
1886 - u16 bcap_val, bcap_val_11b, bcap_val_11n_20, bcap_val_11n_40;
1887 - u16 scap_val, scap_val_11b, scap_val_11n_20, scap_val_11n_40;
1888 + u16 lpf_ofdm_20mhz[2], lpf_ofdm_40mhz[2], lpf_11b[2];
1890 + s16 bcap_val_11b[2], bcap_val_11n_20[2], bcap_val_11n_40[2];
1892 + s16 scap_val_11b[2], scap_val_11n_20[2], scap_val_11n_40[2];
1893 bool rccal_ovrd = false;
1895 - u16 rx2tx_lut_20_11b, rx2tx_lut_20_11n, rx2tx_lut_40_11n;
1896 u16 bias, conv, filt;
1903 + b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x0125);
1904 + b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x01b3);
1905 + b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x0105);
1906 + b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x016e);
1907 + b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0x00cd);
1908 + b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x0020);
1910 if (phy->rev == 7) {
1911 b43_phy_set(dev, B43_NPHY_FINERX2_CGC, 0x10);
1912 b43_phy_maskset(dev, B43_NPHY_FREQGAIN0, 0xFF80, 0x0020);
1913 @@ -2349,11 +2761,18 @@ static void b43_nphy_workarounds_rev7plu
1914 b43_phy_maskset(dev, B43_NPHY_FREQGAIN7, 0xFF80, 0x0040);
1915 b43_phy_maskset(dev, B43_NPHY_FREQGAIN7, 0x80FF, 0x4000);
1917 - if (phy->rev <= 8) {
1919 + if (phy->rev >= 16) {
1920 + b43_phy_write(dev, B43_NPHY_FORCEFRONT0, 0x7ff);
1921 + b43_phy_write(dev, B43_NPHY_FORCEFRONT1, 0x7ff);
1922 + } else if (phy->rev <= 8) {
1923 b43_phy_write(dev, B43_NPHY_FORCEFRONT0, 0x1B0);
1924 b43_phy_write(dev, B43_NPHY_FORCEFRONT1, 0x1B0);
1926 - if (phy->rev >= 8)
1928 + if (phy->rev >= 16)
1929 + b43_phy_maskset(dev, B43_NPHY_TXTAILCNT, ~0xFF, 0xa0);
1930 + else if (phy->rev >= 8)
1931 b43_phy_maskset(dev, B43_NPHY_TXTAILCNT, ~0xFF, 0x72);
1933 b43_ntab_write(dev, B43_NTAB16(8, 0x00), 2);
1934 @@ -2361,9 +2780,11 @@ static void b43_nphy_workarounds_rev7plu
1935 tmp32 = b43_ntab_read(dev, B43_NTAB32(30, 0));
1937 b43_ntab_write(dev, B43_NTAB32(30, 0), tmp32);
1938 - b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x15e), 2, ntab7_15e_16e);
1939 - b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x16e), 2, ntab7_15e_16e);
1940 + b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x15d), 3, ntab7_15e_16e);
1941 + b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x16d), 3, ntab7_15e_16e);
1943 + b43_nphy_set_rf_sequence(dev, 1, tx2rx_events, tx2rx_delays,
1944 + ARRAY_SIZE(tx2rx_events));
1945 if (b43_nphy_ipa(dev))
1946 b43_nphy_set_rf_sequence(dev, 0, rx2tx_events_ipa,
1947 rx2tx_delays_ipa, ARRAY_SIZE(rx2tx_events_ipa));
1948 @@ -2371,84 +2792,176 @@ static void b43_nphy_workarounds_rev7plu
1949 b43_phy_maskset(dev, B43_NPHY_EPS_OVERRIDEI_0, 0x3FFF, 0x4000);
1950 b43_phy_maskset(dev, B43_NPHY_EPS_OVERRIDEI_1, 0x3FFF, 0x4000);
1952 - lpf_20 = b43_nphy_read_lpf_ctl(dev, 0x154);
1953 - lpf_40 = b43_nphy_read_lpf_ctl(dev, 0x159);
1954 - lpf_11b = b43_nphy_read_lpf_ctl(dev, 0x152);
1955 + for (core = 0; core < 2; core++) {
1956 + lpf_ofdm_20mhz[core] = b43_nphy_read_lpf_ctl(dev, 0x154 + core * 0x10);
1957 + lpf_ofdm_40mhz[core] = b43_nphy_read_lpf_ctl(dev, 0x159 + core * 0x10);
1958 + lpf_11b[core] = b43_nphy_read_lpf_ctl(dev, 0x152 + core * 0x10);
1961 + bcap_val = b43_radio_read(dev, R2057_RCCAL_BCAP_VAL);
1962 + scap_val = b43_radio_read(dev, R2057_RCCAL_SCAP_VAL);
1964 if (b43_nphy_ipa(dev)) {
1965 - if ((phy->radio_rev == 5 && phy->is_40mhz) ||
1966 - phy->radio_rev == 7 || phy->radio_rev == 8) {
1967 - bcap_val = b43_radio_read(dev, 0x16b);
1968 - scap_val = b43_radio_read(dev, 0x16a);
1969 - scap_val_11b = scap_val;
1970 - bcap_val_11b = bcap_val;
1971 - if (phy->radio_rev == 5 && phy->is_40mhz) {
1972 - scap_val_11n_20 = scap_val;
1973 - bcap_val_11n_20 = bcap_val;
1974 - scap_val_11n_40 = bcap_val_11n_40 = 0xc;
1975 + bool ghz2 = b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ;
1977 + switch (phy->radio_rev) {
1979 + /* Check radio version (to be 0) by PHY rev for now */
1980 + if (phy->rev == 8 && b43_is_40mhz(dev)) {
1981 + for (core = 0; core < 2; core++) {
1982 + scap_val_11b[core] = scap_val;
1983 + bcap_val_11b[core] = bcap_val;
1984 + scap_val_11n_20[core] = scap_val;
1985 + bcap_val_11n_20[core] = bcap_val;
1986 + scap_val_11n_40[core] = 0xc;
1987 + bcap_val_11n_40[core] = 0xc;
1991 - } else { /* Rev 7/8 */
1995 + if (phy->rev == 9) {
1996 + /* TODO: Radio version 1 (e.g. BCM5357B0) */
2001 + for (core = 0; core < 2; core++) {
2002 + scap_val_11b[core] = scap_val;
2003 + bcap_val_11b[core] = bcap_val;
2004 + lpf_ofdm_20mhz[core] = 4;
2005 + lpf_11b[core] = 1;
2006 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
2007 - scap_val_11n_20 = 0xc;
2008 - bcap_val_11n_20 = 0xc;
2009 - scap_val_11n_40 = 0xa;
2010 - bcap_val_11n_40 = 0xa;
2011 + scap_val_11n_20[core] = 0xc;
2012 + bcap_val_11n_20[core] = 0xc;
2013 + scap_val_11n_40[core] = 0xa;
2014 + bcap_val_11n_40[core] = 0xa;
2016 - scap_val_11n_20 = 0x14;
2017 - bcap_val_11n_20 = 0x14;
2018 - scap_val_11n_40 = 0xf;
2019 - bcap_val_11n_40 = 0xf;
2020 + scap_val_11n_20[core] = 0x14;
2021 + bcap_val_11n_20[core] = 0x14;
2022 + scap_val_11n_40[core] = 0xf;
2023 + bcap_val_11n_40[core] = 0xf;
2025 - rccal_ovrd = true;
2028 + rccal_ovrd = true;
2031 + for (core = 0; core < 2; core++) {
2032 + bcap_val_11b[core] = bcap_val;
2033 + scap_val_11b[core] = scap_val;
2034 + lpf_11b[core] = 1;
2037 + bcap_val_11n_20[core] = bcap_val + 13;
2038 + scap_val_11n_20[core] = scap_val + 15;
2040 + bcap_val_11n_20[core] = bcap_val + 14;
2041 + scap_val_11n_20[core] = scap_val + 15;
2043 + lpf_ofdm_20mhz[core] = 4;
2046 + bcap_val_11n_40[core] = bcap_val - 7;
2047 + scap_val_11n_40[core] = scap_val - 5;
2049 + bcap_val_11n_40[core] = bcap_val + 2;
2050 + scap_val_11n_40[core] = scap_val + 4;
2052 + lpf_ofdm_40mhz[core] = 4;
2055 + rccal_ovrd = true;
2058 + for (core = 0; core < 2; core++) {
2059 + bcap_val_11b[core] = bcap_val;
2060 + scap_val_11b[core] = scap_val;
2061 + lpf_11b[core] = 1;
2064 + bcap_val_11n_20[0] = bcap_val + 20;
2065 + scap_val_11n_20[0] = scap_val + 20;
2066 + lpf_ofdm_20mhz[0] = 3;
2068 + bcap_val_11n_20[1] = bcap_val + 16;
2069 + scap_val_11n_20[1] = scap_val + 16;
2070 + lpf_ofdm_20mhz[1] = 3;
2072 + bcap_val_11n_40[0] = bcap_val + 20;
2073 + scap_val_11n_40[0] = scap_val + 20;
2074 + lpf_ofdm_40mhz[0] = 4;
2076 + bcap_val_11n_40[1] = bcap_val + 10;
2077 + scap_val_11n_40[1] = scap_val + 10;
2078 + lpf_ofdm_40mhz[1] = 4;
2080 + rccal_ovrd = true;
2084 if (phy->radio_rev == 5) {
2087 - bcap_val = b43_radio_read(dev, 0x16b);
2088 - scap_val = b43_radio_read(dev, 0x16a);
2089 - scap_val_11b = scap_val;
2090 - bcap_val_11b = bcap_val;
2091 - scap_val_11n_20 = 0x11;
2092 - scap_val_11n_40 = 0x11;
2093 - bcap_val_11n_20 = 0x13;
2094 - bcap_val_11n_40 = 0x13;
2095 + for (core = 0; core < 2; core++) {
2096 + lpf_ofdm_20mhz[core] = 1;
2097 + lpf_ofdm_40mhz[core] = 3;
2098 + scap_val_11b[core] = scap_val;
2099 + bcap_val_11b[core] = bcap_val;
2100 + scap_val_11n_20[core] = 0x11;
2101 + scap_val_11n_40[core] = 0x11;
2102 + bcap_val_11n_20[core] = 0x13;
2103 + bcap_val_11n_40[core] = 0x13;
2110 - rx2tx_lut_20_11b = (bcap_val_11b << 8) |
2111 - (scap_val_11b << 3) |
2113 - rx2tx_lut_20_11n = (bcap_val_11n_20 << 8) |
2114 - (scap_val_11n_20 << 3) |
2116 - rx2tx_lut_40_11n = (bcap_val_11n_40 << 8) |
2117 - (scap_val_11n_40 << 3) |
2119 + u16 rx2tx_lut_20_11b[2], rx2tx_lut_20_11n[2], rx2tx_lut_40_11n[2];
2120 + u8 rx2tx_lut_extra = 1;
2122 + for (core = 0; core < 2; core++) {
2123 + bcap_val_11b[core] = clamp_val(bcap_val_11b[core], 0, 0x1f);
2124 + scap_val_11b[core] = clamp_val(scap_val_11b[core], 0, 0x1f);
2125 + bcap_val_11n_20[core] = clamp_val(bcap_val_11n_20[core], 0, 0x1f);
2126 + scap_val_11n_20[core] = clamp_val(scap_val_11n_20[core], 0, 0x1f);
2127 + bcap_val_11n_40[core] = clamp_val(bcap_val_11n_40[core], 0, 0x1f);
2128 + scap_val_11n_40[core] = clamp_val(scap_val_11n_40[core], 0, 0x1f);
2130 + rx2tx_lut_20_11b[core] = (rx2tx_lut_extra << 13) |
2131 + (bcap_val_11b[core] << 8) |
2132 + (scap_val_11b[core] << 3) |
2134 + rx2tx_lut_20_11n[core] = (rx2tx_lut_extra << 13) |
2135 + (bcap_val_11n_20[core] << 8) |
2136 + (scap_val_11n_20[core] << 3) |
2137 + lpf_ofdm_20mhz[core];
2138 + rx2tx_lut_40_11n[core] = (rx2tx_lut_extra << 13) |
2139 + (bcap_val_11n_40[core] << 8) |
2140 + (scap_val_11n_40[core] << 3) |
2141 + lpf_ofdm_40mhz[core];
2144 for (core = 0; core < 2; core++) {
2145 b43_ntab_write(dev, B43_NTAB16(7, 0x152 + core * 16),
2146 - rx2tx_lut_20_11b);
2147 + rx2tx_lut_20_11b[core]);
2148 b43_ntab_write(dev, B43_NTAB16(7, 0x153 + core * 16),
2149 - rx2tx_lut_20_11n);
2150 + rx2tx_lut_20_11n[core]);
2151 b43_ntab_write(dev, B43_NTAB16(7, 0x154 + core * 16),
2152 - rx2tx_lut_20_11n);
2153 + rx2tx_lut_20_11n[core]);
2154 b43_ntab_write(dev, B43_NTAB16(7, 0x155 + core * 16),
2155 - rx2tx_lut_40_11n);
2156 + rx2tx_lut_40_11n[core]);
2157 b43_ntab_write(dev, B43_NTAB16(7, 0x156 + core * 16),
2158 - rx2tx_lut_40_11n);
2159 + rx2tx_lut_40_11n[core]);
2160 b43_ntab_write(dev, B43_NTAB16(7, 0x157 + core * 16),
2161 - rx2tx_lut_40_11n);
2162 + rx2tx_lut_40_11n[core]);
2163 b43_ntab_write(dev, B43_NTAB16(7, 0x158 + core * 16),
2164 - rx2tx_lut_40_11n);
2165 + rx2tx_lut_40_11n[core]);
2166 b43_ntab_write(dev, B43_NTAB16(7, 0x159 + core * 16),
2167 - rx2tx_lut_40_11n);
2168 + rx2tx_lut_40_11n[core]);
2170 - b43_nphy_rf_ctl_override_rev7(dev, 16, 1, 3, false, 2);
2173 b43_phy_write(dev, 0x32F, 0x3);
2175 if (phy->radio_rev == 4 || phy->radio_rev == 6)
2176 b43_nphy_rf_ctl_override_rev7(dev, 4, 1, 3, false, 0);
2178 @@ -2496,7 +3009,8 @@ static void b43_nphy_workarounds_rev7plu
2182 - if (phy->radio_rev == 3) {
2183 + switch (phy->radio_rev) {
2185 for (core = 0; core < 2; core++) {
2187 b43_radio_write(dev, 0x64,
2188 @@ -2522,17 +3036,34 @@ static void b43_nphy_workarounds_rev7plu
2192 - } else if (phy->radio_rev == 7 || phy->radio_rev == 8) {
2193 - if (!phy->is_40mhz) {
2197 + if (!b43_is_40mhz(dev)) {
2198 b43_radio_write(dev, 0x5F, 0x14);
2199 b43_radio_write(dev, 0xE8, 0x12);
2201 b43_radio_write(dev, 0x5F, 0x16);
2202 b43_radio_write(dev, 0xE8, 0x16);
2206 + for (core = 0; core < 2; core++) {
2207 + int o = core ? 0x85 : 0;
2209 + b43_radio_write(dev, o + R2057_IPA2G_CASCONV_CORE0, 0x13);
2210 + b43_radio_write(dev, o + R2057_TXMIX2G_TUNE_BOOST_PU_CORE0, 0x21);
2211 + b43_radio_write(dev, o + R2057_IPA2G_BIAS_FILTER_CORE0, 0xff);
2212 + b43_radio_write(dev, o + R2057_PAD2G_IDACS_CORE0, 0x88);
2213 + b43_radio_write(dev, o + R2057_PAD2G_TUNE_PUS_CORE0, 0x23);
2214 + b43_radio_write(dev, o + R2057_IPA2G_IMAIN_CORE0, 0x16);
2215 + b43_radio_write(dev, o + R2057_PAD_BIAS_FILTER_BWS_CORE0, 0x3e);
2216 + b43_radio_write(dev, o + R2057_BACKUP1_CORE0, 0x10);
2221 - u16 freq = phy->channel_freq;
2222 + u16 freq = phy->chandef->chan->center_freq;
2223 if ((freq >= 5180 && freq <= 5230) ||
2224 (freq >= 5745 && freq <= 5805)) {
2225 b43_radio_write(dev, 0x7D, 0xFF);
2226 @@ -2577,8 +3108,8 @@ static void b43_nphy_workarounds_rev7plu
2227 b43_phy_set(dev, B43_NPHY_AFECTL_OVER1, 0x1);
2228 b43_phy_mask(dev, B43_NPHY_AFECTL_C2, ~0x1);
2229 b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x1);
2230 - b43_ntab_write(dev, B43_NTAB16(8, 0x05), 0x20);
2231 - b43_ntab_write(dev, B43_NTAB16(8, 0x15), 0x20);
2232 + b43_ntab_write(dev, B43_NTAB16(8, 0x05), 0);
2233 + b43_ntab_write(dev, B43_NTAB16(8, 0x15), 0);
2235 b43_phy_mask(dev, B43_NPHY_AFECTL_C1, ~0x4);
2236 b43_phy_mask(dev, B43_NPHY_AFECTL_OVER1, ~0x4);
2237 @@ -2589,20 +3120,20 @@ static void b43_nphy_workarounds_rev7plu
2238 b43_phy_write(dev, B43_NPHY_ENDROP_TLEN, 0x2);
2240 b43_ntab_write(dev, B43_NTAB32(16, 0x100), 20);
2241 - b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x138), 2, ntab7_138_146);
2242 + b43_ntab_write_bulk(dev, B43_NTAB8(7, 0x138), 2, ntab7_138_146);
2243 b43_ntab_write(dev, B43_NTAB16(7, 0x141), 0x77);
2244 - b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x133), 3, ntab7_133);
2245 - b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x146), 2, ntab7_138_146);
2246 + b43_ntab_write_bulk(dev, B43_NTAB8(7, 0x133), 3, ntab7_133);
2247 + b43_ntab_write_bulk(dev, B43_NTAB8(7, 0x146), 2, ntab7_138_146);
2248 b43_ntab_write(dev, B43_NTAB16(7, 0x123), 0x77);
2249 b43_ntab_write(dev, B43_NTAB16(7, 0x12A), 0x77);
2251 - if (!phy->is_40mhz) {
2252 - b43_ntab_write(dev, B43_NTAB32(16, 0x03), 0x18D);
2253 - b43_ntab_write(dev, B43_NTAB32(16, 0x7F), 0x18D);
2255 - b43_ntab_write(dev, B43_NTAB32(16, 0x03), 0x14D);
2256 - b43_ntab_write(dev, B43_NTAB32(16, 0x7F), 0x14D);
2258 + b43_ntab_read_bulk(dev, B43_NTAB32(16, 0x02), 1, noise_tbl);
2259 + noise_tbl[1] = b43_is_40mhz(dev) ? 0x14D : 0x18D;
2260 + b43_ntab_write_bulk(dev, B43_NTAB32(16, 0x02), 2, noise_tbl);
2262 + b43_ntab_read_bulk(dev, B43_NTAB32(16, 0x7E), 1, noise_tbl);
2263 + noise_tbl[1] = b43_is_40mhz(dev) ? 0x14D : 0x18D;
2264 + b43_ntab_write_bulk(dev, B43_NTAB32(16, 0x7E), 2, noise_tbl);
2266 b43_nphy_gain_ctl_workarounds(dev);
2268 @@ -2695,7 +3226,7 @@ static void b43_nphy_workarounds_rev3plu
2270 b43_phy_maskset(dev, B43_NPHY_SGILTRNOFFSET, 0xF0FF, 0x0700);
2272 - if (!dev->phy.is_40mhz) {
2273 + if (!b43_is_40mhz(dev)) {
2274 b43_ntab_write(dev, B43_NTAB32(16, 3), 0x18D);
2275 b43_ntab_write(dev, B43_NTAB32(16, 127), 0x18D);
2277 @@ -2930,6 +3461,7 @@ static void b43_nphy_workarounds(struct
2278 b43_phy_set(dev, B43_NPHY_IQFLIP,
2279 B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2);
2281 + /* TODO: rev19+ */
2282 if (dev->phy.rev >= 7)
2283 b43_nphy_workarounds_rev7plus(dev);
2284 else if (dev->phy.rev >= 3)
2285 @@ -2950,12 +3482,13 @@ static void b43_nphy_workarounds(struct
2286 * http://bcm-v4.sipsolutions.net/802.11/PHY/N/TXTone
2288 static int b43_nphy_tx_tone(struct b43_wldev *dev, u32 freq, u16 max_val,
2289 - bool iqmode, bool dac_test)
2290 + bool iqmode, bool dac_test, bool modify_bbmult)
2292 u16 samp = b43_nphy_gen_load_samples(dev, freq, max_val, dac_test);
2295 - b43_nphy_run_samples(dev, samp, 0xFFFF, 0, iqmode, dac_test);
2296 + b43_nphy_run_samples(dev, samp, 0xFFFF, 0, iqmode, dac_test,
2301 @@ -2990,6 +3523,7 @@ static void b43_nphy_update_txrx_chain(s
2302 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/stop-playback */
2303 static void b43_nphy_stop_playback(struct b43_wldev *dev)
2305 + struct b43_phy *phy = &dev->phy;
2306 struct b43_phy_n *nphy = dev->phy.n;
2309 @@ -3010,6 +3544,15 @@ static void b43_nphy_stop_playback(struc
2310 nphy->bb_mult_save = 0;
2313 + if (phy->rev >= 7 && nphy->lpf_bw_overrode_for_sample_play) {
2314 + if (phy->rev >= 19)
2315 + b43_nphy_rf_ctl_override_rev19(dev, 0x80, 0, 0, true,
2318 + b43_nphy_rf_ctl_override_rev7(dev, 0x80, 0, 0, true, 1);
2319 + nphy->lpf_bw_overrode_for_sample_play = false;
2322 if (nphy->hang_avoid)
2323 b43_nphy_stay_in_carrier_search(dev, 0);
2325 @@ -3019,16 +3562,23 @@ static void b43_nphy_iq_cal_gain_params(
2326 struct nphy_txgains target,
2327 struct nphy_iqcal_params *params)
2329 + struct b43_phy *phy = &dev->phy;
2333 if (dev->phy.rev >= 3) {
2334 + params->tx_lpf = target.tx_lpf[core]; /* Rev 7+ */
2335 params->txgm = target.txgm[core];
2336 params->pga = target.pga[core];
2337 params->pad = target.pad[core];
2338 params->ipa = target.ipa[core];
2339 - params->cal_gain = (params->txgm << 12) | (params->pga << 8) |
2340 - (params->pad << 4) | (params->ipa);
2341 + if (phy->rev >= 19) {
2343 + } else if (phy->rev >= 7) {
2344 + params->cal_gain = (params->txgm << 12) | (params->pga << 8) | (params->pad << 3) | (params->ipa) | (params->tx_lpf << 15);
2346 + params->cal_gain = (params->txgm << 12) | (params->pga << 8) | (params->pad << 4) | (params->ipa);
2348 for (j = 0; j < 5; j++)
2349 params->ncorr[j] = 0x79;
2351 @@ -3069,6 +3619,7 @@ static enum b43_txpwr_result b43_nphy_op
2352 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlEnable */
2353 static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable)
2355 + struct b43_phy *phy = &dev->phy;
2356 struct b43_phy_n *nphy = dev->phy.n;
2358 u16 bmask, val, tmp;
2359 @@ -3118,7 +3669,7 @@ static void b43_nphy_tx_power_ctrl(struc
2360 b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3,
2361 ~B43_NPHY_BPHY_CTL3_SCALE, 0x5A);
2363 - if (dev->phy.rev < 2 && dev->phy.is_40mhz)
2364 + if (dev->phy.rev < 2 && b43_is_40mhz(dev))
2365 b43_hf_write(dev, b43_hf_read(dev) | B43_HF_TSSIRPSMW);
2367 b43_ntab_write_bulk(dev, B43_NTAB16(26, 64), 84,
2368 @@ -3138,12 +3689,25 @@ static void b43_nphy_tx_power_ctrl(struc
2369 b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD, ~(bmask), val);
2371 if (band == IEEE80211_BAND_5GHZ) {
2372 - b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD,
2373 - ~B43_NPHY_TXPCTL_CMD_INIT, 0x64);
2374 - if (dev->phy.rev > 1)
2375 + if (phy->rev >= 19) {
2377 + } else if (phy->rev >= 7) {
2378 + b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD,
2379 + ~B43_NPHY_TXPCTL_CMD_INIT,
2381 b43_phy_maskset(dev, B43_NPHY_TXPCTL_INIT,
2382 ~B43_NPHY_TXPCTL_INIT_PIDXI1,
2385 + b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD,
2386 + ~B43_NPHY_TXPCTL_CMD_INIT,
2389 + b43_phy_maskset(dev,
2390 + B43_NPHY_TXPCTL_INIT,
2391 + ~B43_NPHY_TXPCTL_INIT_PIDXI1,
2396 if (dev->phy.rev >= 3) {
2397 @@ -3160,6 +3724,10 @@ static void b43_nphy_tx_power_ctrl(struc
2401 + if (phy->rev >= 7) {
2405 if (dev->phy.rev >= 3) {
2406 b43_phy_mask(dev, B43_NPHY_AFECTL_OVER1, ~0x100);
2407 b43_phy_mask(dev, B43_NPHY_AFECTL_OVER, ~0x100);
2408 @@ -3172,7 +3740,7 @@ static void b43_nphy_tx_power_ctrl(struc
2409 else if (dev->phy.rev < 2)
2410 b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3, ~0xFF, 0x40);
2412 - if (dev->phy.rev < 2 && dev->phy.is_40mhz)
2413 + if (dev->phy.rev < 2 && b43_is_40mhz(dev))
2414 b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_TSSIRPSMW);
2416 if (b43_nphy_ipa(dev)) {
2417 @@ -3188,18 +3756,20 @@ static void b43_nphy_tx_power_ctrl(struc
2418 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrFix */
2419 static void b43_nphy_tx_power_fix(struct b43_wldev *dev)
2421 + struct b43_phy *phy = &dev->phy;
2422 struct b43_phy_n *nphy = dev->phy.n;
2423 struct ssb_sprom *sprom = dev->dev->bus_sprom;
2425 u8 txpi[2], bbmult, i;
2426 u16 tmp, radio_gain, dac_gain;
2427 - u16 freq = dev->phy.channel_freq;
2428 + u16 freq = phy->chandef->chan->center_freq;
2430 /* u32 gaintbl; rev3+ */
2432 if (nphy->hang_avoid)
2433 b43_nphy_stay_in_carrier_search(dev, 1);
2435 + /* TODO: rev19+ */
2436 if (dev->phy.rev >= 7) {
2437 txpi[0] = txpi[1] = 30;
2438 } else if (dev->phy.rev >= 3) {
2439 @@ -3238,7 +3808,11 @@ static void b43_nphy_tx_power_fix(struct
2442 for (i = 0; i < 2; i++) {
2443 - txgain = *(b43_nphy_get_tx_gain_table(dev) + txpi[i]);
2444 + const u32 *table = b43_nphy_get_tx_gain_table(dev);
2448 + txgain = *(table + txpi[i]);
2450 if (dev->phy.rev >= 3)
2451 radio_gain = (txgain >> 16) & 0x1FFFF;
2452 @@ -3298,7 +3872,9 @@ static void b43_nphy_ipa_internal_tssi_s
2454 u16 r; /* routing */
2456 - if (phy->rev >= 7) {
2457 + if (phy->rev >= 19) {
2459 + } else if (phy->rev >= 7) {
2460 for (core = 0; core < 2; core++) {
2461 r = core ? 0x190 : 0x170;
2462 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
2463 @@ -3381,29 +3957,38 @@ static void b43_nphy_tx_power_ctl_idle_t
2467 - /* TODO: check if we can transmit */
2468 + if (phy->chandef->chan->flags & IEEE80211_CHAN_NO_IR)
2471 if (b43_nphy_ipa(dev))
2472 b43_nphy_ipa_internal_tssi_setup(dev);
2474 - if (phy->rev >= 7)
2475 - b43_nphy_rf_ctl_override_rev7(dev, 0x2000, 0, 3, false, 0);
2476 + if (phy->rev >= 19)
2477 + b43_nphy_rf_ctl_override_rev19(dev, 0x1000, 0, 3, false, 0);
2478 + else if (phy->rev >= 7)
2479 + b43_nphy_rf_ctl_override_rev7(dev, 0x1000, 0, 3, false, 0);
2480 else if (phy->rev >= 3)
2481 b43_nphy_rf_ctl_override(dev, 0x2000, 0, 3, false);
2483 b43_nphy_stop_playback(dev);
2484 - b43_nphy_tx_tone(dev, 0xFA0, 0, false, false);
2485 + b43_nphy_tx_tone(dev, 4000, 0, false, false, false);
2487 tmp = b43_nphy_poll_rssi(dev, N_RSSI_TSSI_2G, rssi, 1);
2488 b43_nphy_stop_playback(dev);
2490 b43_nphy_rssi_select(dev, 0, N_RSSI_W1);
2492 - if (phy->rev >= 7)
2493 - b43_nphy_rf_ctl_override_rev7(dev, 0x2000, 0, 3, true, 0);
2494 + if (phy->rev >= 19)
2495 + b43_nphy_rf_ctl_override_rev19(dev, 0x1000, 0, 3, true, 0);
2496 + else if (phy->rev >= 7)
2497 + b43_nphy_rf_ctl_override_rev7(dev, 0x1000, 0, 3, true, 0);
2498 else if (phy->rev >= 3)
2499 b43_nphy_rf_ctl_override(dev, 0x2000, 0, 3, true);
2501 - if (phy->rev >= 3) {
2502 + if (phy->rev >= 19) {
2505 + } else if (phy->rev >= 3) {
2506 nphy->pwr_ctl_info[0].idle_tssi_5g = (tmp >> 24) & 0xFF;
2507 nphy->pwr_ctl_info[1].idle_tssi_5g = (tmp >> 8) & 0xFF;
2509 @@ -3443,21 +4028,21 @@ static void b43_nphy_tx_prepare_adjusted
2513 - if (dev->phy.is_40mhz && dev->phy.rev >= 5) {
2514 + if (b43_is_40mhz(dev) && dev->phy.rev >= 5) {
2518 - idx = dev->phy.is_40mhz ? 52 : 4;
2519 + idx = b43_is_40mhz(dev) ? 52 : 4;
2523 - idx = dev->phy.is_40mhz ? 76 : 28;
2524 + idx = b43_is_40mhz(dev) ? 76 : 28;
2527 - idx = dev->phy.is_40mhz ? 84 : 36;
2528 + idx = b43_is_40mhz(dev) ? 84 : 36;
2531 - idx = dev->phy.is_40mhz ? 92 : 44;
2532 + idx = b43_is_40mhz(dev) ? 92 : 44;
2536 @@ -3478,6 +4063,7 @@ static void b43_nphy_tx_prepare_adjusted
2537 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlSetup */
2538 static void b43_nphy_tx_power_ctl_setup(struct b43_wldev *dev)
2540 + struct b43_phy *phy = &dev->phy;
2541 struct b43_phy_n *nphy = dev->phy.n;
2542 struct ssb_sprom *sprom = dev->dev->bus_sprom;
2544 @@ -3487,7 +4073,7 @@ static void b43_nphy_tx_power_ctl_setup(
2548 - u16 freq = dev->phy.channel_freq;
2549 + u16 freq = phy->chandef->chan->center_freq;
2551 u16 r; /* routing */
2553 @@ -3594,7 +4180,9 @@ static void b43_nphy_tx_power_ctl_setup(
2557 - if (dev->phy.rev >= 7) {
2558 + if (phy->rev >= 19) {
2560 + } else if (phy->rev >= 7) {
2561 b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD,
2562 ~B43_NPHY_TXPCTL_CMD_INIT, 0x19);
2563 b43_phy_maskset(dev, B43_NPHY_TXPCTL_INIT,
2564 @@ -3651,27 +4239,36 @@ static void b43_nphy_tx_gain_table_uploa
2567 table = b43_nphy_get_tx_gain_table(dev);
2571 b43_ntab_write_bulk(dev, B43_NTAB32(26, 192), 128, table);
2572 b43_ntab_write_bulk(dev, B43_NTAB32(27, 192), 128, table);
2574 - if (phy->rev >= 3) {
2579 - nphy->gmval = (table[0] >> 16) & 0x7000;
2580 + nphy->gmval = (table[0] >> 16) & 0x7000;
2583 - for (i = 0; i < 128; i++) {
2584 + for (i = 0; i < 128; i++) {
2585 + if (phy->rev >= 19) {
2588 + } else if (phy->rev >= 7) {
2592 pga_gain = (table[i] >> 24) & 0xF;
2593 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
2595 - b43_ntab_papd_pga_gain_delta_ipa_2g[pga_gain];
2596 + rfpwr_offset = b43_ntab_papd_pga_gain_delta_ipa_2g[pga_gain];
2600 - b43_ntab_write(dev, B43_NTAB32(26, 576 + i),
2602 - b43_ntab_write(dev, B43_NTAB32(27, 576 + i),
2604 + rfpwr_offset = 0; /* FIXME */
2607 + b43_ntab_write(dev, B43_NTAB32(26, 576 + i), rfpwr_offset);
2608 + b43_ntab_write(dev, B43_NTAB32(27, 576 + i), rfpwr_offset);
2612 @@ -3688,7 +4285,9 @@ static void b43_nphy_pa_override(struct
2613 nphy->rfctrl_intc2_save = b43_phy_read(dev,
2614 B43_NPHY_RFCTL_INTC2);
2615 band = b43_current_band(dev->wl);
2616 - if (dev->phy.rev >= 3) {
2617 + if (dev->phy.rev >= 7) {
2619 + } else if (dev->phy.rev >= 3) {
2620 if (band == IEEE80211_BAND_5GHZ)
2623 @@ -3709,21 +4308,28 @@ static void b43_nphy_pa_override(struct
2627 -/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxLpFbw */
2628 -static void b43_nphy_tx_lp_fbw(struct b43_wldev *dev)
2630 + * TX low-pass filter bandwidth setup
2631 + * http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxLpFbw
2633 +static void b43_nphy_tx_lpf_bw(struct b43_wldev *dev)
2637 - if (dev->phy.rev >= 3) {
2638 - if (b43_nphy_ipa(dev)) {
2640 - b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S2,
2641 - (((((tmp << 3) | tmp) << 3) | tmp) << 3) | tmp);
2643 + if (dev->phy.rev < 3 || dev->phy.rev >= 7)
2646 + if (b43_nphy_ipa(dev))
2647 + tmp = b43_is_40mhz(dev) ? 5 : 4;
2649 + tmp = b43_is_40mhz(dev) ? 3 : 1;
2650 + b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S2,
2651 + (tmp << 9) | (tmp << 6) | (tmp << 3) | tmp);
2654 + if (b43_nphy_ipa(dev)) {
2655 + tmp = b43_is_40mhz(dev) ? 4 : 1;
2656 b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S2,
2657 - (((((tmp << 3) | tmp) << 3) | tmp) << 3) | tmp);
2658 + (tmp << 9) | (tmp << 6) | (tmp << 3) | tmp);
2662 @@ -3996,7 +4602,7 @@ static void b43_nphy_spur_workaround(str
2664 if (nphy->gband_spurwar_en) {
2665 /* TODO: N PHY Adjust Analog Pfbw (7) */
2666 - if (channel == 11 && dev->phy.is_40mhz)
2667 + if (channel == 11 && b43_is_40mhz(dev))
2668 ; /* TODO: N PHY Adjust Min Noise Var(2, tone, noise)*/
2670 ; /* TODO: N PHY Adjust Min Noise Var(0, NULL, NULL)*/
2671 @@ -4128,7 +4734,13 @@ static void b43_nphy_restore_rssi_cal(st
2672 rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G;
2675 - if (dev->phy.rev >= 7) {
2676 + if (dev->phy.rev >= 19) {
2678 + } else if (dev->phy.rev >= 7) {
2679 + b43_radio_maskset(dev, R2057_NB_MASTER_CORE0, ~R2057_VCM_MASK,
2680 + rssical_radio_regs[0]);
2681 + b43_radio_maskset(dev, R2057_NB_MASTER_CORE1, ~R2057_VCM_MASK,
2682 + rssical_radio_regs[1]);
2684 b43_radio_maskset(dev, B2056_RX0 | B2056_RX_RSSI_MISC, 0xE3,
2685 rssical_radio_regs[0]);
2686 @@ -4152,15 +4764,78 @@ static void b43_nphy_restore_rssi_cal(st
2687 b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Y, rssical_phy_regs[11]);
2690 +static void b43_nphy_tx_cal_radio_setup_rev19(struct b43_wldev *dev)
2695 +static void b43_nphy_tx_cal_radio_setup_rev7(struct b43_wldev *dev)
2697 + struct b43_phy *phy = &dev->phy;
2698 + struct b43_phy_n *nphy = dev->phy.n;
2699 + u16 *save = nphy->tx_rx_cal_radio_saveregs;
2703 + for (core = 0; core < 2; core++) {
2704 + r = core ? 0x20 : 0;
2707 + save[off + 0] = b43_radio_read(dev, r + R2057_TX0_TX_SSI_MASTER);
2708 + save[off + 1] = b43_radio_read(dev, r + R2057_TX0_IQCAL_VCM_HG);
2709 + save[off + 2] = b43_radio_read(dev, r + R2057_TX0_IQCAL_IDAC);
2710 + save[off + 3] = b43_radio_read(dev, r + R2057_TX0_TSSI_VCM);
2711 + save[off + 4] = 0;
2712 + save[off + 5] = b43_radio_read(dev, r + R2057_TX0_TX_SSI_MUX);
2713 + if (phy->radio_rev != 5)
2714 + save[off + 6] = b43_radio_read(dev, r + R2057_TX0_TSSIA);
2715 + save[off + 7] = b43_radio_read(dev, r + R2057_TX0_TSSIG);
2716 + save[off + 8] = b43_radio_read(dev, r + R2057_TX0_TSSI_MISC1);
2718 + if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
2719 + b43_radio_write(dev, r + R2057_TX0_TX_SSI_MASTER, 0xA);
2720 + b43_radio_write(dev, r + R2057_TX0_IQCAL_VCM_HG, 0x43);
2721 + b43_radio_write(dev, r + R2057_TX0_IQCAL_IDAC, 0x55);
2722 + b43_radio_write(dev, r + R2057_TX0_TSSI_VCM, 0);
2723 + b43_radio_write(dev, r + R2057_TX0_TSSIG, 0);
2724 + if (nphy->use_int_tx_iq_lo_cal) {
2725 + b43_radio_write(dev, r + R2057_TX0_TX_SSI_MUX, 0x4);
2726 + tmp = true ? 0x31 : 0x21; /* TODO */
2727 + b43_radio_write(dev, r + R2057_TX0_TSSIA, tmp);
2729 + b43_radio_write(dev, r + R2057_TX0_TSSI_MISC1, 0x00);
2731 + b43_radio_write(dev, r + R2057_TX0_TX_SSI_MASTER, 0x6);
2732 + b43_radio_write(dev, r + R2057_TX0_IQCAL_VCM_HG, 0x43);
2733 + b43_radio_write(dev, r + R2057_TX0_IQCAL_IDAC, 0x55);
2734 + b43_radio_write(dev, r + R2057_TX0_TSSI_VCM, 0);
2736 + if (phy->radio_rev != 5)
2737 + b43_radio_write(dev, r + R2057_TX0_TSSIA, 0);
2738 + if (nphy->use_int_tx_iq_lo_cal) {
2739 + b43_radio_write(dev, r + R2057_TX0_TX_SSI_MUX, 0x6);
2740 + tmp = true ? 0x31 : 0x21; /* TODO */
2741 + b43_radio_write(dev, r + R2057_TX0_TSSIG, tmp);
2743 + b43_radio_write(dev, r + R2057_TX0_TSSI_MISC1, 0);
2748 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalRadioSetup */
2749 static void b43_nphy_tx_cal_radio_setup(struct b43_wldev *dev)
2751 + struct b43_phy *phy = &dev->phy;
2752 struct b43_phy_n *nphy = dev->phy.n;
2753 u16 *save = nphy->tx_rx_cal_radio_saveregs;
2757 - if (dev->phy.rev >= 3) {
2758 + if (phy->rev >= 19) {
2759 + b43_nphy_tx_cal_radio_setup_rev19(dev);
2760 + } else if (phy->rev >= 7) {
2761 + b43_nphy_tx_cal_radio_setup_rev7(dev);
2762 + } else if (phy->rev >= 3) {
2763 for (i = 0; i < 2; i++) {
2764 tmp = (i == 0) ? 0x2000 : 0x3000;
2766 @@ -4269,41 +4944,62 @@ static void b43_nphy_update_tx_cal_ladde
2770 +static void b43_nphy_pa_set_tx_dig_filter(struct b43_wldev *dev, u16 offset,
2771 + const s16 *filter)
2775 + offset = B43_PHY_N(offset);
2777 + for (i = 0; i < 15; i++, offset++)
2778 + b43_phy_write(dev, offset, filter[i]);
2781 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ExtPaSetTxDigiFilts */
2782 static void b43_nphy_ext_pa_set_tx_dig_filters(struct b43_wldev *dev)
2785 - for (i = 0; i < 15; i++)
2786 - b43_phy_write(dev, B43_PHY_N(0x2C5 + i),
2787 - tbl_tx_filter_coef_rev4[2][i]);
2788 + b43_nphy_pa_set_tx_dig_filter(dev, 0x2C5,
2789 + tbl_tx_filter_coef_rev4[2]);
2792 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/IpaSetTxDigiFilts */
2793 static void b43_nphy_int_pa_set_tx_dig_filters(struct b43_wldev *dev)
2796 /* B43_NPHY_TXF_20CO_S0A1, B43_NPHY_TXF_40CO_S0A1, unknown */
2797 static const u16 offset[] = { 0x186, 0x195, 0x2C5 };
2798 + static const s16 dig_filter_phy_rev16[] = {
2799 + -375, 136, -407, 208, -1527,
2800 + 956, 93, 186, 93, 230,
2801 + -44, 230, 201, -191, 201,
2805 for (i = 0; i < 3; i++)
2806 - for (j = 0; j < 15; j++)
2807 - b43_phy_write(dev, B43_PHY_N(offset[i] + j),
2808 - tbl_tx_filter_coef_rev4[i][j]);
2810 - if (dev->phy.is_40mhz) {
2811 - for (j = 0; j < 15; j++)
2812 - b43_phy_write(dev, B43_PHY_N(offset[0] + j),
2813 - tbl_tx_filter_coef_rev4[3][j]);
2814 - } else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
2815 - for (j = 0; j < 15; j++)
2816 - b43_phy_write(dev, B43_PHY_N(offset[0] + j),
2817 - tbl_tx_filter_coef_rev4[5][j]);
2820 - if (dev->phy.channel == 14)
2821 - for (j = 0; j < 15; j++)
2822 - b43_phy_write(dev, B43_PHY_N(offset[0] + j),
2823 - tbl_tx_filter_coef_rev4[6][j]);
2824 + b43_nphy_pa_set_tx_dig_filter(dev, offset[i],
2825 + tbl_tx_filter_coef_rev4[i]);
2827 + /* Verified with BCM43227 and BCM43228 */
2828 + if (dev->phy.rev == 16)
2829 + b43_nphy_pa_set_tx_dig_filter(dev, 0x186, dig_filter_phy_rev16);
2831 + /* Verified with BCM43131 and BCM43217 */
2832 + if (dev->phy.rev == 17) {
2833 + b43_nphy_pa_set_tx_dig_filter(dev, 0x186, dig_filter_phy_rev16);
2834 + b43_nphy_pa_set_tx_dig_filter(dev, 0x195,
2835 + tbl_tx_filter_coef_rev4[1]);
2838 + if (b43_is_40mhz(dev)) {
2839 + b43_nphy_pa_set_tx_dig_filter(dev, 0x186,
2840 + tbl_tx_filter_coef_rev4[3]);
2842 + if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
2843 + b43_nphy_pa_set_tx_dig_filter(dev, 0x186,
2844 + tbl_tx_filter_coef_rev4[5]);
2845 + if (dev->phy.channel == 14)
2846 + b43_nphy_pa_set_tx_dig_filter(dev, 0x186,
2847 + tbl_tx_filter_coef_rev4[6]);
2851 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetTxGain */
2852 @@ -4325,7 +5021,13 @@ static struct nphy_txgains b43_nphy_get_
2853 b43_nphy_stay_in_carrier_search(dev, false);
2855 for (i = 0; i < 2; ++i) {
2856 - if (dev->phy.rev >= 3) {
2857 + if (dev->phy.rev >= 7) {
2858 + target.ipa[i] = curr_gain[i] & 0x0007;
2859 + target.pad[i] = (curr_gain[i] & 0x00F8) >> 3;
2860 + target.pga[i] = (curr_gain[i] & 0x0F00) >> 8;
2861 + target.txgm[i] = (curr_gain[i] & 0x7000) >> 12;
2862 + target.tx_lpf[i] = (curr_gain[i] & 0x8000) >> 15;
2863 + } else if (dev->phy.rev >= 3) {
2864 target.ipa[i] = curr_gain[i] & 0x000F;
2865 target.pad[i] = (curr_gain[i] & 0x00F0) >> 4;
2866 target.pga[i] = (curr_gain[i] & 0x0F00) >> 8;
2867 @@ -4349,7 +5051,16 @@ static struct nphy_txgains b43_nphy_get_
2869 for (i = 0; i < 2; ++i) {
2870 table = b43_nphy_get_tx_gain_table(dev);
2871 - if (dev->phy.rev >= 3) {
2875 + if (dev->phy.rev >= 7) {
2876 + target.ipa[i] = (table[index[i]] >> 16) & 0x7;
2877 + target.pad[i] = (table[index[i]] >> 19) & 0x1F;
2878 + target.pga[i] = (table[index[i]] >> 24) & 0xF;
2879 + target.txgm[i] = (table[index[i]] >> 28) & 0x7;
2880 + target.tx_lpf[i] = (table[index[i]] >> 31) & 0x1;
2881 + } else if (dev->phy.rev >= 3) {
2882 target.ipa[i] = (table[index[i]] >> 16) & 0xF;
2883 target.pad[i] = (table[index[i]] >> 20) & 0xF;
2884 target.pga[i] = (table[index[i]] >> 24) & 0xF;
2885 @@ -4398,6 +5109,8 @@ static void b43_nphy_tx_cal_phy_cleanup(
2886 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalPhySetup */
2887 static void b43_nphy_tx_cal_phy_setup(struct b43_wldev *dev)
2889 + struct b43_phy *phy = &dev->phy;
2890 + struct b43_phy_n *nphy = dev->phy.n;
2891 u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs;
2894 @@ -4429,7 +5142,12 @@ static void b43_nphy_tx_cal_phy_setup(st
2895 regs[7] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
2896 regs[8] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
2898 - b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_PA, 1, 3);
2899 + if (!nphy->use_int_tx_iq_lo_cal)
2900 + b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_PA,
2903 + b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_PA,
2905 b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_TRSW, 2, 1);
2906 b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_TRSW, 8, 2);
2908 @@ -4437,6 +5155,33 @@ static void b43_nphy_tx_cal_phy_setup(st
2909 regs[10] = b43_phy_read(dev, B43_NPHY_PAPD_EN1);
2910 b43_phy_mask(dev, B43_NPHY_PAPD_EN0, ~0x0001);
2911 b43_phy_mask(dev, B43_NPHY_PAPD_EN1, ~0x0001);
2913 + tmp = b43_nphy_read_lpf_ctl(dev, 0);
2914 + if (phy->rev >= 19)
2915 + b43_nphy_rf_ctl_override_rev19(dev, 0x80, tmp, 0, false,
2917 + else if (phy->rev >= 7)
2918 + b43_nphy_rf_ctl_override_rev7(dev, 0x80, tmp, 0, false,
2921 + if (nphy->use_int_tx_iq_lo_cal && true /* FIXME */) {
2922 + if (phy->rev >= 19) {
2923 + b43_nphy_rf_ctl_override_rev19(dev, 0x8, 0, 0x3,
2925 + } else if (phy->rev >= 8) {
2926 + b43_nphy_rf_ctl_override_rev7(dev, 0x8, 0, 0x3,
2928 + } else if (phy->rev == 7) {
2929 + b43_radio_maskset(dev, R2057_OVR_REG0, 1 << 4, 1 << 4);
2930 + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
2931 + b43_radio_maskset(dev, R2057_PAD2G_TUNE_PUS_CORE0, ~1, 0);
2932 + b43_radio_maskset(dev, R2057_PAD2G_TUNE_PUS_CORE1, ~1, 0);
2934 + b43_radio_maskset(dev, R2057_IPA5G_CASCOFFV_PU_CORE0, ~1, 0);
2935 + b43_radio_maskset(dev, R2057_IPA5G_CASCOFFV_PU_CORE1, ~1, 0);
2940 b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, 0xA000);
2941 b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, 0xA000);
2942 @@ -4465,6 +5210,7 @@ static void b43_nphy_tx_cal_phy_setup(st
2943 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SaveCal */
2944 static void b43_nphy_save_cal(struct b43_wldev *dev)
2946 + struct b43_phy *phy = &dev->phy;
2947 struct b43_phy_n *nphy = dev->phy.n;
2949 struct b43_phy_n_iq_comp *rxcal_coeffs = NULL;
2950 @@ -4489,7 +5235,26 @@ static void b43_nphy_save_cal(struct b43
2952 b43_nphy_rx_iq_coeffs(dev, false, rxcal_coeffs);
2953 /* TODO use some definitions */
2954 - if (dev->phy.rev >= 3) {
2955 + if (phy->rev >= 19) {
2957 + } else if (phy->rev >= 7) {
2958 + txcal_radio_regs[0] = b43_radio_read(dev,
2959 + R2057_TX0_LOFT_FINE_I);
2960 + txcal_radio_regs[1] = b43_radio_read(dev,
2961 + R2057_TX0_LOFT_FINE_Q);
2962 + txcal_radio_regs[4] = b43_radio_read(dev,
2963 + R2057_TX0_LOFT_COARSE_I);
2964 + txcal_radio_regs[5] = b43_radio_read(dev,
2965 + R2057_TX0_LOFT_COARSE_Q);
2966 + txcal_radio_regs[2] = b43_radio_read(dev,
2967 + R2057_TX1_LOFT_FINE_I);
2968 + txcal_radio_regs[3] = b43_radio_read(dev,
2969 + R2057_TX1_LOFT_FINE_Q);
2970 + txcal_radio_regs[6] = b43_radio_read(dev,
2971 + R2057_TX1_LOFT_COARSE_I);
2972 + txcal_radio_regs[7] = b43_radio_read(dev,
2973 + R2057_TX1_LOFT_COARSE_Q);
2974 + } else if (phy->rev >= 3) {
2975 txcal_radio_regs[0] = b43_radio_read(dev, 0x2021);
2976 txcal_radio_regs[1] = b43_radio_read(dev, 0x2022);
2977 txcal_radio_regs[2] = b43_radio_read(dev, 0x3021);
2978 @@ -4504,8 +5269,9 @@ static void b43_nphy_save_cal(struct b43
2979 txcal_radio_regs[2] = b43_radio_read(dev, 0x8D);
2980 txcal_radio_regs[3] = b43_radio_read(dev, 0xBC);
2982 - iqcal_chanspec->center_freq = dev->phy.channel_freq;
2983 - iqcal_chanspec->channel_type = dev->phy.channel_type;
2984 + iqcal_chanspec->center_freq = dev->phy.chandef->chan->center_freq;
2985 + iqcal_chanspec->channel_type =
2986 + cfg80211_get_chandef_type(dev->phy.chandef);
2987 b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 8, table);
2989 if (nphy->hang_avoid)
2990 @@ -4515,6 +5281,7 @@ static void b43_nphy_save_cal(struct b43
2991 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RestoreCal */
2992 static void b43_nphy_restore_cal(struct b43_wldev *dev)
2994 + struct b43_phy *phy = &dev->phy;
2995 struct b43_phy_n *nphy = dev->phy.n;
2998 @@ -4562,7 +5329,26 @@ static void b43_nphy_restore_cal(struct
3001 /* TODO use some definitions */
3002 - if (dev->phy.rev >= 3) {
3003 + if (phy->rev >= 19) {
3005 + } else if (phy->rev >= 7) {
3006 + b43_radio_write(dev, R2057_TX0_LOFT_FINE_I,
3007 + txcal_radio_regs[0]);
3008 + b43_radio_write(dev, R2057_TX0_LOFT_FINE_Q,
3009 + txcal_radio_regs[1]);
3010 + b43_radio_write(dev, R2057_TX0_LOFT_COARSE_I,
3011 + txcal_radio_regs[4]);
3012 + b43_radio_write(dev, R2057_TX0_LOFT_COARSE_Q,
3013 + txcal_radio_regs[5]);
3014 + b43_radio_write(dev, R2057_TX1_LOFT_FINE_I,
3015 + txcal_radio_regs[2]);
3016 + b43_radio_write(dev, R2057_TX1_LOFT_FINE_Q,
3017 + txcal_radio_regs[3]);
3018 + b43_radio_write(dev, R2057_TX1_LOFT_COARSE_I,
3019 + txcal_radio_regs[6]);
3020 + b43_radio_write(dev, R2057_TX1_LOFT_COARSE_Q,
3021 + txcal_radio_regs[7]);
3022 + } else if (phy->rev >= 3) {
3023 b43_radio_write(dev, 0x2021, txcal_radio_regs[0]);
3024 b43_radio_write(dev, 0x2022, txcal_radio_regs[1]);
3025 b43_radio_write(dev, 0x3021, txcal_radio_regs[2]);
3026 @@ -4585,6 +5371,7 @@ static int b43_nphy_cal_tx_iq_lo(struct
3027 struct nphy_txgains target,
3028 bool full, bool mphase)
3030 + struct b43_phy *phy = &dev->phy;
3031 struct b43_phy_n *nphy = dev->phy.n;
3034 @@ -4625,7 +5412,7 @@ static int b43_nphy_cal_tx_iq_lo(struct
3035 (dev->phy.rev == 5 && nphy->ipa2g_on &&
3036 b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ);
3038 - if (dev->phy.is_40mhz) {
3039 + if (b43_is_40mhz(dev)) {
3040 b43_ntab_write_bulk(dev, B43_NTAB16(15, 0), 18,
3041 tbl_tx_iqlo_cal_loft_ladder_40);
3042 b43_ntab_write_bulk(dev, B43_NTAB16(15, 32), 18,
3043 @@ -4638,18 +5425,24 @@ static int b43_nphy_cal_tx_iq_lo(struct
3047 - b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8AA9);
3048 + if (phy->rev >= 19) {
3050 + } else if (phy->rev >= 7) {
3051 + b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8AD9);
3053 + b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8AA9);
3056 - if (!dev->phy.is_40mhz)
3057 + if (!b43_is_40mhz(dev))
3062 if (nphy->mphase_cal_phase_id > 2)
3063 - b43_nphy_run_samples(dev, (dev->phy.is_40mhz ? 40 : 20) * 8,
3064 - 0xFFFF, 0, true, false);
3065 + b43_nphy_run_samples(dev, (b43_is_40mhz(dev) ? 40 : 20) * 8,
3066 + 0xFFFF, 0, true, false, false);
3068 - error = b43_nphy_tx_tone(dev, freq, 250, true, false);
3069 + error = b43_nphy_tx_tone(dev, freq, 250, true, false, false);
3072 if (nphy->mphase_cal_phase_id > 2) {
3073 @@ -4777,9 +5570,9 @@ static int b43_nphy_cal_tx_iq_lo(struct
3074 nphy->txiqlocal_bestc);
3075 nphy->txiqlocal_coeffsvalid = true;
3076 nphy->txiqlocal_chanspec.center_freq =
3077 - dev->phy.channel_freq;
3078 + phy->chandef->chan->center_freq;
3079 nphy->txiqlocal_chanspec.channel_type =
3080 - dev->phy.channel_type;
3081 + cfg80211_get_chandef_type(phy->chandef);
3084 if (dev->phy.rev < 3)
3085 @@ -4815,8 +5608,8 @@ static void b43_nphy_reapply_tx_cal_coef
3088 if (!nphy->txiqlocal_coeffsvalid ||
3089 - nphy->txiqlocal_chanspec.center_freq != dev->phy.channel_freq ||
3090 - nphy->txiqlocal_chanspec.channel_type != dev->phy.channel_type)
3091 + nphy->txiqlocal_chanspec.center_freq != dev->phy.chandef->chan->center_freq ||
3092 + nphy->txiqlocal_chanspec.channel_type != cfg80211_get_chandef_type(dev->phy.chandef))
3095 b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer);
3096 @@ -4972,11 +5765,11 @@ static int b43_nphy_rev2_cal_rx_iq(struc
3098 ret = b43_nphy_tx_tone(dev, 4000,
3099 (nphy->rxcalparams & 0xFFFF),
3101 + false, false, true);
3104 - b43_nphy_run_samples(dev, 160, 0xFFFF, 0,
3106 + b43_nphy_run_samples(dev, 160, 0xFFFF, 0, false,
3111 @@ -5032,6 +5825,9 @@ static int b43_nphy_rev3_cal_rx_iq(struc
3112 static int b43_nphy_cal_rx_iq(struct b43_wldev *dev,
3113 struct nphy_txgains target, u8 type, bool debug)
3115 + if (dev->phy.rev >= 7)
3118 if (dev->phy.rev >= 3)
3119 return b43_nphy_rev3_cal_rx_iq(dev, target, type, debug);
3121 @@ -5118,6 +5914,9 @@ static void b43_nphy_bphy_init(struct b4
3122 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SuperSwitchInit */
3123 static void b43_nphy_superswitch_init(struct b43_wldev *dev, bool init)
3125 + if (dev->phy.rev >= 7)
3128 if (dev->phy.rev >= 3) {
3131 @@ -5193,6 +5992,10 @@ static int b43_phy_initn(struct b43_wlde
3135 + nphy->use_int_tx_iq_lo_cal = b43_nphy_ipa(dev) ||
3138 + sprom->boardflags2_hi & B43_BFH2_INTERNDET_TXIQCAL);
3139 nphy->deaf_count = 0;
3140 b43_nphy_tables_init(dev);
3141 nphy->crsminpwr_adjusted = false;
3142 @@ -5202,6 +6005,16 @@ static int b43_phy_initn(struct b43_wlde
3143 if (dev->phy.rev >= 3) {
3144 b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S1, 0);
3145 b43_phy_write(dev, B43_NPHY_RFCTL_OVER, 0);
3146 + if (phy->rev >= 7) {
3147 + b43_phy_write(dev, B43_NPHY_REV7_RF_CTL_OVER3, 0);
3148 + b43_phy_write(dev, B43_NPHY_REV7_RF_CTL_OVER4, 0);
3149 + b43_phy_write(dev, B43_NPHY_REV7_RF_CTL_OVER5, 0);
3150 + b43_phy_write(dev, B43_NPHY_REV7_RF_CTL_OVER6, 0);
3152 + if (phy->rev >= 19) {
3156 b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S0, 0);
3157 b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S1, 0);
3159 @@ -5239,7 +6052,9 @@ static int b43_phy_initn(struct b43_wlde
3160 b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x50);
3161 b43_phy_write(dev, B43_NPHY_TXRIFS_FRDEL, 0x30);
3163 - b43_nphy_update_mimo_config(dev, nphy->preamble_override);
3165 + b43_nphy_update_mimo_config(dev, nphy->preamble_override);
3167 b43_nphy_update_txrx_chain(dev);
3170 @@ -5271,10 +6086,12 @@ static int b43_phy_initn(struct b43_wlde
3172 b43_mac_phy_clock_set(dev, true);
3174 - b43_nphy_pa_override(dev, false);
3175 - b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX);
3176 - b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
3177 - b43_nphy_pa_override(dev, true);
3178 + if (phy->rev < 7) {
3179 + b43_nphy_pa_override(dev, false);
3180 + b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX);
3181 + b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
3182 + b43_nphy_pa_override(dev, true);
3185 b43_nphy_classifier(dev, 0, 0);
3186 b43_nphy_read_clip_detection(dev, clip);
3187 @@ -5348,7 +6165,7 @@ static int b43_phy_initn(struct b43_wlde
3188 b43_phy_write(dev, B43_NPHY_TXMACDELAY, 0x0320);
3189 if (phy->rev >= 3 && phy->rev <= 6)
3190 b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x0032);
3191 - b43_nphy_tx_lp_fbw(dev);
3192 + b43_nphy_tx_lpf_bw(dev);
3194 b43_nphy_spur_workaround(dev);
3196 @@ -5397,23 +6214,23 @@ static void b43_nphy_channel_setup(struc
3197 struct b43_phy *phy = &dev->phy;
3198 struct b43_phy_n *nphy = dev->phy.n;
3199 int ch = new_channel->hw_value;
3201 - u16 old_band_5ghz;
3205 - b43_phy_read(dev, B43_NPHY_BANDCTL) & B43_NPHY_BANDCTL_5GHZ;
3206 - if (new_channel->band == IEEE80211_BAND_5GHZ && !old_band_5ghz) {
3207 + if (new_channel->band == IEEE80211_BAND_5GHZ) {
3208 tmp16 = b43_read16(dev, B43_MMIO_PSM_PHY_HDR);
3209 b43_write16(dev, B43_MMIO_PSM_PHY_HDR, tmp16 | 4);
3210 - b43_phy_set(dev, B43_PHY_B_BBCFG, 0xC000);
3211 + /* Put BPHY in the reset */
3212 + b43_phy_set(dev, B43_PHY_B_BBCFG,
3213 + B43_PHY_B_BBCFG_RSTCCA | B43_PHY_B_BBCFG_RSTRX);
3214 b43_write16(dev, B43_MMIO_PSM_PHY_HDR, tmp16);
3215 b43_phy_set(dev, B43_NPHY_BANDCTL, B43_NPHY_BANDCTL_5GHZ);
3216 - } else if (new_channel->band == IEEE80211_BAND_2GHZ && old_band_5ghz) {
3217 + } else if (new_channel->band == IEEE80211_BAND_2GHZ) {
3218 b43_phy_mask(dev, B43_NPHY_BANDCTL, ~B43_NPHY_BANDCTL_5GHZ);
3219 tmp16 = b43_read16(dev, B43_MMIO_PSM_PHY_HDR);
3220 b43_write16(dev, B43_MMIO_PSM_PHY_HDR, tmp16 | 4);
3221 - b43_phy_mask(dev, B43_PHY_B_BBCFG, 0x3FFF);
3222 + /* Take BPHY out of the reset */
3223 + b43_phy_mask(dev, B43_PHY_B_BBCFG,
3224 + (u16)~(B43_PHY_B_BBCFG_RSTCCA | B43_PHY_B_BBCFG_RSTRX));
3225 b43_write16(dev, B43_MMIO_PSM_PHY_HDR, tmp16);
3228 @@ -5434,35 +6251,49 @@ static void b43_nphy_channel_setup(struc
3229 if (dev->phy.rev < 3)
3230 b43_nphy_adjust_lna_gain_table(dev);
3232 - b43_nphy_tx_lp_fbw(dev);
3233 + b43_nphy_tx_lpf_bw(dev);
3235 if (dev->phy.rev >= 3 &&
3236 dev->phy.n->spur_avoid != B43_SPUR_AVOID_DISABLE) {
3237 - bool avoid = false;
3240 if (dev->phy.n->spur_avoid == B43_SPUR_AVOID_FORCE) {
3242 - } else if (!b43_channel_type_is_40mhz(phy->channel_type)) {
3243 - if ((ch >= 5 && ch <= 8) || ch == 13 || ch == 14)
3245 - } else { /* 40MHz */
3246 - if (nphy->aband_spurwar_en &&
3247 - (ch == 38 || ch == 102 || ch == 118))
3248 - avoid = dev->dev->chip_id == 0x4716;
3251 - b43_nphy_pmu_spur_avoid(dev, avoid);
3253 - if (dev->dev->chip_id == 43222 || dev->dev->chip_id == 43224 ||
3254 - dev->dev->chip_id == 43225) {
3255 - b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW,
3256 - avoid ? 0x5341 : 0x8889);
3257 - b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
3259 + } else if (phy->rev >= 19) {
3261 + } else if (phy->rev >= 18) {
3263 + } else if (phy->rev >= 17) {
3264 + /* TODO: Off for channels 1-11, but check 12-14! */
3265 + } else if (phy->rev >= 16) {
3266 + /* TODO: Off for 2 GHz, but check 5 GHz! */
3267 + } else if (phy->rev >= 7) {
3268 + if (!b43_is_40mhz(dev)) { /* 20MHz */
3269 + if (ch == 13 || ch == 14 || ch == 153)
3271 + } else { /* 40 MHz */
3276 + if (!b43_is_40mhz(dev)) { /* 20MHz */
3277 + if ((ch >= 5 && ch <= 8) || ch == 13 || ch == 14)
3279 + } else { /* 40MHz */
3280 + if (nphy->aband_spurwar_en &&
3281 + (ch == 38 || ch == 102 || ch == 118))
3282 + spuravoid = dev->dev->chip_id == 0x4716;
3286 + b43_nphy_pmu_spur_avoid(dev, spuravoid);
3288 + b43_mac_switch_freq(dev, spuravoid);
3290 if (dev->phy.rev == 3 || dev->phy.rev == 4)
3291 ; /* TODO: reset PLL */
3295 b43_phy_set(dev, B43_NPHY_BBCFG, B43_NPHY_BBCFG_RSTRX);
3297 b43_phy_mask(dev, B43_NPHY_BBCFG,
3298 @@ -5488,10 +6319,20 @@ static int b43_nphy_set_channel(struct b
3300 const struct b43_nphy_channeltab_entry_rev2 *tabent_r2 = NULL;
3301 const struct b43_nphy_channeltab_entry_rev3 *tabent_r3 = NULL;
3302 + const struct b43_nphy_chantabent_rev7 *tabent_r7 = NULL;
3303 + const struct b43_nphy_chantabent_rev7_2g *tabent_r7_2g = NULL;
3307 - if (dev->phy.rev >= 3) {
3308 + if (phy->rev >= 19) {
3311 + } else if (phy->rev >= 7) {
3312 + r2057_get_chantabent_rev7(dev, channel->center_freq,
3313 + &tabent_r7, &tabent_r7_2g);
3314 + if (!tabent_r7 && !tabent_r7_2g)
3316 + } else if (phy->rev >= 3) {
3317 tabent_r3 = b43_nphy_get_chantabent_rev3(dev,
3318 channel->center_freq);
3320 @@ -5506,20 +6347,38 @@ static int b43_nphy_set_channel(struct b
3321 /* Channel is set later in common code, but we need to set it on our
3322 own to let this function's subcalls work properly. */
3323 phy->channel = channel->hw_value;
3324 - phy->channel_freq = channel->center_freq;
3327 if (b43_channel_type_is_40mhz(phy->channel_type) !=
3328 b43_channel_type_is_40mhz(channel_type))
3329 ; /* TODO: BMAC BW Set (channel_type) */
3332 - if (channel_type == NL80211_CHAN_HT40PLUS)
3333 - b43_phy_set(dev, B43_NPHY_RXCTL,
3334 - B43_NPHY_RXCTL_BSELU20);
3335 - else if (channel_type == NL80211_CHAN_HT40MINUS)
3336 - b43_phy_mask(dev, B43_NPHY_RXCTL,
3337 - ~B43_NPHY_RXCTL_BSELU20);
3338 + if (channel_type == NL80211_CHAN_HT40PLUS) {
3339 + b43_phy_set(dev, B43_NPHY_RXCTL, B43_NPHY_RXCTL_BSELU20);
3340 + if (phy->rev >= 7)
3341 + b43_phy_set(dev, 0x310, 0x8000);
3342 + } else if (channel_type == NL80211_CHAN_HT40MINUS) {
3343 + b43_phy_mask(dev, B43_NPHY_RXCTL, ~B43_NPHY_RXCTL_BSELU20);
3344 + if (phy->rev >= 7)
3345 + b43_phy_mask(dev, 0x310, (u16)~0x8000);
3348 - if (dev->phy.rev >= 3) {
3349 + if (phy->rev >= 19) {
3351 + } else if (phy->rev >= 7) {
3352 + const struct b43_phy_n_sfo_cfg *phy_regs = tabent_r7 ?
3353 + &(tabent_r7->phy_regs) : &(tabent_r7_2g->phy_regs);
3355 + if (phy->radio_rev <= 4 || phy->radio_rev == 6) {
3356 + tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 2 : 0;
3357 + b43_radio_maskset(dev, R2057_TIA_CONFIG_CORE0, ~2, tmp);
3358 + b43_radio_maskset(dev, R2057_TIA_CONFIG_CORE1, ~2, tmp);
3361 + b43_radio_2057_setup(dev, tabent_r7, tabent_r7_2g);
3362 + b43_nphy_channel_setup(dev, phy_regs, channel);
3363 + } else if (phy->rev >= 3) {
3364 tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 4 : 0;
3365 b43_radio_maskset(dev, 0x08, 0xFFFB, tmp);
3366 b43_radio_2056_setup(dev, tabent_r3);
3367 @@ -5561,7 +6420,6 @@ static void b43_nphy_op_prepare_structs(
3368 nphy->hang_avoid = (phy->rev == 3 || phy->rev == 4);
3369 nphy->spur_avoid = (phy->rev >= 3) ?
3370 B43_SPUR_AVOID_AUTO : B43_SPUR_AVOID_DISABLE;
3371 - nphy->init_por = true;
3372 nphy->gain_boost = true; /* this way we follow wl, assume it is true */
3373 nphy->txrx_chain = 2; /* sth different than 0 and 1 for now */
3374 nphy->phyrxchain = 3; /* to avoid b43_nphy_set_rx_core_state like wl */
3375 @@ -5602,8 +6460,6 @@ static void b43_nphy_op_prepare_structs(
3376 nphy->ipa2g_on = sprom->fem.ghz2.extpa_gain == 2;
3377 nphy->ipa5g_on = sprom->fem.ghz5.extpa_gain == 2;
3380 - nphy->init_por = true;
3383 static void b43_nphy_op_free(struct b43_wldev *dev)
3384 @@ -5663,7 +6519,7 @@ static void b43_nphy_op_maskset(struct b
3385 static u16 b43_nphy_op_radio_read(struct b43_wldev *dev, u16 reg)
3387 /* Register 1 is a 32-bit register. */
3388 - B43_WARN_ON(reg == 1);
3389 + B43_WARN_ON(dev->phy.rev < 7 && reg == 1);
3391 if (dev->phy.rev >= 7)
3392 reg |= 0x200; /* Radio 0x2057 */
3393 @@ -5677,7 +6533,7 @@ static u16 b43_nphy_op_radio_read(struct
3394 static void b43_nphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
3396 /* Register 1 is a 32-bit register. */
3397 - B43_WARN_ON(reg == 1);
3398 + B43_WARN_ON(dev->phy.rev < 7 && reg == 1);
3400 b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
3401 b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
3402 @@ -5687,15 +6543,23 @@ static void b43_nphy_op_radio_write(stru
3403 static void b43_nphy_op_software_rfkill(struct b43_wldev *dev,
3406 + struct b43_phy *phy = &dev->phy;
3408 if (b43_read32(dev, B43_MMIO_MACCTL) & B43_MACCTL_ENABLED)
3409 b43err(dev->wl, "MAC not suspended\n");
3412 - b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
3413 - ~B43_NPHY_RFCTL_CMD_CHIP0PU);
3414 - if (dev->phy.rev >= 7) {
3415 + if (phy->rev >= 19) {
3417 - } else if (dev->phy.rev >= 3) {
3418 + } else if (phy->rev >= 8) {
3419 + b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
3420 + ~B43_NPHY_RFCTL_CMD_CHIP0PU);
3421 + } else if (phy->rev >= 7) {
3422 + /* Nothing needed */
3423 + } else if (phy->rev >= 3) {
3424 + b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
3425 + ~B43_NPHY_RFCTL_CMD_CHIP0PU);
3427 b43_radio_mask(dev, 0x09, ~0x2);
3429 b43_radio_write(dev, 0x204D, 0);
3430 @@ -5713,11 +6577,15 @@ static void b43_nphy_op_software_rfkill(
3431 b43_radio_write(dev, 0x3064, 0);
3434 - if (dev->phy.rev >= 7) {
3435 - b43_radio_2057_init(dev);
3436 + if (phy->rev >= 19) {
3438 + } else if (phy->rev >= 7) {
3439 + if (!dev->phy.radio_on)
3440 + b43_radio_2057_init(dev);
3441 b43_switch_channel(dev, dev->phy.channel);
3442 - } else if (dev->phy.rev >= 3) {
3443 - b43_radio_init2056(dev);
3444 + } else if (phy->rev >= 3) {
3445 + if (!dev->phy.radio_on)
3446 + b43_radio_init2056(dev);
3447 b43_switch_channel(dev, dev->phy.channel);
3449 b43_radio_init2055(dev);
3450 @@ -5728,10 +6596,13 @@ static void b43_nphy_op_software_rfkill(
3451 /* http://bcm-v4.sipsolutions.net/802.11/PHY/Anacore */
3452 static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on)
3454 + struct b43_phy *phy = &dev->phy;
3455 u16 override = on ? 0x0 : 0x7FFF;
3456 u16 core = on ? 0xD : 0x00FD;
3458 - if (dev->phy.rev >= 3) {
3459 + if (phy->rev >= 19) {
3461 + } else if (phy->rev >= 3) {
3463 b43_phy_write(dev, B43_NPHY_AFECTL_C1, core);
3464 b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, override);
3465 --- a/drivers/net/wireless/b43/phy_n.h
3466 +++ b/drivers/net/wireless/b43/phy_n.h
3467 @@ -366,11 +366,13 @@
3468 #define B43_NPHY_TXF_40CO_B1S0 B43_PHY_N(0x0E5) /* TX filter 40 coeff B1 stage 0 */
3469 #define B43_NPHY_TXF_40CO_B32S1 B43_PHY_N(0x0E6) /* TX filter 40 coeff B32 stage 1 */
3470 #define B43_NPHY_TXF_40CO_B1S1 B43_PHY_N(0x0E7) /* TX filter 40 coeff B1 stage 1 */
3471 +#define B43_NPHY_REV3_RFCTL_OVER0 B43_PHY_N(0x0E7)
3472 #define B43_NPHY_TXF_40CO_B32S2 B43_PHY_N(0x0E8) /* TX filter 40 coeff B32 stage 2 */
3473 #define B43_NPHY_TXF_40CO_B1S2 B43_PHY_N(0x0E9) /* TX filter 40 coeff B1 stage 2 */
3474 #define B43_NPHY_BIST_STAT2 B43_PHY_N(0x0EA) /* BIST status 2 */
3475 #define B43_NPHY_BIST_STAT3 B43_PHY_N(0x0EB) /* BIST status 3 */
3476 #define B43_NPHY_RFCTL_OVER B43_PHY_N(0x0EC) /* RF control override */
3477 +#define B43_NPHY_REV3_RFCTL_OVER1 B43_PHY_N(0x0EC)
3478 #define B43_NPHY_MIMOCFG B43_PHY_N(0x0ED) /* MIMO config */
3479 #define B43_NPHY_MIMOCFG_GFMIX 0x0004 /* Greenfield or mixed mode */
3480 #define B43_NPHY_MIMOCFG_AUTO 0x0100 /* Greenfield/mixed mode auto */
3481 @@ -857,7 +859,18 @@
3482 #define B43_NPHY_REV3_C2_CLIP2_GAIN_A B43_PHY_N(0x2AF)
3483 #define B43_NPHY_REV3_C2_CLIP2_GAIN_B B43_PHY_N(0x2B0)
3485 +#define B43_NPHY_REV7_RF_CTL_MISC_REG3 B43_PHY_N(0x340)
3486 +#define B43_NPHY_REV7_RF_CTL_MISC_REG4 B43_PHY_N(0x341)
3487 +#define B43_NPHY_REV7_RF_CTL_OVER3 B43_PHY_N(0x342)
3488 +#define B43_NPHY_REV7_RF_CTL_OVER4 B43_PHY_N(0x343)
3489 +#define B43_NPHY_REV7_RF_CTL_MISC_REG5 B43_PHY_N(0x344)
3490 +#define B43_NPHY_REV7_RF_CTL_MISC_REG6 B43_PHY_N(0x345)
3491 +#define B43_NPHY_REV7_RF_CTL_OVER5 B43_PHY_N(0x346)
3492 +#define B43_NPHY_REV7_RF_CTL_OVER6 B43_PHY_N(0x347)
3494 #define B43_PHY_B_BBCFG B43_PHY_N_BMODE(0x001) /* BB config */
3495 +#define B43_PHY_B_BBCFG_RSTCCA 0x4000 /* Reset CCA */
3496 +#define B43_PHY_B_BBCFG_RSTRX 0x8000 /* Reset RX */
3497 #define B43_PHY_B_TEST B43_PHY_N_BMODE(0x00A)
3500 @@ -931,11 +944,12 @@ struct b43_phy_n {
3501 u16 papd_epsilon_offset[2];
3502 s32 preamble_override;
3507 bool elna_gain_config;
3508 bool band5g_pwrgain;
3509 + bool use_int_tx_iq_lo_cal;
3510 + bool lpf_bw_overrode_for_sample_play;
3512 u8 mphase_cal_phase_id;
3513 u16 mphase_txcal_cmdidx;
3514 --- a/drivers/net/wireless/b43/tables_nphy.c
3515 +++ b/drivers/net/wireless/b43/tables_nphy.c
3516 @@ -2146,7 +2146,196 @@ static const u16 b43_ntab_antswctl_r3[4]
3520 -/* TX gain tables */
3521 +/* static tables, PHY revision >= 7 */
3523 +/* Copied from brcmsmac (5.75.11) */
3524 +static const u32 b43_ntab_tmap_r7[] = {
3525 + 0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
3526 + 0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
3527 + 0xf1111110, 0x11111111, 0x11f11111, 0x00000111,
3528 + 0x11000000, 0x1111f111, 0x11111111, 0x111111f1,
3529 + 0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x000aa888,
3530 + 0x88880000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
3531 + 0xa1111110, 0x11111111, 0x11c11111, 0x00000111,
3532 + 0x11000000, 0x1111a111, 0x11111111, 0x111111a1,
3533 + 0xa2222220, 0x22222222, 0x22c22222, 0x00000222,
3534 + 0x22000000, 0x2222a222, 0x22222222, 0x222222a2,
3535 + 0xf1111110, 0x11111111, 0x11f11111, 0x00011111,
3536 + 0x11110000, 0x1111f111, 0x11111111, 0x111111f1,
3537 + 0xa8aa88a0, 0xa88888a8, 0xa8a8a88a, 0x00088aaa,
3538 + 0xaaaa0000, 0xa8a8aa88, 0xa88aaaaa, 0xaaaa8a8a,
3539 + 0xaaa8aaa0, 0x8aaa8aaa, 0xaa8a8a8a, 0x000aaa88,
3540 + 0x8aaa0000, 0xaaa8a888, 0x8aa88a8a, 0x8a88a888,
3541 + 0x08080a00, 0x0a08080a, 0x080a0a08, 0x00080808,
3542 + 0x080a0000, 0x080a0808, 0x080a0808, 0x0a0a0a08,
3543 + 0xa0a0a0a0, 0x80a0a080, 0x8080a0a0, 0x00008080,
3544 + 0x80a00000, 0x80a080a0, 0xa080a0a0, 0x8080a0a0,
3545 + 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3546 + 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3547 + 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3548 + 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3549 + 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3550 + 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3551 + 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3552 + 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3553 + 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3554 + 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3555 + 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3556 + 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3557 + 0x99999000, 0x9b9b99bb, 0x9bb99999, 0x9999b9b9,
3558 + 0x9b99bb90, 0x9bbbbb9b, 0x9b9b9bb9, 0x00000999,
3559 + 0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
3560 + 0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00aaa888,
3561 + 0x22000000, 0x2222b222, 0x22222222, 0x222222b2,
3562 + 0xb2222220, 0x22222222, 0x22d22222, 0x00000222,
3563 + 0x11000000, 0x1111a111, 0x11111111, 0x111111a1,
3564 + 0xa1111110, 0x11111111, 0x11c11111, 0x00000111,
3565 + 0x33000000, 0x3333b333, 0x33333333, 0x333333b3,
3566 + 0xb3333330, 0x33333333, 0x33d33333, 0x00000333,
3567 + 0x22000000, 0x2222a222, 0x22222222, 0x222222a2,
3568 + 0xa2222220, 0x22222222, 0x22c22222, 0x00000222,
3569 + 0x99b99b00, 0x9b9b99bb, 0x9bb99999, 0x9999b9b9,
3570 + 0x9b99bb99, 0x9bbbbb9b, 0x9b9b9bb9, 0x00000999,
3571 + 0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
3572 + 0x8a88aa88, 0x8aaaaa8a, 0x8a8a8aa8, 0x08aaa888,
3573 + 0x22222200, 0x2222f222, 0x22222222, 0x222222f2,
3574 + 0x22222222, 0x22222222, 0x22f22222, 0x00000222,
3575 + 0x11000000, 0x1111f111, 0x11111111, 0x11111111,
3576 + 0xf1111111, 0x11111111, 0x11f11111, 0x01111111,
3577 + 0xbb9bb900, 0xb9b9bb99, 0xb99bbbbb, 0xbbbb9b9b,
3578 + 0xb9bb99bb, 0xb99999b9, 0xb9b9b99b, 0x00000bbb,
3579 + 0xaa000000, 0xa8a8aa88, 0xa88aaaaa, 0xaaaa8a8a,
3580 + 0xa8aa88aa, 0xa88888a8, 0xa8a8a88a, 0x0a888aaa,
3581 + 0xaa000000, 0xa8a8aa88, 0xa88aaaaa, 0xaaaa8a8a,
3582 + 0xa8aa88a0, 0xa88888a8, 0xa8a8a88a, 0x00000aaa,
3583 + 0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
3584 + 0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
3585 + 0xbbbbbb00, 0x999bbbbb, 0x9bb99b9b, 0xb9b9b9bb,
3586 + 0xb9b99bbb, 0xb9b9b9bb, 0xb9bb9b99, 0x00000999,
3587 + 0x8a000000, 0xaa88a888, 0xa88888aa, 0xa88a8a88,
3588 + 0xa88aa88a, 0x88a8aaaa, 0xa8aa8aaa, 0x0888a88a,
3589 + 0x0b0b0b00, 0x090b0b0b, 0x0b090b0b, 0x0909090b,
3590 + 0x09090b0b, 0x09090b0b, 0x09090b09, 0x00000909,
3591 + 0x0a000000, 0x0a080808, 0x080a080a, 0x080a0a08,
3592 + 0x080a080a, 0x0808080a, 0x0a0a0a08, 0x0808080a,
3593 + 0xb0b0b000, 0x9090b0b0, 0x90b09090, 0xb0b0b090,
3594 + 0xb0b090b0, 0x90b0b0b0, 0xb0b09090, 0x00000090,
3595 + 0x80000000, 0xa080a080, 0xa08080a0, 0xa0808080,
3596 + 0xa080a080, 0x80a0a0a0, 0xa0a080a0, 0x00a0a0a0,
3597 + 0x22000000, 0x2222f222, 0x22222222, 0x222222f2,
3598 + 0xf2222220, 0x22222222, 0x22f22222, 0x00000222,
3599 + 0x11000000, 0x1111f111, 0x11111111, 0x111111f1,
3600 + 0xf1111110, 0x11111111, 0x11f11111, 0x00000111,
3601 + 0x33000000, 0x3333f333, 0x33333333, 0x333333f3,
3602 + 0xf3333330, 0x33333333, 0x33f33333, 0x00000333,
3603 + 0x22000000, 0x2222f222, 0x22222222, 0x222222f2,
3604 + 0xf2222220, 0x22222222, 0x22f22222, 0x00000222,
3605 + 0x99000000, 0x9b9b99bb, 0x9bb99999, 0x9999b9b9,
3606 + 0x9b99bb90, 0x9bbbbb9b, 0x9b9b9bb9, 0x00000999,
3607 + 0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
3608 + 0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
3609 + 0x88888000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
3610 + 0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
3611 + 0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
3612 + 0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00aaa888,
3613 + 0x88a88a00, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
3614 + 0x8a88aa88, 0x8aaaaa8a, 0x8a8a8aa8, 0x000aa888,
3615 + 0x88880000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
3616 + 0x8a88aa88, 0x8aaaaa8a, 0x8a8a8aa8, 0x08aaa888,
3617 + 0x11000000, 0x1111a111, 0x11111111, 0x111111a1,
3618 + 0xa1111110, 0x11111111, 0x11c11111, 0x00000111,
3619 + 0x11000000, 0x1111a111, 0x11111111, 0x111111a1,
3620 + 0xa1111110, 0x11111111, 0x11c11111, 0x00000111,
3621 + 0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
3622 + 0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
3623 + 0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
3624 + 0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
3625 + 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3626 + 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3627 + 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3628 + 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3629 + 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3630 + 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3631 + 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3632 + 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3633 + 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3634 + 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3635 + 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3636 + 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3639 +/* Extracted from MMIO dump of 6.30.223.141 */
3640 +static const u32 b43_ntab_noisevar_r7[] = {
3641 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3642 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3643 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3644 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3645 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3646 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3647 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3648 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3649 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3650 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3651 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3652 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3653 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3654 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3655 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3656 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3657 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3658 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3659 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3660 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3661 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3662 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3663 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3664 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3665 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3666 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3667 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3668 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3669 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3670 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3671 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3672 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3673 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3674 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3675 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3676 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3677 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3678 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3679 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3680 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3681 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3682 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3683 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3684 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3685 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3686 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3687 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3688 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3689 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3690 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3691 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3692 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3693 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3694 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3695 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3696 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3697 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3698 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3699 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3700 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3701 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3702 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3703 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3704 + 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3707 +/**************************************************
3709 + **************************************************/
3711 static const u32 b43_ntab_tx_gain_rev0_1_2[] = {
3712 0x03cc2b44, 0x03cc2b42, 0x03cc2a44, 0x03cc2a42,
3713 0x03cc2944, 0x03c82b44, 0x03c82b42, 0x03c82a44,
3714 @@ -2182,7 +2371,9 @@ static const u32 b43_ntab_tx_gain_rev0_1
3715 0x03801442, 0x03801344, 0x03801342, 0x00002b00,
3718 -static const u32 b43_ntab_tx_gain_rev3plus_2ghz[] = {
3721 +static const u32 b43_ntab_tx_gain_epa_rev3_2g[] = {
3722 0x1f410044, 0x1f410042, 0x1f410040, 0x1f41003e,
3723 0x1f41003c, 0x1f41003b, 0x1f410039, 0x1f410037,
3724 0x1e410044, 0x1e410042, 0x1e410040, 0x1e41003e,
3725 @@ -2217,7 +2408,44 @@ static const u32 b43_ntab_tx_gain_rev3pl
3726 0x1041003c, 0x1041003b, 0x10410039, 0x10410037,
3729 -static const u32 b43_ntab_tx_gain_rev3_5ghz[] = {
3730 +static const u32 b43_ntab_tx_gain_epa_rev3_hi_pwr_2g[] = {
3731 + 0x0f410044, 0x0f410042, 0x0f410040, 0x0f41003e,
3732 + 0x0f41003c, 0x0f41003b, 0x0f410039, 0x0f410037,
3733 + 0x0e410044, 0x0e410042, 0x0e410040, 0x0e41003e,
3734 + 0x0e41003c, 0x0e41003b, 0x0e410039, 0x0e410037,
3735 + 0x0d410044, 0x0d410042, 0x0d410040, 0x0d41003e,
3736 + 0x0d41003c, 0x0d41003b, 0x0d410039, 0x0d410037,
3737 + 0x0c410044, 0x0c410042, 0x0c410040, 0x0c41003e,
3738 + 0x0c41003c, 0x0c41003b, 0x0c410039, 0x0c410037,
3739 + 0x0b410044, 0x0b410042, 0x0b410040, 0x0b41003e,
3740 + 0x0b41003c, 0x0b41003b, 0x0b410039, 0x0b410037,
3741 + 0x0a410044, 0x0a410042, 0x0a410040, 0x0a41003e,
3742 + 0x0a41003c, 0x0a41003b, 0x0a410039, 0x0a410037,
3743 + 0x09410044, 0x09410042, 0x09410040, 0x0941003e,
3744 + 0x0941003c, 0x0941003b, 0x09410039, 0x09410037,
3745 + 0x08410044, 0x08410042, 0x08410040, 0x0841003e,
3746 + 0x0841003c, 0x0841003b, 0x08410039, 0x08410037,
3747 + 0x07410044, 0x07410042, 0x07410040, 0x0741003e,
3748 + 0x0741003c, 0x0741003b, 0x07410039, 0x07410037,
3749 + 0x06410044, 0x06410042, 0x06410040, 0x0641003e,
3750 + 0x0641003c, 0x0641003b, 0x06410039, 0x06410037,
3751 + 0x05410044, 0x05410042, 0x05410040, 0x0541003e,
3752 + 0x0541003c, 0x0541003b, 0x05410039, 0x05410037,
3753 + 0x04410044, 0x04410042, 0x04410040, 0x0441003e,
3754 + 0x0441003c, 0x0441003b, 0x04410039, 0x04410037,
3755 + 0x03410044, 0x03410042, 0x03410040, 0x0341003e,
3756 + 0x0341003c, 0x0341003b, 0x03410039, 0x03410037,
3757 + 0x02410044, 0x02410042, 0x02410040, 0x0241003e,
3758 + 0x0241003c, 0x0241003b, 0x02410039, 0x02410037,
3759 + 0x01410044, 0x01410042, 0x01410040, 0x0141003e,
3760 + 0x0141003c, 0x0141003b, 0x01410039, 0x01410037,
3761 + 0x00410044, 0x00410042, 0x00410040, 0x0041003e,
3762 + 0x0041003c, 0x0041003b, 0x00410039, 0x00410037
3767 +static const u32 b43_ntab_tx_gain_epa_rev3_5g[] = {
3768 0xcff70044, 0xcff70042, 0xcff70040, 0xcff7003e,
3769 0xcff7003c, 0xcff7003b, 0xcff70039, 0xcff70037,
3770 0xcef70044, 0xcef70042, 0xcef70040, 0xcef7003e,
3771 @@ -2252,7 +2480,7 @@ static const u32 b43_ntab_tx_gain_rev3_5
3772 0xc0f7003c, 0xc0f7003b, 0xc0f70039, 0xc0f70037,
3775 -static const u32 b43_ntab_tx_gain_rev4_5ghz[] = {
3776 +static const u32 b43_ntab_tx_gain_epa_rev4_5g[] = {
3777 0x2ff20044, 0x2ff20042, 0x2ff20040, 0x2ff2003e,
3778 0x2ff2003c, 0x2ff2003b, 0x2ff20039, 0x2ff20037,
3779 0x2ef20044, 0x2ef20042, 0x2ef20040, 0x2ef2003e,
3780 @@ -2287,7 +2515,42 @@ static const u32 b43_ntab_tx_gain_rev4_5
3781 0x20d2003a, 0x20d20038, 0x20d20036, 0x20d20034,
3784 -static const u32 b43_ntab_tx_gain_rev5plus_5ghz[] = {
3785 +static const u32 b43_ntab_tx_gain_epa_rev4_hi_pwr_5g[] = {
3786 + 0x2ff10044, 0x2ff10042, 0x2ff10040, 0x2ff1003e,
3787 + 0x2ff1003c, 0x2ff1003b, 0x2ff10039, 0x2ff10037,
3788 + 0x2ef10044, 0x2ef10042, 0x2ef10040, 0x2ef1003e,
3789 + 0x2ef1003c, 0x2ef1003b, 0x2ef10039, 0x2ef10037,
3790 + 0x2df10044, 0x2df10042, 0x2df10040, 0x2df1003e,
3791 + 0x2df1003c, 0x2df1003b, 0x2df10039, 0x2df10037,
3792 + 0x2cf10044, 0x2cf10042, 0x2cf10040, 0x2cf1003e,
3793 + 0x2cf1003c, 0x2cf1003b, 0x2cf10039, 0x2cf10037,
3794 + 0x2bf10044, 0x2bf10042, 0x2bf10040, 0x2bf1003e,
3795 + 0x2bf1003c, 0x2bf1003b, 0x2bf10039, 0x2bf10037,
3796 + 0x2af10044, 0x2af10042, 0x2af10040, 0x2af1003e,
3797 + 0x2af1003c, 0x2af1003b, 0x2af10039, 0x2af10037,
3798 + 0x29f10044, 0x29f10042, 0x29f10040, 0x29f1003e,
3799 + 0x29f1003c, 0x29f1003b, 0x29f10039, 0x29f10037,
3800 + 0x28f10044, 0x28f10042, 0x28f10040, 0x28f1003e,
3801 + 0x28f1003c, 0x28f1003b, 0x28f10039, 0x28f10037,
3802 + 0x27f10044, 0x27f10042, 0x27f10040, 0x27f1003e,
3803 + 0x27f1003c, 0x27f1003b, 0x27f10039, 0x27f10037,
3804 + 0x26f10044, 0x26f10042, 0x26f10040, 0x26f1003e,
3805 + 0x26f1003c, 0x26f1003b, 0x26f10039, 0x26f10037,
3806 + 0x25f10044, 0x25f10042, 0x25f10040, 0x25f1003e,
3807 + 0x25f1003c, 0x25f1003b, 0x25f10039, 0x25f10037,
3808 + 0x24f10044, 0x24f10042, 0x24f10040, 0x24f1003e,
3809 + 0x24f1003c, 0x24f1003b, 0x24f10039, 0x24f10038,
3810 + 0x23f10041, 0x23f10040, 0x23f1003f, 0x23f1003e,
3811 + 0x23f1003c, 0x23f1003b, 0x23f10039, 0x23f10037,
3812 + 0x22f10044, 0x22f10042, 0x22f10040, 0x22f1003e,
3813 + 0x22f1003c, 0x22f1003b, 0x22f10039, 0x22f10037,
3814 + 0x21f10044, 0x21f10042, 0x21f10040, 0x21f1003e,
3815 + 0x21f1003c, 0x21f1003b, 0x21f10039, 0x21f10037,
3816 + 0x20d10043, 0x20d10041, 0x20d1003e, 0x20d1003c,
3817 + 0x20d1003a, 0x20d10038, 0x20d10036, 0x20d10034
3820 +static const u32 b43_ntab_tx_gain_epa_rev5_5g[] = {
3821 0x0f62004a, 0x0f620048, 0x0f620046, 0x0f620044,
3822 0x0f620042, 0x0f620040, 0x0f62003e, 0x0f62003c,
3823 0x0e620044, 0x0e620042, 0x0e620040, 0x0e62003e,
3824 @@ -2322,7 +2585,9 @@ static const u32 b43_ntab_tx_gain_rev5pl
3825 0x0062003b, 0x00620039, 0x00620037, 0x00620035,
3828 -static const u32 txpwrctrl_tx_gain_ipa[] = {
3831 +static const u32 b43_ntab_tx_gain_ipa_rev3_2g[] = {
3832 0x5ff7002d, 0x5ff7002b, 0x5ff7002a, 0x5ff70029,
3833 0x5ff70028, 0x5ff70027, 0x5ff70026, 0x5ff70025,
3834 0x5ef7002d, 0x5ef7002b, 0x5ef7002a, 0x5ef70029,
3835 @@ -2357,7 +2622,7 @@ static const u32 txpwrctrl_tx_gain_ipa[]
3836 0x50f70028, 0x50f70027, 0x50f70026, 0x50f70025,
3839 -static const u32 txpwrctrl_tx_gain_ipa_rev5[] = {
3840 +static const u32 b43_ntab_tx_gain_ipa_rev5_2g[] = {
3841 0x1ff7002d, 0x1ff7002b, 0x1ff7002a, 0x1ff70029,
3842 0x1ff70028, 0x1ff70027, 0x1ff70026, 0x1ff70025,
3843 0x1ef7002d, 0x1ef7002b, 0x1ef7002a, 0x1ef70029,
3844 @@ -2392,7 +2657,7 @@ static const u32 txpwrctrl_tx_gain_ipa_r
3845 0x10f70028, 0x10f70027, 0x10f70026, 0x10f70025,
3848 -static const u32 txpwrctrl_tx_gain_ipa_rev6[] = {
3849 +static const u32 b43_ntab_tx_gain_ipa_rev6_2g[] = {
3850 0x0ff7002d, 0x0ff7002b, 0x0ff7002a, 0x0ff70029,
3851 0x0ff70028, 0x0ff70027, 0x0ff70026, 0x0ff70025,
3852 0x0ef7002d, 0x0ef7002b, 0x0ef7002a, 0x0ef70029,
3853 @@ -2427,7 +2692,117 @@ static const u32 txpwrctrl_tx_gain_ipa_r
3854 0x00f70028, 0x00f70027, 0x00f70026, 0x00f70025,
3857 -static const u32 txpwrctrl_tx_gain_ipa_5g[] = {
3858 +/* Copied from brcmsmac (5.75.11): nphy_tpc_txgain_ipa_2g_2057rev5 */
3859 +static const u32 b43_ntab_tx_gain_ipa_2057_rev5_2g[] = {
3860 + 0x30ff0031, 0x30e70031, 0x30e7002e, 0x30cf002e,
3861 + 0x30bf002e, 0x30af002e, 0x309f002f, 0x307f0033,
3862 + 0x307f0031, 0x307f002e, 0x3077002e, 0x306f002e,
3863 + 0x3067002e, 0x305f002f, 0x30570030, 0x3057002d,
3864 + 0x304f002e, 0x30470031, 0x3047002e, 0x3047002c,
3865 + 0x30470029, 0x303f002c, 0x303f0029, 0x3037002d,
3866 + 0x3037002a, 0x30370028, 0x302f002c, 0x302f002a,
3867 + 0x302f0028, 0x302f0026, 0x3027002c, 0x30270029,
3868 + 0x30270027, 0x30270025, 0x30270023, 0x301f002c,
3869 + 0x301f002a, 0x301f0028, 0x301f0025, 0x301f0024,
3870 + 0x301f0022, 0x301f001f, 0x3017002d, 0x3017002b,
3871 + 0x30170028, 0x30170026, 0x30170024, 0x30170022,
3872 + 0x30170020, 0x3017001e, 0x3017001d, 0x3017001b,
3873 + 0x3017001a, 0x30170018, 0x30170017, 0x30170015,
3874 + 0x300f002c, 0x300f0029, 0x300f0027, 0x300f0024,
3875 + 0x300f0022, 0x300f0021, 0x300f001f, 0x300f001d,
3876 + 0x300f001b, 0x300f001a, 0x300f0018, 0x300f0017,
3877 + 0x300f0016, 0x300f0015, 0x300f0115, 0x300f0215,
3878 + 0x300f0315, 0x300f0415, 0x300f0515, 0x300f0615,
3879 + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3880 + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3881 + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3882 + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3883 + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3884 + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3885 + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3886 + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3887 + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3888 + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3889 + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3890 + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3891 + 0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3894 +/* Extracted from MMIO dump of 6.30.223.141 */
3895 +static const u32 b43_ntab_tx_gain_ipa_2057_rev9_2g[] = {
3896 + 0x60ff0031, 0x60e7002c, 0x60cf002a, 0x60c70029,
3897 + 0x60b70029, 0x60a70029, 0x609f002a, 0x6097002b,
3898 + 0x6087002e, 0x60770031, 0x606f0032, 0x60670034,
3899 + 0x60670031, 0x605f0033, 0x605f0031, 0x60570033,
3900 + 0x60570030, 0x6057002d, 0x6057002b, 0x604f002d,
3901 + 0x604f002b, 0x604f0029, 0x604f0026, 0x60470029,
3902 + 0x60470027, 0x603f0029, 0x603f0027, 0x603f0025,
3903 + 0x60370029, 0x60370027, 0x60370024, 0x602f002a,
3904 + 0x602f0028, 0x602f0026, 0x602f0024, 0x6027002a,
3905 + 0x60270028, 0x60270026, 0x60270024, 0x60270022,
3906 + 0x601f002b, 0x601f0029, 0x601f0027, 0x601f0024,
3907 + 0x601f0022, 0x601f0020, 0x601f001f, 0x601f001d,
3908 + 0x60170029, 0x60170027, 0x60170025, 0x60170023,
3909 + 0x60170021, 0x6017001f, 0x6017001d, 0x6017001c,
3910 + 0x6017001a, 0x60170018, 0x60170018, 0x60170016,
3911 + 0x60170015, 0x600f0029, 0x600f0027, 0x600f0025,
3912 + 0x600f0023, 0x600f0021, 0x600f001f, 0x600f001d,
3913 + 0x600f001c, 0x600f001a, 0x600f0019, 0x600f0018,
3914 + 0x600f0016, 0x600f0015, 0x600f0115, 0x600f0215,
3915 + 0x600f0315, 0x600f0415, 0x600f0515, 0x600f0615,
3916 + 0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
3917 + 0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
3918 + 0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
3919 + 0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
3920 + 0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
3921 + 0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
3922 + 0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
3923 + 0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
3924 + 0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
3925 + 0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
3926 + 0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
3927 + 0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
3930 +/* Extracted from MMIO dump of 6.30.223.248 */
3931 +static const u32 b43_ntab_tx_gain_ipa_2057_rev14_2g[] = {
3932 + 0x50df002e, 0x50cf002d, 0x50bf002c, 0x50b7002b,
3933 + 0x50af002a, 0x50a70029, 0x509f0029, 0x50970028,
3934 + 0x508f0027, 0x50870027, 0x507f0027, 0x50770027,
3935 + 0x506f0027, 0x50670027, 0x505f0028, 0x50570029,
3936 + 0x504f002b, 0x5047002e, 0x5047002b, 0x50470029,
3937 + 0x503f002c, 0x503f0029, 0x5037002c, 0x5037002a,
3938 + 0x50370028, 0x502f002d, 0x502f002b, 0x502f0028,
3939 + 0x502f0026, 0x5027002d, 0x5027002a, 0x50270028,
3940 + 0x50270026, 0x50270024, 0x501f002e, 0x501f002b,
3941 + 0x501f0029, 0x501f0027, 0x501f0024, 0x501f0022,
3942 + 0x501f0020, 0x501f001f, 0x5017002c, 0x50170029,
3943 + 0x50170027, 0x50170024, 0x50170022, 0x50170021,
3944 + 0x5017001f, 0x5017001d, 0x5017001b, 0x5017001a,
3945 + 0x50170018, 0x50170017, 0x50170015, 0x500f002c,
3946 + 0x500f002a, 0x500f0027, 0x500f0025, 0x500f0023,
3947 + 0x500f0022, 0x500f001f, 0x500f001e, 0x500f001c,
3948 + 0x500f001a, 0x500f0019, 0x500f0018, 0x500f0016,
3949 + 0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
3950 + 0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
3951 + 0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
3952 + 0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
3953 + 0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
3954 + 0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
3955 + 0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
3956 + 0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
3957 + 0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
3958 + 0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
3959 + 0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
3960 + 0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
3961 + 0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
3962 + 0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
3963 + 0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
3968 +static const u32 b43_ntab_tx_gain_ipa_rev3_5g[] = {
3969 0x7ff70035, 0x7ff70033, 0x7ff70032, 0x7ff70031,
3970 0x7ff7002f, 0x7ff7002e, 0x7ff7002d, 0x7ff7002b,
3971 0x7ff7002a, 0x7ff70029, 0x7ff70028, 0x7ff70027,
3972 @@ -2462,6 +2837,42 @@ static const u32 txpwrctrl_tx_gain_ipa_5
3973 0x70f70021, 0x70f70020, 0x70f70020, 0x70f7001f,
3976 +/* Extracted from MMIO dump of 6.30.223.141 */
3977 +static const u32 b43_ntab_tx_gain_ipa_2057_rev9_5g[] = {
3978 + 0x7f7f0053, 0x7f7f004b, 0x7f7f0044, 0x7f7f003f,
3979 + 0x7f7f0039, 0x7f7f0035, 0x7f7f0032, 0x7f7f0030,
3980 + 0x7f7f002d, 0x7e7f0030, 0x7e7f002d, 0x7d7f0032,
3981 + 0x7d7f002f, 0x7d7f002c, 0x7c7f0032, 0x7c7f0030,
3982 + 0x7c7f002d, 0x7b7f0030, 0x7b7f002e, 0x7b7f002b,
3983 + 0x7a7f0032, 0x7a7f0030, 0x7a7f002d, 0x7a7f002b,
3984 + 0x797f0030, 0x797f002e, 0x797f002b, 0x797f0029,
3985 + 0x787f0030, 0x787f002d, 0x787f002b, 0x777f0032,
3986 + 0x777f0030, 0x777f002d, 0x777f002b, 0x767f0031,
3987 + 0x767f002f, 0x767f002c, 0x767f002a, 0x757f0031,
3988 + 0x757f002f, 0x757f002c, 0x757f002a, 0x747f0030,
3989 + 0x747f002d, 0x747f002b, 0x737f0032, 0x737f002f,
3990 + 0x737f002c, 0x737f002a, 0x727f0030, 0x727f002d,
3991 + 0x727f002b, 0x727f0029, 0x717f0030, 0x717f002d,
3992 + 0x717f002b, 0x707f0031, 0x707f002f, 0x707f002c,
3993 + 0x707f002a, 0x707f0027, 0x707f0025, 0x707f0023,
3994 + 0x707f0021, 0x707f001f, 0x707f001d, 0x707f001c,
3995 + 0x707f001a, 0x707f0019, 0x707f0017, 0x707f0016,
3996 + 0x707f0015, 0x707f0014, 0x707f0012, 0x707f0012,
3997 + 0x707f0011, 0x707f0010, 0x707f000f, 0x707f000e,
3998 + 0x707f000d, 0x707f000d, 0x707f000c, 0x707f000b,
3999 + 0x707f000a, 0x707f000a, 0x707f0009, 0x707f0008,
4000 + 0x707f0008, 0x707f0008, 0x707f0008, 0x707f0007,
4001 + 0x707f0007, 0x707f0006, 0x707f0006, 0x707f0006,
4002 + 0x707f0005, 0x707f0005, 0x707f0005, 0x707f0004,
4003 + 0x707f0004, 0x707f0004, 0x707f0003, 0x707f0003,
4004 + 0x707f0003, 0x707f0003, 0x707f0003, 0x707f0003,
4005 + 0x707f0003, 0x707f0003, 0x707f0003, 0x707f0003,
4006 + 0x707f0002, 0x707f0002, 0x707f0002, 0x707f0002,
4007 + 0x707f0002, 0x707f0002, 0x707f0002, 0x707f0002,
4008 + 0x707f0002, 0x707f0001, 0x707f0001, 0x707f0001,
4009 + 0x707f0001, 0x707f0001, 0x707f0001, 0x707f0001,
4012 const s8 b43_ntab_papd_pga_gain_delta_ipa_2g[] = {
4013 -114, -108, -98, -91, -84, -78, -70, -62,
4014 -54, -46, -39, -31, -23, -15, -8, 0
4015 @@ -2698,11 +3109,11 @@ static const struct nphy_rf_control_over
4016 { 0x0010, 0x07A, 0x07D, 0x0010, 4 },
4017 { 0x0020, 0x07A, 0x07D, 0x0020, 5 },
4018 { 0x0040, 0x07A, 0x07D, 0x0040, 6 },
4019 - { 0x0080, 0x0F8, 0x0FA, 0x0080, 7 },
4020 + { 0x0080, 0x07A, 0x07D, 0x0080, 7 },
4021 { 0x0400, 0x0F8, 0x0FA, 0x0070, 4 },
4022 { 0x0800, 0x07B, 0x07E, 0xFFFF, 0 },
4023 { 0x1000, 0x07C, 0x07F, 0xFFFF, 0 },
4024 - { 0x6000, 0x348, 0x349, 0xFFFF, 0 },
4025 + { 0x6000, 0x348, 0x349, 0x00FF, 0 },
4026 { 0x2000, 0x348, 0x349, 0x000F, 0 },
4029 @@ -3031,31 +3442,8 @@ void b43_ntab_write_bulk(struct b43_wlde
4030 b43_ntab_write_bulk(dev, offset, ARRAY_SIZE(data), data); \
4033 -static void b43_nphy_tables_init_rev3(struct b43_wldev *dev)
4034 +static void b43_nphy_tables_init_shared_lut(struct b43_wldev *dev)
4036 - struct ssb_sprom *sprom = dev->dev->bus_sprom;
4039 - if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
4040 - antswlut = sprom->fem.ghz5.antswlut;
4042 - antswlut = sprom->fem.ghz2.antswlut;
4044 - /* Static tables */
4045 - ntab_upload(dev, B43_NTAB_FRAMESTRUCT_R3, b43_ntab_framestruct_r3);
4046 - ntab_upload(dev, B43_NTAB_PILOT_R3, b43_ntab_pilot_r3);
4047 - ntab_upload(dev, B43_NTAB_TMAP_R3, b43_ntab_tmap_r3);
4048 - ntab_upload(dev, B43_NTAB_INTLEVEL_R3, b43_ntab_intlevel_r3);
4049 - ntab_upload(dev, B43_NTAB_TDTRN_R3, b43_ntab_tdtrn_r3);
4050 - ntab_upload(dev, B43_NTAB_NOISEVAR_R3, b43_ntab_noisevar_r3);
4051 - ntab_upload(dev, B43_NTAB_MCS_R3, b43_ntab_mcs_r3);
4052 - ntab_upload(dev, B43_NTAB_TDI20A0_R3, b43_ntab_tdi20a0_r3);
4053 - ntab_upload(dev, B43_NTAB_TDI20A1_R3, b43_ntab_tdi20a1_r3);
4054 - ntab_upload(dev, B43_NTAB_TDI40A0_R3, b43_ntab_tdi40a0_r3);
4055 - ntab_upload(dev, B43_NTAB_TDI40A1_R3, b43_ntab_tdi40a1_r3);
4056 - ntab_upload(dev, B43_NTAB_PILOTLT_R3, b43_ntab_pilotlt_r3);
4057 - ntab_upload(dev, B43_NTAB_CHANEST_R3, b43_ntab_channelest_r3);
4058 - ntab_upload(dev, B43_NTAB_FRAMELT_R3, b43_ntab_framelookup_r3);
4059 ntab_upload(dev, B43_NTAB_C0_ESTPLT_R3, b43_ntab_estimatepowerlt0_r3);
4060 ntab_upload(dev, B43_NTAB_C1_ESTPLT_R3, b43_ntab_estimatepowerlt1_r3);
4061 ntab_upload(dev, B43_NTAB_C0_ADJPLT_R3, b43_ntab_adjustpower0_r3);
4062 @@ -3066,6 +3454,107 @@ static void b43_nphy_tables_init_rev3(st
4063 ntab_upload(dev, B43_NTAB_C1_IQLT_R3, b43_ntab_iqlt1_r3);
4064 ntab_upload(dev, B43_NTAB_C0_LOFEEDTH_R3, b43_ntab_loftlt0_r3);
4065 ntab_upload(dev, B43_NTAB_C1_LOFEEDTH_R3, b43_ntab_loftlt1_r3);
4068 +static void b43_nphy_tables_init_rev7_volatile(struct b43_wldev *dev)
4070 + struct ssb_sprom *sprom = dev->dev->bus_sprom;
4072 + int core, offset, i;
4074 + const int antswlut0_offsets[] = { 0, 4, 8, }; /* Offsets for values */
4075 + const u8 antswlut0_values[][3] = {
4076 + { 0x2, 0x12, 0x8 }, /* Core 0 */
4077 + { 0x2, 0x18, 0x2 }, /* Core 1 */
4080 + if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
4081 + antswlut = sprom->fem.ghz5.antswlut;
4083 + antswlut = sprom->fem.ghz2.antswlut;
4085 + switch (antswlut) {
4087 + for (core = 0; core < 2; core++) {
4088 + for (i = 0; i < ARRAY_SIZE(antswlut0_values[0]); i++) {
4089 + offset = core ? 0x20 : 0x00;
4090 + offset += antswlut0_offsets[i];
4091 + b43_ntab_write(dev, B43_NTAB8(9, offset),
4092 + antswlut0_values[core][i]);
4097 + b43err(dev->wl, "Unsupported antswlut: %d\n", antswlut);
4102 +static void b43_nphy_tables_init_rev16(struct b43_wldev *dev)
4104 + /* Static tables */
4105 + if (dev->phy.do_full_init) {
4106 + ntab_upload(dev, B43_NTAB_NOISEVAR_R7, b43_ntab_noisevar_r7);
4107 + b43_nphy_tables_init_shared_lut(dev);
4110 + /* Volatile tables */
4111 + b43_nphy_tables_init_rev7_volatile(dev);
4114 +static void b43_nphy_tables_init_rev7(struct b43_wldev *dev)
4116 + /* Static tables */
4117 + if (dev->phy.do_full_init) {
4118 + ntab_upload(dev, B43_NTAB_FRAMESTRUCT_R3, b43_ntab_framestruct_r3);
4119 + ntab_upload(dev, B43_NTAB_PILOT_R3, b43_ntab_pilot_r3);
4120 + ntab_upload(dev, B43_NTAB_TMAP_R7, b43_ntab_tmap_r7);
4121 + ntab_upload(dev, B43_NTAB_INTLEVEL_R3, b43_ntab_intlevel_r3);
4122 + ntab_upload(dev, B43_NTAB_TDTRN_R3, b43_ntab_tdtrn_r3);
4123 + ntab_upload(dev, B43_NTAB_NOISEVAR_R7, b43_ntab_noisevar_r7);
4124 + ntab_upload(dev, B43_NTAB_MCS_R3, b43_ntab_mcs_r3);
4125 + ntab_upload(dev, B43_NTAB_TDI20A0_R3, b43_ntab_tdi20a0_r3);
4126 + ntab_upload(dev, B43_NTAB_TDI20A1_R3, b43_ntab_tdi20a1_r3);
4127 + ntab_upload(dev, B43_NTAB_TDI40A0_R3, b43_ntab_tdi40a0_r3);
4128 + ntab_upload(dev, B43_NTAB_TDI40A1_R3, b43_ntab_tdi40a1_r3);
4129 + ntab_upload(dev, B43_NTAB_PILOTLT_R3, b43_ntab_pilotlt_r3);
4130 + ntab_upload(dev, B43_NTAB_CHANEST_R3, b43_ntab_channelest_r3);
4131 + ntab_upload(dev, B43_NTAB_FRAMELT_R3, b43_ntab_framelookup_r3);
4132 + b43_nphy_tables_init_shared_lut(dev);
4135 + /* Volatile tables */
4136 + b43_nphy_tables_init_rev7_volatile(dev);
4139 +static void b43_nphy_tables_init_rev3(struct b43_wldev *dev)
4141 + struct ssb_sprom *sprom = dev->dev->bus_sprom;
4144 + if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
4145 + antswlut = sprom->fem.ghz5.antswlut;
4147 + antswlut = sprom->fem.ghz2.antswlut;
4149 + /* Static tables */
4150 + if (dev->phy.do_full_init) {
4151 + ntab_upload(dev, B43_NTAB_FRAMESTRUCT_R3, b43_ntab_framestruct_r3);
4152 + ntab_upload(dev, B43_NTAB_PILOT_R3, b43_ntab_pilot_r3);
4153 + ntab_upload(dev, B43_NTAB_TMAP_R3, b43_ntab_tmap_r3);
4154 + ntab_upload(dev, B43_NTAB_INTLEVEL_R3, b43_ntab_intlevel_r3);
4155 + ntab_upload(dev, B43_NTAB_TDTRN_R3, b43_ntab_tdtrn_r3);
4156 + ntab_upload(dev, B43_NTAB_NOISEVAR_R3, b43_ntab_noisevar_r3);
4157 + ntab_upload(dev, B43_NTAB_MCS_R3, b43_ntab_mcs_r3);
4158 + ntab_upload(dev, B43_NTAB_TDI20A0_R3, b43_ntab_tdi20a0_r3);
4159 + ntab_upload(dev, B43_NTAB_TDI20A1_R3, b43_ntab_tdi20a1_r3);
4160 + ntab_upload(dev, B43_NTAB_TDI40A0_R3, b43_ntab_tdi40a0_r3);
4161 + ntab_upload(dev, B43_NTAB_TDI40A1_R3, b43_ntab_tdi40a1_r3);
4162 + ntab_upload(dev, B43_NTAB_PILOTLT_R3, b43_ntab_pilotlt_r3);
4163 + ntab_upload(dev, B43_NTAB_CHANEST_R3, b43_ntab_channelest_r3);
4164 + ntab_upload(dev, B43_NTAB_FRAMELT_R3, b43_ntab_framelookup_r3);
4165 + b43_nphy_tables_init_shared_lut(dev);
4168 /* Volatile tables */
4169 if (antswlut < ARRAY_SIZE(b43_ntab_antswctl_r3))
4170 @@ -3078,20 +3567,22 @@ static void b43_nphy_tables_init_rev3(st
4171 static void b43_nphy_tables_init_rev0(struct b43_wldev *dev)
4174 - ntab_upload(dev, B43_NTAB_FRAMESTRUCT, b43_ntab_framestruct);
4175 - ntab_upload(dev, B43_NTAB_FRAMELT, b43_ntab_framelookup);
4176 - ntab_upload(dev, B43_NTAB_TMAP, b43_ntab_tmap);
4177 - ntab_upload(dev, B43_NTAB_TDTRN, b43_ntab_tdtrn);
4178 - ntab_upload(dev, B43_NTAB_INTLEVEL, b43_ntab_intlevel);
4179 - ntab_upload(dev, B43_NTAB_PILOT, b43_ntab_pilot);
4180 - ntab_upload(dev, B43_NTAB_TDI20A0, b43_ntab_tdi20a0);
4181 - ntab_upload(dev, B43_NTAB_TDI20A1, b43_ntab_tdi20a1);
4182 - ntab_upload(dev, B43_NTAB_TDI40A0, b43_ntab_tdi40a0);
4183 - ntab_upload(dev, B43_NTAB_TDI40A1, b43_ntab_tdi40a1);
4184 - ntab_upload(dev, B43_NTAB_CHANEST, b43_ntab_channelest);
4185 - ntab_upload(dev, B43_NTAB_MCS, b43_ntab_mcs);
4186 - ntab_upload(dev, B43_NTAB_NOISEVAR10, b43_ntab_noisevar10);
4187 - ntab_upload(dev, B43_NTAB_NOISEVAR11, b43_ntab_noisevar11);
4188 + if (dev->phy.do_full_init) {
4189 + ntab_upload(dev, B43_NTAB_FRAMESTRUCT, b43_ntab_framestruct);
4190 + ntab_upload(dev, B43_NTAB_FRAMELT, b43_ntab_framelookup);
4191 + ntab_upload(dev, B43_NTAB_TMAP, b43_ntab_tmap);
4192 + ntab_upload(dev, B43_NTAB_TDTRN, b43_ntab_tdtrn);
4193 + ntab_upload(dev, B43_NTAB_INTLEVEL, b43_ntab_intlevel);
4194 + ntab_upload(dev, B43_NTAB_PILOT, b43_ntab_pilot);
4195 + ntab_upload(dev, B43_NTAB_TDI20A0, b43_ntab_tdi20a0);
4196 + ntab_upload(dev, B43_NTAB_TDI20A1, b43_ntab_tdi20a1);
4197 + ntab_upload(dev, B43_NTAB_TDI40A0, b43_ntab_tdi40a0);
4198 + ntab_upload(dev, B43_NTAB_TDI40A1, b43_ntab_tdi40a1);
4199 + ntab_upload(dev, B43_NTAB_CHANEST, b43_ntab_channelest);
4200 + ntab_upload(dev, B43_NTAB_MCS, b43_ntab_mcs);
4201 + ntab_upload(dev, B43_NTAB_NOISEVAR10, b43_ntab_noisevar10);
4202 + ntab_upload(dev, B43_NTAB_NOISEVAR11, b43_ntab_noisevar11);
4205 /* Volatile tables */
4206 ntab_upload(dev, B43_NTAB_BDI, b43_ntab_bdi);
4207 @@ -3111,7 +3602,11 @@ static void b43_nphy_tables_init_rev0(st
4208 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/InitTables */
4209 void b43_nphy_tables_init(struct b43_wldev *dev)
4211 - if (dev->phy.rev >= 3)
4212 + if (dev->phy.rev >= 16)
4213 + b43_nphy_tables_init_rev16(dev);
4214 + else if (dev->phy.rev >= 7)
4215 + b43_nphy_tables_init_rev7(dev);
4216 + else if (dev->phy.rev >= 3)
4217 b43_nphy_tables_init_rev3(dev);
4219 b43_nphy_tables_init_rev0(dev);
4220 @@ -3120,23 +3615,55 @@ void b43_nphy_tables_init(struct b43_wld
4221 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetIpaGainTbl */
4222 static const u32 *b43_nphy_get_ipa_gain_table(struct b43_wldev *dev)
4224 + struct b43_phy *phy = &dev->phy;
4226 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
4227 - if (dev->phy.rev >= 6) {
4228 - if (dev->dev->chip_id == 47162)
4229 - return txpwrctrl_tx_gain_ipa_rev5;
4230 - return txpwrctrl_tx_gain_ipa_rev6;
4231 - } else if (dev->phy.rev >= 5) {
4232 - return txpwrctrl_tx_gain_ipa_rev5;
4234 - return txpwrctrl_tx_gain_ipa;
4235 + switch (phy->rev) {
4237 + if (phy->radio_rev == 14)
4238 + return b43_ntab_tx_gain_ipa_2057_rev14_2g;
4241 + if (phy->radio_rev == 9)
4242 + return b43_ntab_tx_gain_ipa_2057_rev9_2g;
4245 + if (phy->radio_rev == 5)
4246 + return b43_ntab_tx_gain_ipa_2057_rev5_2g;
4249 + if (dev->dev->chip_id == BCMA_CHIP_ID_BCM47162)
4250 + return b43_ntab_tx_gain_ipa_rev5_2g;
4251 + return b43_ntab_tx_gain_ipa_rev6_2g;
4253 + return b43_ntab_tx_gain_ipa_rev5_2g;
4256 + return b43_ntab_tx_gain_ipa_rev3_2g;
4260 + "No 2GHz IPA gain table available for this device\n");
4263 - return txpwrctrl_tx_gain_ipa_5g;
4264 + switch (phy->rev) {
4266 + if (phy->radio_rev == 9)
4267 + return b43_ntab_tx_gain_ipa_2057_rev9_5g;
4270 + return b43_ntab_tx_gain_ipa_rev3_5g;
4274 + "No 5GHz IPA gain table available for this device\n");
4279 const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev)
4281 + struct b43_phy *phy = &dev->phy;
4282 enum ieee80211_band band = b43_current_band(dev->wl);
4283 struct ssb_sprom *sprom = dev->dev->bus_sprom;
4285 @@ -3148,19 +3675,36 @@ const u32 *b43_nphy_get_tx_gain_table(st
4286 (dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ)) {
4287 return b43_nphy_get_ipa_gain_table(dev);
4288 } else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
4289 - if (dev->phy.rev == 3)
4290 - return b43_ntab_tx_gain_rev3_5ghz;
4291 - if (dev->phy.rev == 4)
4292 + switch (phy->rev) {
4295 + return b43_ntab_tx_gain_epa_rev5_5g;
4297 return sprom->fem.ghz5.extpa_gain == 3 ?
4298 - b43_ntab_tx_gain_rev4_5ghz :
4299 - b43_ntab_tx_gain_rev4_5ghz; /* FIXME */
4301 - return b43_ntab_tx_gain_rev5plus_5ghz;
4302 + b43_ntab_tx_gain_epa_rev4_5g :
4303 + b43_ntab_tx_gain_epa_rev4_hi_pwr_5g;
4305 + return b43_ntab_tx_gain_epa_rev3_5g;
4308 + "No 5GHz EPA gain table available for this device\n");
4312 - if (dev->phy.rev >= 5 && sprom->fem.ghz5.extpa_gain == 3)
4313 - return b43_ntab_tx_gain_rev3plus_2ghz; /* FIXME */
4315 - return b43_ntab_tx_gain_rev3plus_2ghz;
4316 + switch (phy->rev) {
4319 + if (sprom->fem.ghz5.extpa_gain == 3)
4320 + return b43_ntab_tx_gain_epa_rev3_hi_pwr_2g;
4321 + /* fall through */
4324 + return b43_ntab_tx_gain_epa_rev3_2g;
4327 + "No 2GHz EPA gain table available for this device\n");
4333 @@ -3187,7 +3731,7 @@ struct nphy_gain_ctl_workaround_entry *b
4334 /* Some workarounds to the workarounds... */
4335 if (ghz5 && dev->phy.rev >= 6) {
4336 if (dev->phy.radio_rev == 11 &&
4337 - !b43_channel_type_is_40mhz(dev->phy.channel_type))
4338 + !b43_is_40mhz(dev))
4339 e->cliplo_gain = 0x2d;
4340 } else if (!ghz5 && dev->phy.rev >= 5) {
4341 static const int gain_data[] = {0x0062, 0x0064, 0x006a, 0x106a,
4342 --- a/drivers/net/wireless/b43/Kconfig
4343 +++ b/drivers/net/wireless/b43/Kconfig
4344 @@ -37,7 +37,7 @@ config B43_SSB
4346 prompt "Supported bus types"
4348 - default B43_BCMA_AND_SSB
4349 + default B43_BUSES_BCMA_AND_SSB
4351 config B43_BUSES_BCMA_AND_SSB
4353 @@ -123,6 +123,15 @@ config B43_PIO
4358 + bool "Support for G-PHY (802.11g) devices"
4359 + depends on B43 && B43_SSB
4362 + This PHY type can be found in the following chipsets:
4363 + PCI: BCM4306, BCM4311, BCM4318
4364 + SoC: BCM4712, BCM5352E
4367 bool "Support for 802.11n (N-PHY) devices"
4369 --- a/drivers/net/wireless/b43/phy_ht.c
4370 +++ b/drivers/net/wireless/b43/phy_ht.c
4371 @@ -596,7 +596,7 @@ static void b43_phy_ht_tx_power_ctl_setu
4373 s16 a1[3], b0[3], b1[3];
4375 - u16 freq = dev->phy.channel_freq;
4376 + u16 freq = dev->phy.chandef->chan->center_freq;
4379 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
4380 --- a/drivers/net/wireless/b43/phy_a.h
4381 +++ b/drivers/net/wireless/b43/phy_a.h
4382 @@ -123,8 +123,4 @@ struct b43_phy_a {
4384 void b43_phy_inita(struct b43_wldev *dev);
4387 -struct b43_phy_operations;
4388 -extern const struct b43_phy_operations b43_phyops_a;
4390 #endif /* LINUX_B43_PHY_A_H_ */
4391 --- a/drivers/net/wireless/b43/Makefile
4392 +++ b/drivers/net/wireless/b43/Makefile
4397 +b43-$(CPTCFG_B43_PHY_G) += phy_a.o phy_g.o tables.o lo.o wa.o
4398 b43-$(CPTCFG_B43_PHY_N) += tables_nphy.o
4399 b43-$(CPTCFG_B43_PHY_N) += radio_2055.o
4400 b43-$(CPTCFG_B43_PHY_N) += radio_2056.o
4401 b43-$(CPTCFG_B43_PHY_N) += radio_2057.o
4402 b43-y += phy_common.o
4405 b43-$(CPTCFG_B43_PHY_N) += phy_n.o
4406 b43-$(CPTCFG_B43_PHY_LP) += phy_lp.o
4407 b43-$(CPTCFG_B43_PHY_LP) += tables_lpphy.o
4408 @@ -17,8 +15,6 @@ b43-$(CPTCFG_B43_PHY_HT) += radio_2059.o
4409 b43-$(CPTCFG_B43_PHY_LCN) += phy_lcn.o tables_phy_lcn.o
4417 --- a/drivers/net/wireless/b43/phy_a.c
4418 +++ b/drivers/net/wireless/b43/phy_a.c
4419 @@ -573,7 +573,7 @@ static void b43_aphy_op_pwork_60sec(stru
4423 -const struct b43_phy_operations b43_phyops_a = {
4424 +static const struct b43_phy_operations b43_phyops_a = {
4425 .allocate = b43_aphy_op_allocate,
4426 .free = b43_aphy_op_free,
4427 .prepare_structs = b43_aphy_op_prepare_structs,
4428 --- a/drivers/net/wireless/b43/radio_2057.c
4429 +++ b/drivers/net/wireless/b43/radio_2057.c
4431 #include "radio_2057.h"
4432 #include "phy_common.h"
4434 -static u16 r2057_rev4_init[42][2] = {
4435 +static u16 r2057_rev4_init[][2] = {
4436 { 0x0E, 0x20 }, { 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 },
4437 { 0x35, 0x26 }, { 0x3C, 0xff }, { 0x3D, 0xff }, { 0x3E, 0xff },
4438 { 0x3F, 0xff }, { 0x62, 0x33 }, { 0x8A, 0xf0 }, { 0x8B, 0x10 },
4439 @@ -40,7 +40,7 @@ static u16 r2057_rev4_init[42][2] = {
4440 { 0x1AB, 0x00 }, { 0x1AC, 0x00 },
4443 -static u16 r2057_rev5_init[44][2] = {
4444 +static u16 r2057_rev5_init[][2] = {
4445 { 0x00, 0x00 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x23, 0x6 },
4446 { 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 },
4447 { 0x59, 0x88 }, { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f },
4448 @@ -54,7 +54,7 @@ static u16 r2057_rev5_init[44][2] = {
4449 { 0x1AC, 0x00 }, { 0x1B7, 0x0c }, { 0x1C1, 0x01 }, { 0x1C2, 0x80 },
4452 -static u16 r2057_rev5a_init[45][2] = {
4453 +static u16 r2057_rev5a_init[][2] = {
4454 { 0x00, 0x15 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x23, 0x6 },
4455 { 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 },
4456 { 0x59, 0x88 }, { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f },
4457 @@ -69,7 +69,7 @@ static u16 r2057_rev5a_init[45][2] = {
4461 -static u16 r2057_rev7_init[54][2] = {
4462 +static u16 r2057_rev7_init[][2] = {
4463 { 0x00, 0x00 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x31, 0x00 },
4464 { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 }, { 0x59, 0x88 },
4465 { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f }, { 0x64, 0x13 },
4466 @@ -86,7 +86,8 @@ static u16 r2057_rev7_init[54][2] = {
4467 { 0x1B7, 0x05 }, { 0x1C2, 0xa0 },
4470 -static u16 r2057_rev8_init[54][2] = {
4471 +/* TODO: Which devices should use it?
4472 +static u16 r2057_rev8_init[][2] = {
4473 { 0x00, 0x08 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x31, 0x00 },
4474 { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 }, { 0x59, 0x88 },
4475 { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f }, { 0x64, 0x0f },
4476 @@ -102,6 +103,436 @@ static u16 r2057_rev8_init[54][2] = {
4477 { 0x1A6, 0x00 }, { 0x1AA, 0x00 }, { 0x1AB, 0x00 }, { 0x1AC, 0x00 },
4478 { 0x1B7, 0x05 }, { 0x1C2, 0xa0 },
4482 +/* Extracted from MMIO dump of 6.30.223.141 */
4483 +static u16 r2057_rev9_init[][2] = {
4484 + { 0x27, 0x1f }, { 0x28, 0x0a }, { 0x29, 0x2f }, { 0x42, 0x1f },
4485 + { 0x48, 0x3f }, { 0x5c, 0x41 }, { 0x63, 0x14 }, { 0x64, 0x12 },
4486 + { 0x66, 0xff }, { 0x74, 0xa3 }, { 0x7b, 0x14 }, { 0x7c, 0x14 },
4487 + { 0x7d, 0xee }, { 0x86, 0xc0 }, { 0xc4, 0x10 }, { 0xc9, 0x01 },
4488 + { 0xe1, 0x41 }, { 0xe8, 0x14 }, { 0xe9, 0x12 }, { 0xeb, 0xff },
4489 + { 0xf5, 0x0a }, { 0xf8, 0x09 }, { 0xf9, 0xa3 }, { 0x100, 0x14 },
4490 + { 0x101, 0x10 }, { 0x102, 0xee }, { 0x10b, 0xc0 }, { 0x149, 0x10 },
4491 + { 0x14e, 0x01 }, { 0x1b7, 0x05 }, { 0x1c2, 0xa0 },
4494 +/* Extracted from MMIO dump of 6.30.223.248 */
4495 +static u16 r2057_rev14_init[][2] = {
4496 + { 0x011, 0xfc }, { 0x030, 0x24 }, { 0x040, 0x1c }, { 0x082, 0x08 },
4497 + { 0x0b4, 0x44 }, { 0x0c8, 0x01 }, { 0x0c9, 0x01 }, { 0x107, 0x08 },
4498 + { 0x14d, 0x01 }, { 0x14e, 0x01 }, { 0x1af, 0x40 }, { 0x1b0, 0x40 },
4499 + { 0x1cc, 0x01 }, { 0x1cf, 0x10 }, { 0x1d0, 0x0f }, { 0x1d3, 0x10 },
4503 +#define RADIOREGS7(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \
4504 + r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, \
4505 + r20, r21, r22, r23, r24, r25, r26, r27) \
4506 + .radio_vcocal_countval0 = r00, \
4507 + .radio_vcocal_countval1 = r01, \
4508 + .radio_rfpll_refmaster_sparextalsize = r02, \
4509 + .radio_rfpll_loopfilter_r1 = r03, \
4510 + .radio_rfpll_loopfilter_c2 = r04, \
4511 + .radio_rfpll_loopfilter_c1 = r05, \
4512 + .radio_cp_kpd_idac = r06, \
4513 + .radio_rfpll_mmd0 = r07, \
4514 + .radio_rfpll_mmd1 = r08, \
4515 + .radio_vcobuf_tune = r09, \
4516 + .radio_logen_mx2g_tune = r10, \
4517 + .radio_logen_mx5g_tune = r11, \
4518 + .radio_logen_indbuf2g_tune = r12, \
4519 + .radio_logen_indbuf5g_tune = r13, \
4520 + .radio_txmix2g_tune_boost_pu_core0 = r14, \
4521 + .radio_pad2g_tune_pus_core0 = r15, \
4522 + .radio_pga_boost_tune_core0 = r16, \
4523 + .radio_txmix5g_boost_tune_core0 = r17, \
4524 + .radio_pad5g_tune_misc_pus_core0 = r18, \
4525 + .radio_lna2g_tune_core0 = r19, \
4526 + .radio_lna5g_tune_core0 = r20, \
4527 + .radio_txmix2g_tune_boost_pu_core1 = r21, \
4528 + .radio_pad2g_tune_pus_core1 = r22, \
4529 + .radio_pga_boost_tune_core1 = r23, \
4530 + .radio_txmix5g_boost_tune_core1 = r24, \
4531 + .radio_pad5g_tune_misc_pus_core1 = r25, \
4532 + .radio_lna2g_tune_core1 = r26, \
4533 + .radio_lna5g_tune_core1 = r27
4535 +#define RADIOREGS7_2G(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \
4536 + r10, r11, r12, r13, r14, r15, r16, r17) \
4537 + .radio_vcocal_countval0 = r00, \
4538 + .radio_vcocal_countval1 = r01, \
4539 + .radio_rfpll_refmaster_sparextalsize = r02, \
4540 + .radio_rfpll_loopfilter_r1 = r03, \
4541 + .radio_rfpll_loopfilter_c2 = r04, \
4542 + .radio_rfpll_loopfilter_c1 = r05, \
4543 + .radio_cp_kpd_idac = r06, \
4544 + .radio_rfpll_mmd0 = r07, \
4545 + .radio_rfpll_mmd1 = r08, \
4546 + .radio_vcobuf_tune = r09, \
4547 + .radio_logen_mx2g_tune = r10, \
4548 + .radio_logen_indbuf2g_tune = r11, \
4549 + .radio_txmix2g_tune_boost_pu_core0 = r12, \
4550 + .radio_pad2g_tune_pus_core0 = r13, \
4551 + .radio_lna2g_tune_core0 = r14, \
4552 + .radio_txmix2g_tune_boost_pu_core1 = r15, \
4553 + .radio_pad2g_tune_pus_core1 = r16, \
4554 + .radio_lna2g_tune_core1 = r17
4556 +#define PHYREGS(r0, r1, r2, r3, r4, r5) \
4557 + .phy_regs.phy_bw1a = r0, \
4558 + .phy_regs.phy_bw2 = r1, \
4559 + .phy_regs.phy_bw3 = r2, \
4560 + .phy_regs.phy_bw4 = r3, \
4561 + .phy_regs.phy_bw5 = r4, \
4562 + .phy_regs.phy_bw6 = r5
4564 +/* Copied from brcmsmac (5.75.11): chan_info_nphyrev8_2057_rev5 */
4565 +static const struct b43_nphy_chantabent_rev7_2g b43_nphy_chantab_phy_rev8_radio_rev5[] = {
4568 + RADIOREGS7_2G(0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c,
4569 + 0x09, 0x0d, 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61,
4571 + PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
4575 + RADIOREGS7_2G(0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71,
4576 + 0x09, 0x0d, 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61,
4578 + PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
4582 + RADIOREGS7_2G(0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76,
4583 + 0x09, 0x0d, 0x08, 0x0e, 0x61, 0x03, 0xef, 0x61,
4585 + PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
4589 + RADIOREGS7_2G(0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b,
4590 + 0x09, 0x0c, 0x08, 0x0e, 0x61, 0x03, 0xdf, 0x61,
4592 + PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
4596 + RADIOREGS7_2G(0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80,
4597 + 0x09, 0x0c, 0x07, 0x0d, 0x61, 0x03, 0xcf, 0x61,
4599 + PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
4603 + RADIOREGS7_2G(0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85,
4604 + 0x09, 0x0c, 0x07, 0x0d, 0x61, 0x03, 0xbf, 0x61,
4606 + PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
4610 + RADIOREGS7_2G(0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a,
4611 + 0x09, 0x0b, 0x07, 0x0d, 0x61, 0x03, 0xaf, 0x61,
4613 + PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
4617 + RADIOREGS7_2G(0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f,
4618 + 0x09, 0x0b, 0x07, 0x0d, 0x61, 0x03, 0x9f, 0x61,
4620 + PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
4624 + RADIOREGS7_2G(0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94,
4625 + 0x09, 0x0b, 0x07, 0x0d, 0x61, 0x03, 0x8f, 0x61,
4627 + PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
4631 + RADIOREGS7_2G(0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99,
4632 + 0x09, 0x0b, 0x07, 0x0c, 0x61, 0x03, 0x7f, 0x61,
4634 + PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
4638 + RADIOREGS7_2G(0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e,
4639 + 0x09, 0x0b, 0x07, 0x0c, 0x61, 0x03, 0x6f, 0x61,
4641 + PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
4645 + RADIOREGS7_2G(0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3,
4646 + 0x09, 0x0b, 0x06, 0x0c, 0x61, 0x03, 0x5f, 0x61,
4648 + PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b),
4652 + RADIOREGS7_2G(0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8,
4653 + 0x09, 0x0a, 0x06, 0x0b, 0x61, 0x03, 0x4f, 0x61,
4655 + PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429),
4659 + RADIOREGS7_2G(0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4,
4660 + 0x09, 0x0a, 0x06, 0x0b, 0x61, 0x03, 0x3f, 0x61,
4662 + PHYREGS(0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424),
4666 +/* Extracted from MMIO dump of 6.30.223.248 */
4667 +static const struct b43_nphy_chantabent_rev7_2g b43_nphy_chantab_phy_rev17_radio_rev14[] = {
4670 + RADIOREGS7_2G(0x48, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x6c,
4671 + 0x09, 0x0d, 0x09, 0x03, 0x21, 0x53, 0xff, 0x21,
4673 + PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
4677 + RADIOREGS7_2G(0x4b, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x71,
4678 + 0x09, 0x0d, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
4680 + PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
4684 + RADIOREGS7_2G(0x4e, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x76,
4685 + 0x09, 0x0d, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
4687 + PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
4691 + RADIOREGS7_2G(0x52, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x7b,
4692 + 0x09, 0x0c, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
4694 + PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
4698 + RADIOREGS7_2G(0x55, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x80,
4699 + 0x09, 0x0c, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
4701 + PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
4705 + RADIOREGS7_2G(0x58, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x85,
4706 + 0x09, 0x0c, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
4708 + PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
4712 + RADIOREGS7_2G(0x5c, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x8a,
4713 + 0x09, 0x0c, 0x08, 0x03, 0x21, 0x43, 0xff, 0x21,
4715 + PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
4719 + RADIOREGS7_2G(0x5f, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x8f,
4720 + 0x09, 0x0c, 0x08, 0x03, 0x21, 0x43, 0xff, 0x21,
4722 + PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
4726 + RADIOREGS7_2G(0x62, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x94,
4727 + 0x09, 0x0c, 0x08, 0x03, 0x21, 0x43, 0xff, 0x21,
4729 + PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
4733 + RADIOREGS7_2G(0x66, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x99,
4734 + 0x09, 0x0b, 0x07, 0x03, 0x21, 0x43, 0xff, 0x21,
4736 + PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
4740 + RADIOREGS7_2G(0x69, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x9e,
4741 + 0x09, 0x0b, 0x07, 0x03, 0x01, 0x43, 0xff, 0x01,
4743 + PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
4747 +/* Extracted from MMIO dump of 6.30.223.141 */
4748 +static const struct b43_nphy_chantabent_rev7 b43_nphy_chantab_phy_rev16_radio_rev9[] = {
4751 + RADIOREGS7(0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c,
4752 + 0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x41, 0x63,
4753 + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
4754 + 0x00, 0x00, 0xf0, 0x00),
4755 + PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
4759 + RADIOREGS7(0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71,
4760 + 0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x41, 0x63,
4761 + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
4762 + 0x00, 0x00, 0xf0, 0x00),
4763 + PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
4767 + RADIOREGS7(0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76,
4768 + 0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x41, 0x63,
4769 + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
4770 + 0x00, 0x00, 0xf0, 0x00),
4771 + PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
4775 + RADIOREGS7(0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b,
4776 + 0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x41, 0x63,
4777 + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
4778 + 0x00, 0x00, 0xf0, 0x00),
4779 + PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
4783 + RADIOREGS7(0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80,
4784 + 0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x41, 0x63,
4785 + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
4786 + 0x00, 0x00, 0xf0, 0x00),
4787 + PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
4791 + RADIOREGS7(0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85,
4792 + 0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x41, 0x63,
4793 + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
4794 + 0x00, 0x00, 0xf0, 0x00),
4795 + PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
4799 + RADIOREGS7(0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a,
4800 + 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x41, 0x63,
4801 + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
4802 + 0x00, 0x00, 0xf0, 0x00),
4803 + PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
4807 + RADIOREGS7(0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f,
4808 + 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x41, 0x63,
4809 + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
4810 + 0x00, 0x00, 0xf0, 0x00),
4811 + PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
4815 + RADIOREGS7(0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94,
4816 + 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x41, 0x63,
4817 + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
4818 + 0x00, 0x00, 0xf0, 0x00),
4819 + PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
4823 + RADIOREGS7(0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99,
4824 + 0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x41, 0x63,
4825 + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
4826 + 0x00, 0x00, 0xf0, 0x00),
4827 + PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
4831 + RADIOREGS7(0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e,
4832 + 0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x41, 0x63,
4833 + 0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
4834 + 0x00, 0x00, 0xf0, 0x00),
4835 + PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
4839 + RADIOREGS7(0xbe, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x06,
4840 + 0x02, 0x0e, 0x00, 0x0e, 0x00, 0x9e, 0x00, 0x00,
4841 + 0x9f, 0x2f, 0xa3, 0x00, 0xfc, 0x00, 0x00, 0x4f,
4842 + 0x3a, 0x83, 0x00, 0xfc),
4843 + PHYREGS(0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb),
4847 + RADIOREGS7(0xc5, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x08,
4848 + 0x02, 0x0e, 0x00, 0x0e, 0x00, 0x9e, 0x00, 0x00,
4849 + 0x7f, 0x2f, 0x83, 0x00, 0xf8, 0x00, 0x00, 0x4c,
4850 + 0x4a, 0x83, 0x00, 0xf8),
4851 + PHYREGS(0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9),
4855 + RADIOREGS7(0xcc, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x0a,
4856 + 0x02, 0x0e, 0x00, 0x0e, 0x00, 0x9e, 0x00, 0x00,
4857 + 0x6d, 0x3d, 0x83, 0x00, 0xf8, 0x00, 0x00, 0x2d,
4858 + 0x2a, 0x73, 0x00, 0xf8),
4859 + PHYREGS(0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7),
4863 + RADIOREGS7(0xd2, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x0c,
4864 + 0x02, 0x0d, 0x00, 0x0d, 0x00, 0x8d, 0x00, 0x00,
4865 + 0x4d, 0x1c, 0x73, 0x00, 0xf8, 0x00, 0x00, 0x4d,
4866 + 0x2b, 0x73, 0x00, 0xf8),
4867 + PHYREGS(0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5),
4871 + RADIOREGS7(0x7b, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x7d,
4872 + 0x04, 0x08, 0x00, 0x06, 0x00, 0x15, 0x00, 0x00,
4873 + 0x08, 0x03, 0x03, 0x00, 0x30, 0x00, 0x00, 0x06,
4874 + 0x02, 0x03, 0x00, 0x30),
4875 + PHYREGS(0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9),
4879 + RADIOREGS7(0x81, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x81,
4880 + 0x04, 0x08, 0x00, 0x06, 0x00, 0x15, 0x00, 0x00,
4881 + 0x06, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x05,
4882 + 0x02, 0x03, 0x00, 0x00),
4883 + PHYREGS(0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8),
4887 + RADIOREGS7(0x88, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x85,
4888 + 0x04, 0x08, 0x00, 0x06, 0x00, 0x15, 0x00, 0x00,
4889 + 0x08, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x05,
4890 + 0x21, 0x03, 0x00, 0x00),
4891 + PHYREGS(0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6),
4895 + RADIOREGS7(0x8f, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x89,
4896 + 0x04, 0x07, 0x00, 0x06, 0x00, 0x04, 0x00, 0x00,
4897 + 0x06, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03,
4898 + 0x00, 0x03, 0x00, 0x00),
4899 + PHYREGS(0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4),
4903 + RADIOREGS7(0x95, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x8d,
4904 + 0x04, 0x07, 0x00, 0x05, 0x00, 0x03, 0x00, 0x00,
4905 + 0x05, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03,
4906 + 0x00, 0x03, 0x00, 0x00),
4907 + PHYREGS(0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3),
4911 void r2057_upload_inittabs(struct b43_wldev *dev)
4913 @@ -109,33 +540,98 @@ void r2057_upload_inittabs(struct b43_wl
4917 - if (phy->rev == 7) {
4918 + switch (phy->rev) {
4920 table = r2057_rev4_init[0];
4921 size = ARRAY_SIZE(r2057_rev4_init);
4922 - } else if (phy->rev == 8 || phy->rev == 9) {
4925 if (phy->radio_rev == 5) {
4926 - if (phy->radio_rev == 8) {
4927 - table = r2057_rev5_init[0];
4928 - size = ARRAY_SIZE(r2057_rev5_init);
4930 - table = r2057_rev5a_init[0];
4931 - size = ARRAY_SIZE(r2057_rev5a_init);
4933 + table = r2057_rev5_init[0];
4934 + size = ARRAY_SIZE(r2057_rev5_init);
4935 } else if (phy->radio_rev == 7) {
4936 table = r2057_rev7_init[0];
4937 size = ARRAY_SIZE(r2057_rev7_init);
4938 - } else if (phy->radio_rev == 9) {
4939 - table = r2057_rev8_init[0];
4940 - size = ARRAY_SIZE(r2057_rev8_init);
4944 + if (phy->radio_rev == 5) {
4945 + table = r2057_rev5a_init[0];
4946 + size = ARRAY_SIZE(r2057_rev5a_init);
4950 + if (phy->radio_rev == 9) {
4951 + table = r2057_rev9_init[0];
4952 + size = ARRAY_SIZE(r2057_rev9_init);
4956 + if (phy->radio_rev == 14) {
4957 + table = r2057_rev14_init[0];
4958 + size = ARRAY_SIZE(r2057_rev14_init);
4963 + B43_WARN_ON(!table);
4966 - for (i = 0; i < 10; i++) {
4967 - pr_info("radio_write 0x%X ", *table);
4969 - pr_info("0x%X\n", *table);
4971 + for (i = 0; i < size; i++, table += 2)
4972 + b43_radio_write(dev, table[0], table[1]);
4976 +void r2057_get_chantabent_rev7(struct b43_wldev *dev, u16 freq,
4977 + const struct b43_nphy_chantabent_rev7 **tabent_r7,
4978 + const struct b43_nphy_chantabent_rev7_2g **tabent_r7_2g)
4980 + struct b43_phy *phy = &dev->phy;
4981 + const struct b43_nphy_chantabent_rev7 *e_r7 = NULL;
4982 + const struct b43_nphy_chantabent_rev7_2g *e_r7_2g = NULL;
4983 + unsigned int len, i;
4985 + *tabent_r7 = NULL;
4986 + *tabent_r7_2g = NULL;
4988 + switch (phy->rev) {
4990 + if (phy->radio_rev == 5) {
4991 + e_r7_2g = b43_nphy_chantab_phy_rev8_radio_rev5;
4992 + len = ARRAY_SIZE(b43_nphy_chantab_phy_rev8_radio_rev5);
4996 + if (phy->radio_rev == 9) {
4997 + e_r7 = b43_nphy_chantab_phy_rev16_radio_rev9;
4998 + len = ARRAY_SIZE(b43_nphy_chantab_phy_rev16_radio_rev9);
5002 + if (phy->radio_rev == 14) {
5003 + e_r7_2g = b43_nphy_chantab_phy_rev17_radio_rev14;
5004 + len = ARRAY_SIZE(b43_nphy_chantab_phy_rev17_radio_rev14);
5012 + for (i = 0; i < len; i++, e_r7++) {
5013 + if (e_r7->freq == freq) {
5014 + *tabent_r7 = e_r7;
5018 + } else if (e_r7_2g) {
5019 + for (i = 0; i < len; i++, e_r7_2g++) {
5020 + if (e_r7_2g->freq == freq) {
5021 + *tabent_r7_2g = e_r7_2g;
5029 --- a/drivers/net/wireless/b43/radio_2057.h
5030 +++ b/drivers/net/wireless/b43/radio_2057.h
5032 #define R2057_CMOSBUF_RX_RCCR 0x04c
5033 #define R2057_LOGEN_SEL_PKDET 0x04d
5034 #define R2057_CMOSBUF_SHAREIQ_PTAT 0x04e
5037 #define R2057_RXTXBIAS_CONFIG_CORE0 0x04f
5038 #define R2057_TXGM_TXRF_PUS_CORE0 0x050
5039 #define R2057_TXGM_IDAC_BLEED_CORE0 0x051
5041 #define R2057_RXBB_GPAIOSEL_RXLPF_RCCAL_CORE0 0x0d1
5042 #define R2057_LPF_GAIN_CORE0 0x0d2
5043 #define R2057_DACBUF_IDACS_BW_CORE0 0x0d3
5046 #define R2057_RXTXBIAS_CONFIG_CORE1 0x0d4
5047 #define R2057_TXGM_TXRF_PUS_CORE1 0x0d5
5048 #define R2057_TXGM_IDAC_BLEED_CORE1 0x0d6
5050 #define R2057_RXBB_GPAIOSEL_RXLPF_RCCAL_CORE1 0x156
5051 #define R2057_LPF_GAIN_CORE1 0x157
5052 #define R2057_DACBUF_IDACS_BW_CORE1 0x158
5054 #define R2057_DACBUF_VINCM_CORE1 0x159
5055 #define R2057_RCCAL_START_R1_Q1_P1 0x15a
5056 #define R2057_RCCAL_X1 0x15b
5058 #define R2057_RCCAL_BCAP_VAL 0x16b
5059 #define R2057_RCCAL_HPC_VAL 0x16c
5060 #define R2057_RCCAL_OVERRIDES 0x16d
5063 #define R2057_TX0_IQCAL_GAIN_BW 0x170
5064 #define R2057_TX0_LOFT_FINE_I 0x171
5065 #define R2057_TX0_LOFT_FINE_Q 0x172
5067 #define R2057_TX0_TXRXCOUPLE_2G_PWRUP 0x17e
5068 #define R2057_TX0_TXRXCOUPLE_5G_ATTEN 0x17f
5069 #define R2057_TX0_TXRXCOUPLE_5G_PWRUP 0x180
5072 #define R2057_TX1_IQCAL_GAIN_BW 0x190
5073 #define R2057_TX1_LOFT_FINE_I 0x191
5074 #define R2057_TX1_LOFT_FINE_Q 0x192
5076 #define R2057_TX1_TXRXCOUPLE_2G_PWRUP 0x19e
5077 #define R2057_TX1_TXRXCOUPLE_5G_ATTEN 0x19f
5078 #define R2057_TX1_TXRXCOUPLE_5G_PWRUP 0x1a0
5080 #define R2057_AFE_VCM_CAL_MASTER_CORE0 0x1a1
5081 #define R2057_AFE_SET_VCM_I_CORE0 0x1a2
5082 #define R2057_AFE_SET_VCM_Q_CORE0 0x1a3
5083 @@ -425,6 +435,72 @@
5085 #define R2057_VCM_MASK 0x7
5087 +struct b43_nphy_chantabent_rev7 {
5088 + /* The channel frequency in MHz */
5090 + /* Radio regs values on channelswitch */
5091 + u8 radio_vcocal_countval0;
5092 + u8 radio_vcocal_countval1;
5093 + u8 radio_rfpll_refmaster_sparextalsize;
5094 + u8 radio_rfpll_loopfilter_r1;
5095 + u8 radio_rfpll_loopfilter_c2;
5096 + u8 radio_rfpll_loopfilter_c1;
5097 + u8 radio_cp_kpd_idac;
5098 + u8 radio_rfpll_mmd0;
5099 + u8 radio_rfpll_mmd1;
5100 + u8 radio_vcobuf_tune;
5101 + u8 radio_logen_mx2g_tune;
5102 + u8 radio_logen_mx5g_tune;
5103 + u8 radio_logen_indbuf2g_tune;
5104 + u8 radio_logen_indbuf5g_tune;
5105 + u8 radio_txmix2g_tune_boost_pu_core0;
5106 + u8 radio_pad2g_tune_pus_core0;
5107 + u8 radio_pga_boost_tune_core0;
5108 + u8 radio_txmix5g_boost_tune_core0;
5109 + u8 radio_pad5g_tune_misc_pus_core0;
5110 + u8 radio_lna2g_tune_core0;
5111 + u8 radio_lna5g_tune_core0;
5112 + u8 radio_txmix2g_tune_boost_pu_core1;
5113 + u8 radio_pad2g_tune_pus_core1;
5114 + u8 radio_pga_boost_tune_core1;
5115 + u8 radio_txmix5g_boost_tune_core1;
5116 + u8 radio_pad5g_tune_misc_pus_core1;
5117 + u8 radio_lna2g_tune_core1;
5118 + u8 radio_lna5g_tune_core1;
5119 + /* PHY res values on channelswitch */
5120 + struct b43_phy_n_sfo_cfg phy_regs;
5123 +struct b43_nphy_chantabent_rev7_2g {
5124 + /* The channel frequency in MHz */
5126 + /* Radio regs values on channelswitch */
5127 + u8 radio_vcocal_countval0;
5128 + u8 radio_vcocal_countval1;
5129 + u8 radio_rfpll_refmaster_sparextalsize;
5130 + u8 radio_rfpll_loopfilter_r1;
5131 + u8 radio_rfpll_loopfilter_c2;
5132 + u8 radio_rfpll_loopfilter_c1;
5133 + u8 radio_cp_kpd_idac;
5134 + u8 radio_rfpll_mmd0;
5135 + u8 radio_rfpll_mmd1;
5136 + u8 radio_vcobuf_tune;
5137 + u8 radio_logen_mx2g_tune;
5138 + u8 radio_logen_indbuf2g_tune;
5139 + u8 radio_txmix2g_tune_boost_pu_core0;
5140 + u8 radio_pad2g_tune_pus_core0;
5141 + u8 radio_lna2g_tune_core0;
5142 + u8 radio_txmix2g_tune_boost_pu_core1;
5143 + u8 radio_pad2g_tune_pus_core1;
5144 + u8 radio_lna2g_tune_core1;
5145 + /* PHY regs values on channelswitch */
5146 + struct b43_phy_n_sfo_cfg phy_regs;
5149 void r2057_upload_inittabs(struct b43_wldev *dev);
5151 +void r2057_get_chantabent_rev7(struct b43_wldev *dev, u16 freq,
5152 + const struct b43_nphy_chantabent_rev7 **tabent_r7,
5153 + const struct b43_nphy_chantabent_rev7_2g **tabent_r7_2g);
5155 #endif /* B43_RADIO_2057_H_ */
5156 --- a/drivers/net/wireless/b43/tables_nphy.h
5157 +++ b/drivers/net/wireless/b43/tables_nphy.h
5158 @@ -165,6 +165,10 @@ struct nphy_gain_ctl_workaround_entry *b
5159 #define B43_NTAB_C1_LOFEEDTH_R3 B43_NTAB16(27, 448) /* Local Oscillator Feed Through lookup 1 */
5160 #define B43_NTAB_C1_PAPD_COMP_R3 B43_NTAB16(27, 576)
5162 +/* Static N-PHY tables, PHY revision >= 7 */
5163 +#define B43_NTAB_TMAP_R7 B43_NTAB32(12, 0) /* TM AP */
5164 +#define B43_NTAB_NOISEVAR_R7 B43_NTAB32(16, 0) /* noise variance */
5166 #define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_40_SIZE 18
5167 #define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_20_SIZE 18
5168 #define B43_NTAB_TX_IQLO_CAL_IQIMB_LADDER_40_SIZE 18
5169 --- a/drivers/net/wireless/b43/xmit.c
5170 +++ b/drivers/net/wireless/b43/xmit.c
5171 @@ -80,9 +80,10 @@ static int b43_plcp_get_bitrate_idx_cck(
5174 /* Extract the bitrate index out of an OFDM PLCP header. */
5175 -static int b43_plcp_get_bitrate_idx_ofdm(struct b43_plcp_hdr6 *plcp, bool aphy)
5176 +static int b43_plcp_get_bitrate_idx_ofdm(struct b43_plcp_hdr6 *plcp, bool ghz5)
5178 - int base = aphy ? 0 : 4;
5179 + /* For 2 GHz band first OFDM rate is at index 4, see main.c */
5180 + int base = ghz5 ? 0 : 4;
5182 switch (plcp->raw[0] & 0xF) {
5184 @@ -767,7 +768,7 @@ void b43_rx(struct b43_wldev *dev, struc
5186 if (phystat0 & B43_RX_PHYST0_OFDM)
5187 rate_idx = b43_plcp_get_bitrate_idx_ofdm(plcp,
5188 - phytype == B43_PHYTYPE_A);
5189 + !!(chanstat & B43_RX_CHAN_5GHZ));
5191 rate_idx = b43_plcp_get_bitrate_idx_cck(plcp);
5192 if (unlikely(rate_idx == -1)) {
5193 --- a/.local-symbols
5194 +++ b/.local-symbols
5195 @@ -176,6 +176,7 @@ B43_PCMCIA=