brcm2708: switch to 3.14
[openwrt.git] / package / kernel / mac80211 / patches / 800-b43-backports-form-wireless-testing-master-master-20.patch
1 backport b43 patches from wireless testing
2
3 This brings b43 up to wireless-testing/master master-2014-07-29-1
4
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),
16         BCMA_CORETABLE_END
17  };
18  MODULE_DEVICE_TABLE(bcma, b43_bcma_tbl);
19 @@ -206,6 +210,9 @@ static struct ieee80211_channel b43_2ghz
20         CHAN2G(13, 2472, 0),
21         CHAN2G(14, 2484, 0),
22  };
23 +
24 +/* No support for the last 3 channels (12, 13, 14) */
25 +#define b43_2ghz_chantable_limited_size                11
26  #undef CHAN2G
27  
28  #define CHAN4G(_channel, _flags) {                             \
29 @@ -283,6 +290,14 @@ static struct ieee80211_channel b43_5ghz
30         CHAN5G(182, 0),
31  };
32  
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),
38 +       CHAN5G(165, 0),
39 +};
40 +
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,
46  };
47  
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,
54 +};
55 +
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,
61  };
62  
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,
69 +};
70 +
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:
75         return -EPROTO;
76  }
77  
78 +/* http://bcm-v4.sipsolutions.net/802.11/Init/Firmware */
79  static int b43_try_request_fw(struct b43_request_fw_context *ctx)
80  {
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;
85         const char *filename;
86 -       u32 tmshigh;
87         int err;
88  
89 -       /* Files for HT and LCN were found by trying one by one */
90 -
91         /* Get microcode */
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) {
101 +       filename = NULL;
102 +       switch (rev) {
103 +       case 42:
104 +               if (phy->type == B43_PHYTYPE_AC)
105 +                       filename = "ucode42";
106 +               break;
107 +       case 40:
108 +               if (phy->type == B43_PHYTYPE_AC)
109 +                       filename = "ucode40";
110 +               break;
111 +       case 33:
112 +               if (phy->type == B43_PHYTYPE_LCN40)
113 +                       filename = "ucode33_lcn40";
114 +               break;
115 +       case 30:
116 +               if (phy->type == B43_PHYTYPE_N)
117 +                       filename = "ucode30_mimo";
118 +               break;
119 +       case 29:
120 +               if (phy->type == B43_PHYTYPE_HT)
121 +                       filename = "ucode29_mimo";
122 +               break;
123 +       case 26:
124 +               if (phy->type == B43_PHYTYPE_HT)
125 +                       filename = "ucode26_mimo";
126 +               break;
127 +       case 28:
128 +       case 25:
129 +               if (phy->type == B43_PHYTYPE_N)
130 +                       filename = "ucode25_mimo";
131 +               else if (phy->type == B43_PHYTYPE_LCN)
132 +                       filename = "ucode25_lcn";
133 +               break;
134 +       case 24:
135 +               if (phy->type == B43_PHYTYPE_LCN)
136 +                       filename = "ucode24_lcn";
137 +               break;
138 +       case 23:
139 +               if (phy->type == B43_PHYTYPE_N)
140 +                       filename = "ucode16_mimo";
141 +               break;
142 +       case 16 ... 19:
143 +               if (phy->type == B43_PHYTYPE_N)
144 +                       filename = "ucode16_mimo";
145 +               else if (phy->type == B43_PHYTYPE_LP)
146 +                       filename = "ucode16_lp";
147 +               break;
148 +       case 15:
149                 filename = "ucode15";
150 -       } else {
151 -               switch (dev->phy.type) {
152 -               case B43_PHYTYPE_N:
153 -                       if (rev >= 16)
154 -                               filename = "ucode16_mimo";
155 -                       else
156 -                               goto err_no_ucode;
157 -                       break;
158 -               case B43_PHYTYPE_HT:
159 -                       if (rev == 29)
160 -                               filename = "ucode29_mimo";
161 -                       else
162 -                               goto err_no_ucode;
163 -                       break;
164 -               case B43_PHYTYPE_LCN:
165 -                       if (rev == 24)
166 -                               filename = "ucode24_mimo";
167 -                       else
168 -                               goto err_no_ucode;
169 -                       break;
170 -               default:
171 -                       goto err_no_ucode;
172 -               }
173 +               break;
174 +       case 14:
175 +               filename = "ucode14";
176 +               break;
177 +       case 13:
178 +               filename = "ucode13";
179 +               break;
180 +       case 11 ... 12:
181 +               filename = "ucode11";
182 +               break;
183 +       case 5 ... 10:
184 +               filename = "ucode5";
185 +               break;
186         }
187 +       if (!filename)
188 +               goto err_no_ucode;
189         err = b43_do_request_fw(ctx, filename, &fw->ucode, true);
190         if (err)
191                 goto err_load;
192 @@ -2268,117 +2329,121 @@ static int b43_try_request_fw(struct b43
193                 goto err_load;
194  
195         /* Get initvals */
196 +       filename = NULL;
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";
203 -                       else
204 -                               filename = "a0g0initvals5";
205 -               } else
206 -                       goto err_no_initvals;
207 -               break;
208         case B43_PHYTYPE_G:
209 -               if ((rev >= 5) && (rev <= 10))
210 -                       filename = "b0g0initvals5";
211 -               else if (rev >= 13)
212 +               if (rev == 13)
213                         filename = "b0g0initvals13";
214 -               else
215 -                       goto err_no_initvals;
216 +               else if (rev >= 5 && rev <= 10)
217 +                       filename = "b0g0initvals5";
218                 break;
219         case B43_PHYTYPE_N:
220 -               if (rev >= 16)
221 +               if (rev == 30)
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";
234 -               else
235 -                       goto err_no_initvals;
236                 break;
237         case B43_PHYTYPE_LP:
238 -               if (rev == 13)
239 -                       filename = "lp0initvals13";
240 +               if (rev >= 16 && rev <= 18)
241 +                       filename = "lp0initvals16";
242 +               else if (rev == 15)
243 +                       filename = "lp0initvals15";
244                 else if (rev == 14)
245                         filename = "lp0initvals14";
246 -               else if (rev >= 15)
247 -                       filename = "lp0initvals15";
248 -               else
249 -                       goto err_no_initvals;
250 +               else if (rev == 13)
251 +                       filename = "lp0initvals13";
252                 break;
253         case B43_PHYTYPE_HT:
254                 if (rev == 29)
255                         filename = "ht0initvals29";
256 -               else
257 -                       goto err_no_initvals;
258 +               else if (rev == 26)
259 +                       filename = "ht0initvals26";
260                 break;
261         case B43_PHYTYPE_LCN:
262                 if (rev == 24)
263                         filename = "lcn0initvals24";
264 -               else
265 -                       goto err_no_initvals;
266                 break;
267 -       default:
268 -               goto err_no_initvals;
269 +       case B43_PHYTYPE_LCN40:
270 +               if (rev == 33)
271 +                       filename = "lcn400initvals33";
272 +               break;
273 +       case B43_PHYTYPE_AC:
274 +               if (rev == 42)
275 +                       filename = "ac1initvals42";
276 +               else if (rev == 40)
277 +                       filename = "ac0initvals40";
278 +               break;
279         }
280 +       if (!filename)
281 +               goto err_no_initvals;
282         err = b43_do_request_fw(ctx, filename, &fw->initvals, false);
283         if (err)
284                 goto err_load;
285  
286         /* Get bandswitch initvals */
287 +       filename = NULL;
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";
294 -                       else
295 -                               filename = "a0g0bsinitvals5";
296 -               } else if (rev >= 11)
297 -                       filename = NULL;
298 -               else
299 -                       goto err_no_initvals;
300 -               break;
301         case B43_PHYTYPE_G:
302 -               if ((rev >= 5) && (rev <= 10))
303 +               if (rev == 13)
304 +                       filename = "b0g0bsinitvals13";
305 +               else if (rev >= 5 && rev <= 10)
306                         filename = "b0g0bsinitvals5";
307 -               else if (rev >= 11)
308 -                       filename = NULL;
309 -               else
310 -                       goto err_no_initvals;
311                 break;
312         case B43_PHYTYPE_N:
313 -               if (rev >= 16)
314 +               if (rev == 30)
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";
327 -               else
328 -                       goto err_no_initvals;
329                 break;
330         case B43_PHYTYPE_LP:
331 -               if (rev == 13)
332 -                       filename = "lp0bsinitvals13";
333 +               if (rev >= 16 && rev <= 18)
334 +                       filename = "lp0bsinitvals16";
335 +               else if (rev == 15)
336 +                       filename = "lp0bsinitvals15";
337                 else if (rev == 14)
338                         filename = "lp0bsinitvals14";
339 -               else if (rev >= 15)
340 -                       filename = "lp0bsinitvals15";
341 -               else
342 -                       goto err_no_initvals;
343 +               else if (rev == 13)
344 +                       filename = "lp0bsinitvals13";
345                 break;
346         case B43_PHYTYPE_HT:
347                 if (rev == 29)
348                         filename = "ht0bsinitvals29";
349 -               else
350 -                       goto err_no_initvals;
351 +               else if (rev == 26)
352 +                       filename = "ht0bsinitvals26";
353                 break;
354         case B43_PHYTYPE_LCN:
355                 if (rev == 24)
356                         filename = "lcn0bsinitvals24";
357 -               else
358 -                       goto err_no_initvals;
359                 break;
360 -       default:
361 -               goto err_no_initvals;
362 +       case B43_PHYTYPE_LCN40:
363 +               if (rev == 33)
364 +                       filename = "lcn400bsinitvals33";
365 +               break;
366 +       case B43_PHYTYPE_AC:
367 +               if (rev == 42)
368 +                       filename = "ac1bsinitvals42";
369 +               else if (rev == 40)
370 +                       filename = "ac0bsinitvals40";
371 +               break;
372         }
373 +       if (!filename)
374 +               goto err_no_initvals;
375         err = b43_do_request_fw(ctx, filename, &fw->initvals_band, false);
376         if (err)
377                 goto err_load;
378 @@ -2915,6 +2980,46 @@ void b43_mac_phy_clock_set(struct b43_wl
379         }
380  }
381  
382 +/* brcms_b_switch_macfreq */
383 +void b43_mac_switch_freq(struct b43_wldev *dev, u8 spurmode)
384 +{
385 +       u16 chip_id = dev->dev->chip_id;
386 +
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);
398 +                       break;
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);
402 +                       break;
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);
406 +                       break;
407 +               }
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);
413 +                       break;
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);
417 +                       break;
418 +               }
419 +       }
420 +}
421 +
422  static void b43_adjust_opmode(struct b43_wldev *dev)
423  {
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));
428  
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);
433  
434         phy->gmode = gmode;
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)
438  {
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;
445         int antenna;
446         int err = 0;
447 -       bool reload_bss = false;
448  
449         mutex_lock(&wl->mutex);
450 -
451 -       dev = wl->current_dev;
452 -
453         b43_mac_suspend(dev);
454  
455 -       /* Switch the band (if necessary). This might change the active core. */
456 -       err = b43_switch_band(dev, conf->chandef.chan);
457 -       if (err)
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;
462  
463 -       /* Need to reload all settings if the core changed */
464 -       if (dev != wl->current_dev) {
465 -               dev = wl->current_dev;
466 -               changed = ~0;
467 -               reload_bss = true;
468 -       }
469 +               /* Switch the band (if necessary). */
470 +               err = b43_switch_band(dev, conf->chandef.chan);
471 +               if (err)
472 +                       goto out_mac_enable;
473  
474 -       phy = &dev->phy;
475 -
476 -       if (conf_is_ht(conf))
477 -               phy->is_40mhz =
478 -                       (conf_is_ht40_minus(conf) || conf_is_ht40_plus(conf));
479 -       else
480 -               phy->is_40mhz = false;
481 +               /* Switch to the requested channel.
482 +                * The firmware takes care of races with the TX handler.
483 +                */
484 +               b43_switch_channel(dev, phy->channel);
485 +       }
486  
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
490         if (!changed)
491                 goto out_mac_enable;
492  
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);
497 -
498         dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_MONITOR);
499  
500         /* Adjust the desired TX power level. */
501 @@ -3876,12 +3969,8 @@ static int b43_op_config(struct ieee8021
502  
503  out_mac_enable:
504         b43_mac_enable(dev);
505 -out_unlock_mutex:
506         mutex_unlock(&wl->mutex);
507  
508 -       if (wl->vif && reload_bss)
509 -               b43_op_bss_info_changed(hw, wl->vif, &wl->vif->bss_conf, ~0);
510 -
511         return err;
512  }
513  
514 @@ -4307,13 +4396,15 @@ static char *b43_phy_name(struct b43_wld
515  static int b43_phy_versioning(struct b43_wldev *dev)
516  {
517         struct b43_phy *phy = &dev->phy;
518 +       const u8 core_rev = dev->dev->core_rev;
519         u32 tmp;
520         u8 analog_type;
521         u8 phy_type;
522         u8 phy_rev;
523         u16 radio_manuf;
524 -       u16 radio_ver;
525 +       u16 radio_id;
526         u16 radio_rev;
527 +       u8 radio_ver;
528         int unsupported = 0;
529  
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);
535 +
536 +       /* LCNXN is continuation of N which run out of revisions */
537 +       if (phy_type == B43_PHYTYPE_LCNXN) {
538 +               phy_type = B43_PHYTYPE_N;
539 +               phy_rev += 16;
540 +       }
541 +
542         switch (phy_type) {
543 -       case B43_PHYTYPE_A:
544 -               if (phy_rev >= 4)
545 -                       unsupported = 1;
546 -               break;
547 -       case B43_PHYTYPE_B:
548 -               if (phy_rev != 2 && phy_rev != 4 && phy_rev != 6
549 -                   && phy_rev != 7)
550 -                       unsupported = 1;
551 -               break;
552 +#ifdef CPTCFG_B43_PHY_G
553         case B43_PHYTYPE_G:
554                 if (phy_rev > 9)
555                         unsupported = 1;
556                 break;
557 +#endif
558  #ifdef CPTCFG_B43_PHY_N
559         case B43_PHYTYPE_N:
560 -               if (phy_rev > 9)
561 +               if (phy_rev >= 19)
562                         unsupported = 1;
563                 break;
564  #endif
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);
567  
568         /* Get RADIO versioning */
569 -       if (dev->dev->core_rev >= 24) {
570 +       if (core_rev == 40 || core_rev == 42) {
571 +               radio_manuf = 0x17F;
572 +
573 +               b43_write16(dev, B43_MMIO_RADIO24_CONTROL, 0);
574 +               radio_rev = b43_read16(dev, B43_MMIO_RADIO24_DATA);
575 +
576 +               b43_write16(dev, B43_MMIO_RADIO24_CONTROL, 1);
577 +               radio_id = b43_read16(dev, B43_MMIO_RADIO24_DATA);
578 +
579 +               radio_ver = 0; /* Is there version somewhere? */
580 +       } else if (core_rev >= 24) {
581                 u16 radio24[3];
582  
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);
586                 }
587  
588 -               /* Broadcom uses "id" for our "ver" and has separated "ver" */
589 -               /* radio_ver = (radio24[0] & 0xF0) >> 4; */
590 -
591                 radio_manuf = 0x17F;
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;
596         } else {
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
600                                 << 16;
601                 }
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 */
607         }
608  
609         if (radio_manuf != 0x17F /* Broadcom */)
610                 unsupported = 1;
611         switch (phy_type) {
612         case B43_PHYTYPE_A:
613 -               if (radio_ver != 0x2060)
614 +               if (radio_id != 0x2060)
615                         unsupported = 1;
616                 if (radio_rev != 1)
617                         unsupported = 1;
618 @@ -4420,43 +4520,49 @@ static int b43_phy_versioning(struct b43
619                         unsupported = 1;
620                 break;
621         case B43_PHYTYPE_B:
622 -               if ((radio_ver & 0xFFF0) != 0x2050)
623 +               if ((radio_id & 0xFFF0) != 0x2050)
624                         unsupported = 1;
625                 break;
626         case B43_PHYTYPE_G:
627 -               if (radio_ver != 0x2050)
628 +               if (radio_id != 0x2050)
629                         unsupported = 1;
630                 break;
631         case B43_PHYTYPE_N:
632 -               if (radio_ver != 0x2055 && radio_ver != 0x2056)
633 +               if (radio_id != 0x2055 && radio_id != 0x2056 &&
634 +                   radio_id != 0x2057)
635 +                       unsupported = 1;
636 +               if (radio_id == 0x2057 &&
637 +                   !(radio_rev == 9 || radio_rev == 14))
638                         unsupported = 1;
639                 break;
640         case B43_PHYTYPE_LP:
641 -               if (radio_ver != 0x2062 && radio_ver != 0x2063)
642 +               if (radio_id != 0x2062 && radio_id != 0x2063)
643                         unsupported = 1;
644                 break;
645         case B43_PHYTYPE_HT:
646 -               if (radio_ver != 0x2059)
647 +               if (radio_id != 0x2059)
648                         unsupported = 1;
649                 break;
650         case B43_PHYTYPE_LCN:
651 -               if (radio_ver != 0x2064)
652 +               if (radio_id != 0x2064)
653                         unsupported = 1;
654                 break;
655         default:
656                 B43_WARN_ON(1);
657         }
658         if (unsupported) {
659 -               b43err(dev->wl, "FOUND UNSUPPORTED RADIO "
660 -                      "(Manuf 0x%X, Version 0x%X, Revision %u)\n",
661 -                      radio_manuf, radio_ver, radio_rev);
662 +               b43err(dev->wl,
663 +                      "FOUND UNSUPPORTED RADIO (Manuf 0x%X, ID 0x%X, Revision %u, Version %u)\n",
664 +                      radio_manuf, radio_id, radio_rev, radio_ver);
665                 return -EOPNOTSUPP;
666         }
667 -       b43dbg(dev->wl, "Found Radio: Manuf 0x%X, Version 0x%X, Revision %u\n",
668 -              radio_manuf, radio_ver, radio_rev);
669 +       b43info(dev->wl,
670 +               "Found Radio: Manuf 0x%X, ID 0x%X, Revision %u, Version %u\n",
671 +               radio_manuf, radio_id, radio_rev, radio_ver);
672  
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;
678  
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)
682  {
683         struct ieee80211_hw *hw = dev->wl->hw;
684 +       struct b43_phy *phy = &dev->phy;
685 +       bool limited_2g;
686 +       bool limited_5g;
687 +
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;
693  
694         if (have_2ghz_phy)
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) {
699                 if (have_5ghz_phy)
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;
704         } else {
705                 if (have_5ghz_phy)
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)
709  {
710         struct b43_wl *wl = dev->wl;
711 +       struct b43_phy *phy = &dev->phy;
712         int err;
713         u32 tmp;
714         bool have_2ghz_phy = false, have_5ghz_phy = false;
715 @@ -5181,6 +5300,8 @@ static int b43_wireless_core_attach(stru
716                 goto out;
717         }
718  
719 +       phy->do_full_init = true;
720 +
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);
726  
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;
744 +               }
745         }
746  
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);
755  
756  
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
761         phy->ops = NULL;
762  
763         switch (phy->type) {
764 -       case B43_PHYTYPE_A:
765 -               phy->ops = &b43_phyops_a;
766 -               break;
767         case B43_PHYTYPE_G:
768 +#ifdef CPTCFG_B43_PHY_G
769                 phy->ops = &b43_phyops_g;
770 +#endif
771                 break;
772         case B43_PHYTYPE_N:
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;
776         int err;
777  
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.
781 +        */
782 +       if (!phy->chandef) {
783 +               phy->chandef = &dev->wl->hw->conf.chandef;
784 +               phy->channel = phy->chandef->chan->hw_value;
785 +       }
786  
787         phy->ops->switch_analog(dev, true);
788         b43_software_rfkill(dev, false);
789 +
790         err = ops->init(dev);
791         if (err) {
792                 b43err(dev->wl, "PHY init failed\n");
793                 goto err_block_rf;
794         }
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;
799 +
800 +       err = b43_switch_channel(dev, phy->channel);
801         if (err) {
802                 b43err(dev->wl, "PHY init: Channel switch to default failed\n");
803                 goto err_phy_exit;
804 @@ -114,6 +120,7 @@ int b43_phy_init(struct b43_wldev *dev)
805         return 0;
806  
807  err_phy_exit:
808 +       phy->do_full_init = true;
809         if (ops->exit)
810                 ops->exit(dev);
811  err_block_rf:
812 @@ -127,6 +134,7 @@ void b43_phy_exit(struct b43_wldev *dev)
813         const struct b43_phy_operations *ops = dev->phy.ops;
814  
815         b43_software_rfkill(dev, true);
816 +       dev->phy.do_full_init = true;
817         if (ops->exit)
818                 ops->exit(dev);
819  }
820 @@ -403,9 +411,6 @@ int b43_switch_channel(struct b43_wldev
821         u16 channelcookie, savedcookie;
822         int err;
823  
824 -       if (new_channel == B43_DEFAULT_CHANNEL)
825 -               new_channel = phy->ops->get_default_chan(dev);
826 -
827         /* First we set the channel radio code to prevent the
828          * firmware from sending ghost packets.
829          */
830 @@ -423,7 +428,6 @@ int b43_switch_channel(struct b43_wldev
831         if (err)
832                 goto err_restore_cookie;
833  
834 -       dev->phy.channel = new_channel;
835         /* Wait for the radio to tune to the channel and stabilize. */
836         msleep(8);
837  
838 @@ -542,10 +546,9 @@ void b43_phyop_switch_analog_generic(str
839  }
840  
841  
842 -bool b43_channel_type_is_40mhz(enum nl80211_channel_type channel_type)
843 +bool b43_is_40mhz(struct b43_wldev *dev)
844  {
845 -       return (channel_type == NL80211_CHAN_HT40MINUS ||
846 -               channel_type == NL80211_CHAN_HT40PLUS);
847 +       return dev->phy.chandef->width == NL80211_CHAN_WIDTH_40;
848  }
849  
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 {
854         bool supports_2ghz;
855         bool supports_5ghz;
856  
857 -       /* HT info */
858 -       bool is_40mhz;
859 -
860         /* Is GMODE (2 GHz mode) bit enabled? */
861         bool gmode;
862  
863 +       /* After power reset full init has to be performed */
864 +       bool do_full_init;
865 +
866         /* Analog Type */
867         u8 analog;
868         /* B43_PHYTYPE_ */
869 @@ -264,9 +264,8 @@ struct b43_phy {
870         unsigned long next_txpwr_check_time;
871  
872         /* Current channel */
873 +       struct cfg80211_chan_def *chandef;
874         unsigned int channel;
875 -       u16 channel_freq;
876 -       enum nl80211_channel_type channel_type;
877  
878         /* PHY TX errors counter. */
879         atomic_t txerr_cnt;
880 @@ -397,10 +396,6 @@ void b43_phy_take_out_of_reset(struct b4
881   * b43_switch_channel - Switch to another channel
882   */
883  int b43_switch_channel(struct b43_wldev *dev, unsigned int new_channel);
884 -/**
885 - * B43_DEFAULT_CHANNEL - Switch to the default channel.
886 - */
887 -#define B43_DEFAULT_CHANNEL    UINT_MAX
888  
889  /**
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
892   */
893  void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on);
894  
895 -bool b43_channel_type_is_40mhz(enum nl80211_channel_type channel_type);
896 +bool b43_is_40mhz(struct b43_wldev *dev);
897  
898  void b43_phy_force_clock(struct b43_wldev *dev, bool force);
899  
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 {
903         B43_SENSE_VBAT,
904  };
905  
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)
909 -{
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);
915 -                       break;
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);
919 -                       break;
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);
923 -                       break;
924 -               }
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);
930 -                       break;
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);
934 -                       break;
935 -               }
936 -       }
937 -}
938 -
939  /**************************************************
940   * Radio 2064.
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));
945         }
946 -       b43_phy_switch_macfreq(dev, enable);
947 +       b43_mac_switch_freq(dev, enable);
948  }
949  
950  /**************************************************
951 --- a/drivers/net/wireless/b43/phy_n.c
952 +++ b/drivers/net/wireless/b43/phy_n.c
953 @@ -36,6 +36,7 @@
954  #include "main.h"
955  
956  struct nphy_txgains {
957 +       u16 tx_lpf[2];
958         u16 txgm[2];
959         u16 pga[2];
960         u16 pad[2];
961 @@ -43,6 +44,7 @@ struct nphy_txgains {
962  };
963  
964  struct nphy_iqcal_params {
965 +       u16 tx_lpf;
966         u16 txgm;
967         u16 pga;
968         u16 pad;
969 @@ -69,6 +71,14 @@ enum b43_nphy_rf_sequence {
970         B43_RFSEQ_UPDATE_GAINU,
971  };
972  
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,
979 +};
980 +
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);
986  }
987  
988 +static void b43_nphy_rf_ctl_override_rev19(struct b43_wldev *dev, u16 field,
989 +                                          u16 value, u8 core, bool off,
990 +                                          u8 override_id)
991 +{
992 +       /* TODO */
993 +}
994 +
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,
998                                           u8 override)
999  {
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
1005         u16 val_addr;
1006         u8 i;
1007  
1008 +       if (phy->rev >= 19 || phy->rev < 3) {
1009 +               B43_WARN_ON(1);
1010 +               return;
1011 +       }
1012 +
1013         /* Remember: we can get NULL! */
1014         e = b43_nphy_get_rf_ctl_over_rev7(dev, field, override);
1015  
1016 @@ -181,6 +204,50 @@ static void b43_nphy_rf_ctl_override_rev
1017         }
1018  }
1019  
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)
1024 +{
1025 +       struct b43_phy *phy = &dev->phy;
1026 +       u16 tmp;
1027 +
1028 +       B43_WARN_ON(phy->rev < 7);
1029 +
1030 +       switch (cmd) {
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);
1035 +               break;
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);
1042 +               break;
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);
1048 +               break;
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);
1052 +               tmp = value >> 8;
1053 +               b43_nphy_rf_ctl_override_rev7(dev, 0x6000, tmp, core, off, 0);
1054 +               break;
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);
1060 +               break;
1061 +       }
1062 +}
1063 +
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;
1069         int core;
1070  
1071 +       /* TODO: What about rev19+? Revs 3+ and 7+ are a bit similar */
1072 +
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);
1082                         break;
1083                 case N_INTC_OVERRIDE_TRSW:
1084 @@ -505,6 +575,14 @@ static void b43_nphy_stay_in_carrier_sea
1085         }
1086  }
1087  
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)
1090 +{
1091 +       if (!offset)
1092 +               offset = b43_is_40mhz(dev) ? 0x159 : 0x154;
1093 +       return b43_ntab_read(dev, B43_NTAB16(7, offset)) & 0x7;
1094 +}
1095 +
1096  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/AdjustLnaGainTbl */
1097  static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev)
1098  {
1099 @@ -590,44 +668,270 @@ static void b43_nphy_set_rf_sequence(str
1100   * Radio 0x2057
1101   **************************************************/
1102  
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)
1107 +{
1108 +       if (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);
1127 +
1128 +       } else {
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);
1157 +       }
1158 +}
1159 +
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)
1163 +{
1164 +       struct b43_phy *phy = &dev->phy;
1165 +
1166 +       b43_radio_2057_chantab_upload(dev, tabent_r7, tabent_r7_2g);
1167 +
1168 +       switch (phy->radio_rev) {
1169 +       case 0 ... 4:
1170 +       case 6:
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);
1176 +               } else {
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);
1181 +               }
1182 +               break;
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);
1189 +
1190 +                       if (b43_is_40mhz(dev)) {
1191 +                               /* TODO */
1192 +                       } else {
1193 +                               b43_radio_write(dev,
1194 +                                               R2057_PAD_BIAS_FILTER_BWS_CORE0,
1195 +                                               0x3c);
1196 +                               b43_radio_write(dev,
1197 +                                               R2057_PAD_BIAS_FILTER_BWS_CORE1,
1198 +                                               0x3c);
1199 +                       }
1200 +               }
1201 +               break;
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);
1207 +               break;
1208 +       }
1209 +
1210 +       if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
1211 +               u16 txmix2g_tune_boost_pu = 0;
1212 +               u16 pad2g_tune_pus = 0;
1213 +
1214 +               if (b43_nphy_ipa(dev)) {
1215 +                       switch (phy->radio_rev) {
1216 +                       case 9:
1217 +                               txmix2g_tune_boost_pu = 0x0041;
1218 +                               /* TODO */
1219 +                               break;
1220 +                       case 14:
1221 +                               txmix2g_tune_boost_pu = 0x21;
1222 +                               pad2g_tune_pus = 0x23;
1223 +                               break;
1224 +                       }
1225 +               }
1226 +
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,
1232 +                                       pad2g_tune_pus);
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,
1238 +                                       pad2g_tune_pus);
1239 +       }
1240 +
1241 +       usleep_range(50, 100);
1242 +
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);
1249 +}
1250 +
1251 +/* Calibrate resistors in LPF of PLL?
1252 + * http://bcm-v4.sipsolutions.net/PHY/radio205x_rcal
1253 + */
1254  static u8 b43_radio_2057_rcal(struct b43_wldev *dev)
1255  {
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,
1267 +       };
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,
1272 +       };
1273         u16 tmp;
1274 +       int i;
1275  
1276 -       if (phy->radio_rev == 5) {
1277 -               b43_phy_mask(dev, 0x342, ~0x2);
1278 +       /* Save */
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]);
1283 +
1284 +       /* Set */
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);
1293 +
1294 +       switch (phy->radio_rev) {
1295 +       case 5:
1296 +               b43_phy_mask(dev, B43_NPHY_REV7_RF_CTL_OVER3, ~0x2);
1297                 udelay(10);
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);
1301 +               break;
1302 +       case 9:
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);
1307 +               break;
1308 +       case 14:
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);
1315 +               break;
1316         }
1317  
1318 +       /* Enable */
1319         b43_radio_set(dev, R2057_RCAL_CONFIG, 0x1);
1320         udelay(10);
1321 -       b43_radio_set(dev, R2057_RCAL_CONFIG, 0x3);
1322 -       if (!b43_radio_wait_value(dev, R2057_RCCAL_N1_1, 1, 1, 100, 1000000)) {
1323 +
1324 +       /* Start */
1325 +       b43_radio_set(dev, R2057_RCAL_CONFIG, 0x2);
1326 +       usleep_range(100, 200);
1327 +
1328 +       /* Stop */
1329 +       b43_radio_mask(dev, R2057_RCAL_CONFIG, ~0x2);
1330 +
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");
1334                 return 0;
1335         }
1336 -       b43_radio_mask(dev, R2057_RCAL_CONFIG, ~0x2);
1337         tmp = b43_radio_read(dev, R2057_RCAL_STATUS) & 0x3E;
1338 +
1339 +       /* Disable */
1340         b43_radio_mask(dev, R2057_RCAL_CONFIG, ~0x1);
1341  
1342 -       if (phy->radio_rev == 5) {
1343 -               b43_radio_mask(dev, R2057_IPA2G_CASCONV_CORE0, ~0x1);
1344 -               b43_radio_mask(dev, 0x1ca, ~0x2);
1345 -       }
1346 -       if (phy->radio_rev <= 4 || phy->radio_rev == 6) {
1347 +       /* Restore */
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]);
1352 +
1353 +       switch (phy->radio_rev) {
1354 +       case 0 ... 4:
1355 +       case 6:
1356                 b43_radio_maskset(dev, R2057_TEMPSENSE_CONFIG, ~0x3C, tmp);
1357                 b43_radio_maskset(dev, R2057_BANDGAP_RCAL_TRIM, ~0xF0,
1358                                   tmp << 2);
1359 +               break;
1360 +       case 5:
1361 +               b43_radio_mask(dev, R2057_IPA2G_CASCONV_CORE0, ~0x1);
1362 +               b43_radio_mask(dev, R2057v7_IQTEST_SEL_PU2, ~0x2);
1363 +               break;
1364 +       case 9:
1365 +               b43_radio_write(dev, R2057_IQTEST_SEL_PU, saved_regs_radio[0]);
1366 +               break;
1367 +       case 14:
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]);
1370 +               break;
1371         }
1372  
1373         return tmp & 0x3e;
1374  }
1375  
1376 -/* http://bcm-v4.sipsolutions.net/PHY/radio2057_rccal */
1377 +/* Calibrate the internal RC oscillator?
1378 + * http://bcm-v4.sipsolutions.net/PHY/radio2057_rccal
1379 + */
1380  static u16 b43_radio_2057_rccal(struct b43_wldev *dev)
1381  {
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);
1385         u16 tmp;
1386  
1387 +       /* Setup cal */
1388         if (special) {
1389                 b43_radio_write(dev, R2057_RCCAL_MASTER, 0x61);
1390                 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xC0);
1391         } else {
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);
1396         }
1397         b43_radio_write(dev, R2057_RCCAL_X1, 0x6E);
1398 +
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,
1403                                   5000000))
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);
1408 +
1409 +       /* Setup cal */
1410         if (special) {
1411                 b43_radio_write(dev, R2057_RCCAL_MASTER, 0x69);
1412                 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xB0);
1413         } else {
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);
1417         }
1418         b43_radio_write(dev, R2057_RCCAL_X1, 0x6E);
1419 +
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,
1426                                   5000000))
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);
1431 +
1432 +       /* Setup cal */
1433         if (special) {
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);
1437         } else {
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);
1442         }
1443 +
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,
1450                                   5000000)) {
1451                 b43err(dev->wl, "Radio 0x2057 rcal timeout\n");
1452                 return 0;
1453         }
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);
1458 +
1459 +       if (special)
1460 +               b43_radio_mask(dev, R2057_RCCAL_MASTER, ~0x1);
1461 +       else
1462 +               b43_radio_mask(dev, R2057v7_RCCAL_MASTER, ~0x1);
1463 +
1464         return tmp;
1465  }
1466  
1467 @@ -694,19 +1025,20 @@ static void b43_radio_2057_init_post(str
1468  {
1469         b43_radio_set(dev, R2057_XTALPUOVR_PINCTRL, 0x1);
1470  
1471 +       if (0) /* FIXME: Is this BCM43217 specific? */
1472 +               b43_radio_set(dev, R2057_XTALPUOVR_PINCTRL, 0x2);
1473 +
1474         b43_radio_set(dev, R2057_RFPLL_MISC_CAL_RESETN, 0x78);
1475         b43_radio_set(dev, R2057_XTAL_CONFIG2, 0x80);
1476         mdelay(2);
1477         b43_radio_mask(dev, R2057_RFPLL_MISC_CAL_RESETN, ~0x78);
1478         b43_radio_mask(dev, R2057_XTAL_CONFIG2, ~0x80);
1479  
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);
1484         }
1485         b43_radio_mask(dev, R2057_RFPLL_MASTER, ~0x8);
1486 -
1487 -       dev->phy.n->init_por = false;
1488  }
1489  
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)
1494  {
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);
1498         u16 offset;
1499 @@ -897,7 +1230,7 @@ static void b43_radio_2056_setup(struct
1500                                         offset | B2056_TX_MIXG_BOOST_TUNE,
1501                                         mixg_boost);
1502                         } else {
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,
1507                                         bias);
1508 @@ -911,7 +1244,7 @@ static void b43_radio_2056_setup(struct
1509                         b43_radio_write(dev, offset | B2056_TX_PA_SPARE1, 0xee);
1510                 }
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;
1514                 if (freq < 5100) {
1515                         paa_boost = 0xA;
1516                         pada_boost = 0x77;
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);
1524  }
1525  
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);
1530 -
1531 -       dev->phy.n->init_por = false;
1532  }
1533  
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;
1538  
1539 -
1540 -       bw = (dev->phy.is_40mhz) ? 40 : 20;
1541 +       bw = b43_is_40mhz(dev) ? 40 : 20;
1542         len = bw << 3;
1543  
1544         if (test) {
1545 @@ -1224,7 +1554,7 @@ static u16 b43_nphy_gen_load_samples(str
1546                 else
1547                         bw = 80;
1548  
1549 -               if (dev->phy.is_40mhz)
1550 +               if (b43_is_40mhz(dev))
1551                         bw <<= 1;
1552  
1553                 len = bw << 1;
1554 @@ -1252,8 +1582,10 @@ static u16 b43_nphy_gen_load_samples(str
1555  
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)
1561  {
1562 +       struct b43_phy *phy = &dev->phy;
1563         struct b43_phy_n *nphy = dev->phy.n;
1564         int i;
1565         u16 seq_mode;
1566 @@ -1261,17 +1593,35 @@ static void b43_nphy_run_samples(struct
1567  
1568         b43_nphy_stay_in_carrier_search(dev, true);
1569  
1570 +       if (phy->rev >= 7) {
1571 +               bool lpf_bw3, lpf_bw4;
1572 +
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;
1575 +
1576 +               if (lpf_bw3 || lpf_bw4) {
1577 +                       /* TODO */
1578 +               } else {
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,
1582 +                                                              0, false, 1);
1583 +                       else
1584 +                               b43_nphy_rf_ctl_override_rev7(dev, 0x80, value,
1585 +                                                             0, false, 1);
1586 +                       nphy->lpf_bw_overrode_for_sample_play = true;
1587 +               }
1588 +       }
1589 +
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;
1593         }
1594  
1595 -       /* TODO: add modify_bbmult argument */
1596 -       if (!dev->phy.is_40mhz)
1597 -               tmp = 0x6464;
1598 -       else
1599 -               tmp = 0x4747;
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);
1604 +       }
1605  
1606         b43_phy_write(dev, B43_NPHY_SAMP_DEPCNT, (samps - 1));
1607  
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);
1611         } else {
1612 -               if (dac_test)
1613 -                       b43_phy_write(dev, B43_NPHY_SAMP_CMD, 5);
1614 -               else
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);
1618         }
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
1622         }
1623  }
1624  
1625 +static void b43_nphy_rssi_select_rev19(struct b43_wldev *dev, u8 code,
1626 +                                      enum n_rssi_type rssi_type)
1627 +{
1628 +       /* TODO */
1629 +}
1630 +
1631  static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code,
1632                                       enum n_rssi_type rssi_type)
1633  {
1634 @@ -1461,13 +1815,15 @@ static void b43_nphy_rev3_rssi_select(st
1635                                         enum ieee80211_band band =
1636                                                 b43_current_band(dev->wl);
1637  
1638 -                                       if (b43_nphy_ipa(dev))
1639 -                                               val = (band == IEEE80211_BAND_5GHZ) ? 0xC : 0xE;
1640 -                                       else
1641 -                                               val = 0x11;
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;
1648 +                                               else
1649 +                                                       val = 0x11;
1650 +                                               reg = (i == 0) ? B2056_TX0 : B2056_TX1;
1651 +                                               reg |= B2056_TX_TX_SSI_MUX;
1652 +                                               b43_radio_write(dev, reg, val);
1653 +                                       }
1654  
1655                                         reg = (i == 0) ?
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)
1660  {
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);
1666         else
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];
1670         u16 s[2];
1671  
1672 +       /* TODO: rev7+ is treated like rev3+, what about rev19+? */
1673 +
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)
1680  {
1681 +       struct b43_phy *phy = &dev->phy;
1682         struct b43_phy_n *nphy = dev->phy.n;
1683  
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,
1692                 0x2ff,
1693                 B43_NPHY_TXF_40CO_B1S0, B43_NPHY_TXF_40CO_B32S1,
1694                 B43_NPHY_RFCTL_CMD,
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
1700         };
1701         u16 *regs_to_store;
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);
1704  
1705         if (dev->phy.rev >= 7) {
1706 -               /* TODO */
1707 +               b43_nphy_rf_ctl_override_one_to_many(dev,
1708 +                                                    N_RF_CTL_OVER_CMD_RXRF_PU,
1709 +                                                    0, 0, false);
1710 +               b43_nphy_rf_ctl_override_one_to_many(dev,
1711 +                                                    N_RF_CTL_OVER_CMD_RX_PU,
1712 +                                                    1, 0, false);
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,
1717 +                                                     0);
1718 +                       b43_nphy_rf_ctl_override_rev7(dev, 0x10, 1, 0, false,
1719 +                                                     0);
1720                 } else {
1721 +                       b43_nphy_rf_ctl_override_rev7(dev, 0x10, 0, 0, false,
1722 +                                                     0);
1723 +                       b43_nphy_rf_ctl_override_rev7(dev, 0x20, 1, 0, false,
1724 +                                                     0);
1725                 }
1726         } else {
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)
1732 -                               ;
1733 +                               b43_radio_maskset(dev,
1734 +                                                 core ? R2057_NB_MASTER_CORE1 :
1735 +                                                        R2057_NB_MASTER_CORE0,
1736 +                                                 ~R2057_VCM_MASK, vcm);
1737                         else
1738                                 b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC,
1739                                                   0xE3, vcm << 2);
1740 @@ -1810,7 +2191,10 @@ static void b43_nphy_rev3_rssi_cal(struc
1741  
1742                 /* Select the best VCM */
1743                 if (dev->phy.rev >= 7)
1744 -                       ;
1745 +                       b43_radio_maskset(dev,
1746 +                                         core ? R2057_NB_MASTER_CORE1 :
1747 +                                                R2057_NB_MASTER_CORE0,
1748 +                                         ~R2057_VCM_MASK, vcm);
1749                 else
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;
1754         }
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);
1760         } else {
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
1764  
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;
1769         else
1770 -               nphy->rssical_chanspec_5G.center_freq = dev->phy.channel_freq;
1771 +               nphy->rssical_chanspec_5G.center_freq = phy->chandef->chan->center_freq;
1772  
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
1776   */
1777  static void b43_nphy_rssi_cal(struct b43_wldev *dev)
1778  {
1779 -       if (dev->phy.rev >= 3) {
1780 +       if (dev->phy.rev >= 19) {
1781 +               /* TODO */
1782 +       } else if (dev->phy.rev >= 3) {
1783                 b43_nphy_rev3_rssi_cal(dev);
1784         } else {
1785                 b43_nphy_rev2_rssi_cal(dev, N_RSSI_NB);
1786 @@ -2093,7 +2483,21 @@ static void b43_nphy_rssi_cal(struct b43
1787   * Workarounds
1788   **************************************************/
1789  
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)
1792 +{
1793 +       /* TODO */
1794 +}
1795 +
1796 +static void b43_nphy_gain_ctl_workarounds_rev7(struct b43_wldev *dev)
1797 +{
1798 +       struct b43_phy *phy = &dev->phy;
1799 +
1800 +       switch (phy->rev) {
1801 +       /* TODO */
1802 +       }
1803 +}
1804 +
1805 +static void b43_nphy_gain_ctl_workarounds_rev3(struct b43_wldev *dev)
1806  {
1807         struct ssb_sprom *sprom = dev->dev->bus_sprom;
1808  
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);
1812  
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);
1821  
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
1828  
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))
1833                         code = 4;
1834                 else
1835                         code = 5;
1836         } else {
1837 -               code = dev->phy.is_40mhz ? 6 : 7;
1838 +               code = b43_is_40mhz(dev) ? 6 : 7;
1839         }
1840  
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)
1845  {
1846 -       if (dev->phy.rev >= 7)
1847 -               ; /* TODO */
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);
1855         else
1856                 b43_nphy_gain_ctl_workarounds_rev1_2(dev);
1857  }
1858  
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)
1861 -{
1862 -       if (!offset)
1863 -               offset = (dev->phy.is_40mhz) ? 0x159 : 0x154;
1864 -       return b43_ntab_read(dev, B43_NTAB16(7, offset)) & 0x7;
1865 -}
1866 -
1867  static void b43_nphy_workarounds_rev7plus(struct b43_wldev *dev)
1868  {
1869         struct ssb_sprom *sprom = dev->dev->bus_sprom;
1870         struct b43_phy *phy = &dev->phy;
1871  
1872 +       /* TX to RX */
1873 +       u8 tx2rx_events[7] = { 4, 3, 5, 2, 1, 8, 31, };
1874 +       u8 tx2rx_delays[7] = { 8, 4, 4, 4, 4, 6, 1, };
1875 +       /* RX to TX */
1876         u8 rx2tx_events_ipa[9] = { 0x0, 0x1, 0x2, 0x8, 0x5, 0x6, 0xF, 0x3,
1877                                         0x1F };
1878         u8 rx2tx_delays_ipa[9] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 };
1879  
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 };
1884  
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];
1889 +       u16 bcap_val;
1890 +       s16 bcap_val_11b[2], bcap_val_11n_20[2], bcap_val_11n_40[2];
1891 +       u16 scap_val;
1892 +       s16 scap_val_11b[2], scap_val_11n_20[2], scap_val_11n_40[2];
1893         bool rccal_ovrd = false;
1894  
1895 -       u16 rx2tx_lut_20_11b, rx2tx_lut_20_11n, rx2tx_lut_40_11n;
1896         u16 bias, conv, filt;
1897  
1898 +       u32 noise_tbl[2];
1899 +
1900         u32 tmp32;
1901         u8 core;
1902  
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);
1909 +
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);
1916         }
1917 -       if (phy->rev <= 8) {
1918 +
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);
1925         }
1926 -       if (phy->rev >= 8)
1927 +
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);
1932  
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));
1936         tmp32 &= 0xffffff;
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);
1942  
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);
1951  
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);
1959 +       }
1960 +
1961 +       bcap_val = b43_radio_read(dev, R2057_RCCAL_BCAP_VAL);
1962 +       scap_val = b43_radio_read(dev, R2057_RCCAL_SCAP_VAL);
1963 +
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;
1976 +
1977 +               switch (phy->radio_rev) {
1978 +               case 5:
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;
1988 +                               }
1989 +
1990                                 rccal_ovrd = true;
1991 -                       } else { /* Rev 7/8 */
1992 -                               lpf_20 = 4;
1993 -                               lpf_11b = 1;
1994 +                       }
1995 +                       if (phy->rev == 9) {
1996 +                               /* TODO: Radio version 1 (e.g. BCM5357B0) */
1997 +                       }
1998 +                       break;
1999 +               case 7:
2000 +               case 8:
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;
2015                                 } else {
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;
2024                                 }
2025 -                               rccal_ovrd = true;
2026                         }
2027 +
2028 +                       rccal_ovrd = true;
2029 +                       break;
2030 +               case 9:
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;
2035 +
2036 +                               if (ghz2) {
2037 +                                       bcap_val_11n_20[core] = bcap_val + 13;
2038 +                                       scap_val_11n_20[core] = scap_val + 15;
2039 +                               } else {
2040 +                                       bcap_val_11n_20[core] = bcap_val + 14;
2041 +                                       scap_val_11n_20[core] = scap_val + 15;
2042 +                               }
2043 +                               lpf_ofdm_20mhz[core] = 4;
2044 +
2045 +                               if (ghz2) {
2046 +                                       bcap_val_11n_40[core] = bcap_val - 7;
2047 +                                       scap_val_11n_40[core] = scap_val - 5;
2048 +                               } else {
2049 +                                       bcap_val_11n_40[core] = bcap_val + 2;
2050 +                                       scap_val_11n_40[core] = scap_val + 4;
2051 +                               }
2052 +                               lpf_ofdm_40mhz[core] = 4;
2053 +                       }
2054 +
2055 +                       rccal_ovrd = true;
2056 +                       break;
2057 +               case 14:
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;
2062 +                       }
2063 +
2064 +                       bcap_val_11n_20[0] = bcap_val + 20;
2065 +                       scap_val_11n_20[0] = scap_val + 20;
2066 +                       lpf_ofdm_20mhz[0] = 3;
2067 +
2068 +                       bcap_val_11n_20[1] = bcap_val + 16;
2069 +                       scap_val_11n_20[1] = scap_val + 16;
2070 +                       lpf_ofdm_20mhz[1] = 3;
2071 +
2072 +                       bcap_val_11n_40[0] = bcap_val + 20;
2073 +                       scap_val_11n_40[0] = scap_val + 20;
2074 +                       lpf_ofdm_40mhz[0] = 4;
2075 +
2076 +                       bcap_val_11n_40[1] = bcap_val + 10;
2077 +                       scap_val_11n_40[1] = scap_val + 10;
2078 +                       lpf_ofdm_40mhz[1] = 4;
2079 +
2080 +                       rccal_ovrd = true;
2081 +                       break;
2082                 }
2083         } else {
2084                 if (phy->radio_rev == 5) {
2085 -                       lpf_20 = 1;
2086 -                       lpf_40 = 3;
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;
2104 +                       }
2105 +
2106                         rccal_ovrd = true;
2107                 }
2108         }
2109         if (rccal_ovrd) {
2110 -               rx2tx_lut_20_11b = (bcap_val_11b << 8) |
2111 -                                  (scap_val_11b << 3) |
2112 -                                  lpf_11b;
2113 -               rx2tx_lut_20_11n = (bcap_val_11n_20 << 8) |
2114 -                                  (scap_val_11n_20 << 3) |
2115 -                                  lpf_20;
2116 -               rx2tx_lut_40_11n = (bcap_val_11n_40 << 8) |
2117 -                                  (scap_val_11n_40 << 3) |
2118 -                                  lpf_40;
2119 +               u16 rx2tx_lut_20_11b[2], rx2tx_lut_20_11n[2], rx2tx_lut_40_11n[2];
2120 +               u8 rx2tx_lut_extra = 1;
2121 +
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);
2129 +
2130 +                       rx2tx_lut_20_11b[core] = (rx2tx_lut_extra << 13) |
2131 +                                                (bcap_val_11b[core] << 8) |
2132 +                                                (scap_val_11b[core] << 3) |
2133 +                                                lpf_11b[core];
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];
2142 +               }
2143 +
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]);
2169                 }
2170 -               b43_nphy_rf_ctl_override_rev7(dev, 16, 1, 3, false, 2);
2171         }
2172 +
2173         b43_phy_write(dev, 0x32F, 0x3);
2174 +
2175         if (phy->radio_rev == 4 || phy->radio_rev == 6)
2176                 b43_nphy_rf_ctl_override_rev7(dev, 4, 1, 3, false, 0);
2177  
2178 @@ -2496,7 +3009,8 @@ static void b43_nphy_workarounds_rev7plu
2179                                                                 0x7f);
2180                                 }
2181                         }
2182 -                       if (phy->radio_rev == 3) {
2183 +                       switch (phy->radio_rev) {
2184 +                       case 3:
2185                                 for (core = 0; core < 2; core++) {
2186                                         if (core == 0) {
2187                                                 b43_radio_write(dev, 0x64,
2188 @@ -2522,17 +3036,34 @@ static void b43_nphy_workarounds_rev7plu
2189                                                                 0x3E);
2190                                         }
2191                                 }
2192 -                       } else if (phy->radio_rev == 7 || phy->radio_rev == 8) {
2193 -                               if (!phy->is_40mhz) {
2194 +                               break;
2195 +                       case 7:
2196 +                       case 8:
2197 +                               if (!b43_is_40mhz(dev)) {
2198                                         b43_radio_write(dev, 0x5F, 0x14);
2199                                         b43_radio_write(dev, 0xE8, 0x12);
2200                                 } else {
2201                                         b43_radio_write(dev, 0x5F, 0x16);
2202                                         b43_radio_write(dev, 0xE8, 0x16);
2203                                 }
2204 +                               break;
2205 +                       case 14:
2206 +                               for (core = 0; core < 2; core++) {
2207 +                                       int o = core ? 0x85 : 0;
2208 +
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);
2217 +                               }
2218 +                               break;
2219                         }
2220                 } else {
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);
2234  
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);
2239  
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);
2250  
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);
2254 -       } else {
2255 -               b43_ntab_write(dev, B43_NTAB32(16, 0x03), 0x14D);
2256 -               b43_ntab_write(dev, B43_NTAB32(16, 0x7F), 0x14D);
2257 -       }
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);
2261 +
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);
2265  
2266         b43_nphy_gain_ctl_workarounds(dev);
2267  
2268 @@ -2695,7 +3226,7 @@ static void b43_nphy_workarounds_rev3plu
2269  
2270         b43_phy_maskset(dev, B43_NPHY_SGILTRNOFFSET, 0xF0FF, 0x0700);
2271  
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);
2276         } else {
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);
2280  
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
2287   */
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)
2291  {
2292         u16 samp = b43_nphy_gen_load_samples(dev, freq, max_val, dac_test);
2293         if (samp == 0)
2294                 return -1;
2295 -       b43_nphy_run_samples(dev, samp, 0xFFFF, 0, iqmode, dac_test);
2296 +       b43_nphy_run_samples(dev, samp, 0xFFFF, 0, iqmode, dac_test,
2297 +                            modify_bbmult);
2298         return 0;
2299  }
2300  
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)
2304  {
2305 +       struct b43_phy *phy = &dev->phy;
2306         struct b43_phy_n *nphy = dev->phy.n;
2307         u16 tmp;
2308  
2309 @@ -3010,6 +3544,15 @@ static void b43_nphy_stop_playback(struc
2310                 nphy->bb_mult_save = 0;
2311         }
2312  
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,
2316 +                                                      1);
2317 +               else
2318 +                       b43_nphy_rf_ctl_override_rev7(dev, 0x80, 0, 0, true, 1);
2319 +               nphy->lpf_bw_overrode_for_sample_play = false;
2320 +       }
2321 +
2322         if (nphy->hang_avoid)
2323                 b43_nphy_stay_in_carrier_search(dev, 0);
2324  }
2325 @@ -3019,16 +3562,23 @@ static void b43_nphy_iq_cal_gain_params(
2326                                         struct nphy_txgains target,
2327                                         struct nphy_iqcal_params *params)
2328  {
2329 +       struct b43_phy *phy = &dev->phy;
2330         int i, j, indx;
2331         u16 gain;
2332  
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) {
2342 +                       /* TODO */
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);
2345 +               } else {
2346 +                       params->cal_gain = (params->txgm << 12) | (params->pga << 8) | (params->pad << 4) | (params->ipa);
2347 +               }
2348                 for (j = 0; j < 5; j++)
2349                         params->ncorr[j] = 0x79;
2350         } else {
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)
2354  {
2355 +       struct b43_phy *phy = &dev->phy;
2356         struct b43_phy_n *nphy = dev->phy.n;
2357         u8 i;
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);
2362  
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);
2366         } else {
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);
2370  
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) {
2376 +                               /* TODO */
2377 +                       } else if (phy->rev >= 7) {
2378 +                               b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD,
2379 +                                               ~B43_NPHY_TXPCTL_CMD_INIT,
2380 +                                               0x32);
2381                                 b43_phy_maskset(dev, B43_NPHY_TXPCTL_INIT,
2382                                                 ~B43_NPHY_TXPCTL_INIT_PIDXI1,
2383 +                                               0x32);
2384 +                       } else {
2385 +                               b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD,
2386 +                                               ~B43_NPHY_TXPCTL_CMD_INIT,
2387                                                 0x64);
2388 +                               if (phy->rev > 1)
2389 +                                       b43_phy_maskset(dev,
2390 +                                                       B43_NPHY_TXPCTL_INIT,
2391 +                                                       ~B43_NPHY_TXPCTL_INIT_PIDXI1,
2392 +                                                       0x64);
2393 +                       }
2394                 }
2395  
2396                 if (dev->phy.rev >= 3) {
2397 @@ -3160,6 +3724,10 @@ static void b43_nphy_tx_power_ctrl(struc
2398                         }
2399                 }
2400  
2401 +               if (phy->rev >= 7) {
2402 +                       /* TODO */
2403 +               }
2404 +
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);
2411  
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);
2415  
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)
2420  {
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;
2424  
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;
2429         u32 txgain;
2430         /* u32 gaintbl; rev3+ */
2431  
2432         if (nphy->hang_avoid)
2433                 b43_nphy_stay_in_carrier_search(dev, 1);
2434  
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
2440         */
2441  
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);
2445 +
2446 +               if (!table)
2447 +                       break;
2448 +               txgain = *(table + txpi[i]);
2449  
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
2453         u8 core;
2454         u16 r; /* routing */
2455  
2456 -       if (phy->rev >= 7) {
2457 +       if (phy->rev >= 19) {
2458 +               /* TODO */
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
2464         u32 tmp;
2465         s32 rssi[4] = { };
2466  
2467 -       /* TODO: check if we can transmit */
2468 +       if (phy->chandef->chan->flags & IEEE80211_CHAN_NO_IR)
2469 +               return;
2470  
2471         if (b43_nphy_ipa(dev))
2472                 b43_nphy_ipa_internal_tssi_setup(dev);
2473  
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);
2482  
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);
2486         udelay(20);
2487         tmp = b43_nphy_poll_rssi(dev, N_RSSI_TSSI_2G, rssi, 1);
2488         b43_nphy_stop_playback(dev);
2489 +
2490         b43_nphy_rssi_select(dev, 0, N_RSSI_W1);
2491  
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);
2500  
2501 -       if (phy->rev >= 3) {
2502 +       if (phy->rev >= 19) {
2503 +               /* TODO */
2504 +               return;
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;
2508         } else {
2509 @@ -3443,21 +4028,21 @@ static void b43_nphy_tx_prepare_adjusted
2510                 delta = 0;
2511                 switch (stf_mode) {
2512                 case 0:
2513 -                       if (dev->phy.is_40mhz && dev->phy.rev >= 5) {
2514 +                       if (b43_is_40mhz(dev) && dev->phy.rev >= 5) {
2515                                 idx = 68;
2516                         } else {
2517                                 delta = 1;
2518 -                               idx = dev->phy.is_40mhz ? 52 : 4;
2519 +                               idx = b43_is_40mhz(dev) ? 52 : 4;
2520                         }
2521                         break;
2522                 case 1:
2523 -                       idx = dev->phy.is_40mhz ? 76 : 28;
2524 +                       idx = b43_is_40mhz(dev) ? 76 : 28;
2525                         break;
2526                 case 2:
2527 -                       idx = dev->phy.is_40mhz ? 84 : 36;
2528 +                       idx = b43_is_40mhz(dev) ? 84 : 36;
2529                         break;
2530                 case 3:
2531 -                       idx = dev->phy.is_40mhz ? 92 : 44;
2532 +                       idx = b43_is_40mhz(dev) ? 92 : 44;
2533                         break;
2534                 }
2535  
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)
2539  {
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;
2543  
2544 @@ -3487,7 +4073,7 @@ static void b43_nphy_tx_power_ctl_setup(
2545         s32 num, den, pwr;
2546         u32 regval[64];
2547  
2548 -       u16 freq = dev->phy.channel_freq;
2549 +       u16 freq = phy->chandef->chan->center_freq;
2550         u16 tmp;
2551         u16 r; /* routing */
2552         u8 i, c;
2553 @@ -3594,7 +4180,9 @@ static void b43_nphy_tx_power_ctl_setup(
2554                 udelay(1);
2555         }
2556  
2557 -       if (dev->phy.rev >= 7) {
2558 +       if (phy->rev >= 19) {
2559 +               /* TODO */
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
2565         int i;
2566  
2567         table = b43_nphy_get_tx_gain_table(dev);
2568 +       if (!table)
2569 +               return;
2570 +
2571         b43_ntab_write_bulk(dev, B43_NTAB32(26, 192), 128, table);
2572         b43_ntab_write_bulk(dev, B43_NTAB32(27, 192), 128, table);
2573  
2574 -       if (phy->rev >= 3) {
2575 +       if (phy->rev < 3)
2576 +               return;
2577 +
2578  #if 0
2579 -               nphy->gmval = (table[0] >> 16) & 0x7000;
2580 +       nphy->gmval = (table[0] >> 16) & 0x7000;
2581  #endif
2582  
2583 -               for (i = 0; i < 128; i++) {
2584 +       for (i = 0; i < 128; i++) {
2585 +               if (phy->rev >= 19) {
2586 +                       /* TODO */
2587 +                       return;
2588 +               } else if (phy->rev >= 7) {
2589 +                       /* TODO */
2590 +                       return;
2591 +               } else {
2592                         pga_gain = (table[i] >> 24) & 0xF;
2593                         if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
2594 -                               rfpwr_offset =
2595 -                                b43_ntab_papd_pga_gain_delta_ipa_2g[pga_gain];
2596 +                               rfpwr_offset = b43_ntab_papd_pga_gain_delta_ipa_2g[pga_gain];
2597                         else
2598 -                               rfpwr_offset =
2599 -                                0; /* FIXME */
2600 -                       b43_ntab_write(dev, B43_NTAB32(26, 576 + i),
2601 -                                      rfpwr_offset);
2602 -                       b43_ntab_write(dev, B43_NTAB32(27, 576 + i),
2603 -                                      rfpwr_offset);
2604 +                               rfpwr_offset = 0; /* FIXME */
2605                 }
2606 +
2607 +               b43_ntab_write(dev, B43_NTAB32(26, 576 + i), rfpwr_offset);
2608 +               b43_ntab_write(dev, B43_NTAB32(27, 576 + i), rfpwr_offset);
2609         }
2610  }
2611  
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) {
2618 +                       tmp = 0x1480;
2619 +               } else if (dev->phy.rev >= 3) {
2620                         if (band == IEEE80211_BAND_5GHZ)
2621                                 tmp = 0x600;
2622                         else
2623 @@ -3709,21 +4308,28 @@ static void b43_nphy_pa_override(struct
2624         }
2625  }
2626  
2627 -/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxLpFbw */
2628 -static void b43_nphy_tx_lp_fbw(struct b43_wldev *dev)
2629 +/*
2630 + * TX low-pass filter bandwidth setup
2631 + * http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxLpFbw
2632 + */
2633 +static void b43_nphy_tx_lpf_bw(struct b43_wldev *dev)
2634  {
2635         u16 tmp;
2636  
2637 -       if (dev->phy.rev >= 3) {
2638 -               if (b43_nphy_ipa(dev)) {
2639 -                       tmp = 4;
2640 -                       b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S2,
2641 -                             (((((tmp << 3) | tmp) << 3) | tmp) << 3) | tmp);
2642 -               }
2643 +       if (dev->phy.rev < 3 || dev->phy.rev >= 7)
2644 +               return;
2645 +
2646 +       if (b43_nphy_ipa(dev))
2647 +               tmp = b43_is_40mhz(dev) ? 5 : 4;
2648 +       else
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);
2652  
2653 -               tmp = 1;
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);
2659         }
2660  }
2661  
2662 @@ -3996,7 +4602,7 @@ static void b43_nphy_spur_workaround(str
2663  
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)*/
2669                 else
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;
2673         }
2674  
2675 -       if (dev->phy.rev >= 7) {
2676 +       if (dev->phy.rev >= 19) {
2677 +               /* TODO */
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]);
2683         } else {
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]);
2688  }
2689  
2690 +static void b43_nphy_tx_cal_radio_setup_rev19(struct b43_wldev *dev)
2691 +{
2692 +       /* TODO */
2693 +}
2694 +
2695 +static void b43_nphy_tx_cal_radio_setup_rev7(struct b43_wldev *dev)
2696 +{
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;
2700 +       int core, off;
2701 +       u16 r, tmp;
2702 +
2703 +       for (core = 0; core < 2; core++) {
2704 +               r = core ? 0x20 : 0;
2705 +               off = core * 11;
2706 +
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);
2717 +
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);
2728 +                       }
2729 +                       b43_radio_write(dev, r + R2057_TX0_TSSI_MISC1, 0x00);
2730 +               } else {
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);
2735 +
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);
2742 +                       }
2743 +                       b43_radio_write(dev, r + R2057_TX0_TSSI_MISC1, 0);
2744 +               }
2745 +       }
2746 +}
2747 +
2748  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalRadioSetup */
2749  static void b43_nphy_tx_cal_radio_setup(struct b43_wldev *dev)
2750  {
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;
2754         u16 tmp;
2755         u8 offset, i;
2756  
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;
2765                 offset = i * 11;
2766 @@ -4269,41 +4944,62 @@ static void b43_nphy_update_tx_cal_ladde
2767         }
2768  }
2769  
2770 +static void b43_nphy_pa_set_tx_dig_filter(struct b43_wldev *dev, u16 offset,
2771 +                                         const s16 *filter)
2772 +{
2773 +       int i;
2774 +
2775 +       offset = B43_PHY_N(offset);
2776 +
2777 +       for (i = 0; i < 15; i++, offset++)
2778 +               b43_phy_write(dev, offset, filter[i]);
2779 +}
2780 +
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)
2783  {
2784 -       int i;
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]);
2790  }
2791  
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)
2794  {
2795 -       int i, j;
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,
2802 +       };
2803 +       int i;
2804  
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]);
2809 -
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]);
2818 -       }
2819 -
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]);
2826 +
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);
2830 +
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]);
2836 +       }
2837 +
2838 +       if (b43_is_40mhz(dev)) {
2839 +               b43_nphy_pa_set_tx_dig_filter(dev, 0x186,
2840 +                                             tbl_tx_filter_coef_rev4[3]);
2841 +       } else {
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]);
2848 +       }
2849  }
2850  
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);
2854  
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_
2868  
2869                 for (i = 0; i < 2; ++i) {
2870                         table = b43_nphy_get_tx_gain_table(dev);
2871 -                       if (dev->phy.rev >= 3) {
2872 +                       if (!table)
2873 +                               break;
2874 +
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)
2888  {
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;
2892         u16 tmp;
2893  
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);
2897  
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,
2901 +                                                     1, 3);
2902 +               else
2903 +                       b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_PA,
2904 +                                                     0, 3);
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);
2907  
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);
2912 +
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,
2916 +                                                      1);
2917 +               else if (phy->rev >= 7)
2918 +                       b43_nphy_rf_ctl_override_rev7(dev, 0x80, tmp, 0, false,
2919 +                                                     1);
2920 +
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,
2924 +                                                              false, 0);
2925 +                       } else if (phy->rev >= 8) {
2926 +                               b43_nphy_rf_ctl_override_rev7(dev, 0x8, 0, 0x3,
2927 +                                                             false, 0);
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);
2933 +                               } else {
2934 +                                       b43_radio_maskset(dev, R2057_IPA5G_CASCOFFV_PU_CORE0, ~1, 0);
2935 +                                       b43_radio_maskset(dev, R2057_IPA5G_CASCOFFV_PU_CORE1, ~1, 0);
2936 +                               }
2937 +                       }
2938 +               }
2939         } else {
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)
2945  {
2946 +       struct b43_phy *phy = &dev->phy;
2947         struct b43_phy_n *nphy = dev->phy.n;
2948  
2949         struct b43_phy_n_iq_comp *rxcal_coeffs = NULL;
2950 @@ -4489,7 +5235,26 @@ static void b43_nphy_save_cal(struct b43
2951  
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) {
2956 +               /* TODO */
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);
2981         }
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);
2988  
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)
2993  {
2994 +       struct b43_phy *phy = &dev->phy;
2995         struct b43_phy_n *nphy = dev->phy.n;
2996  
2997         u16 coef[4];
2998 @@ -4562,7 +5329,26 @@ static void b43_nphy_restore_cal(struct
2999         }
3000  
3001         /* TODO use some definitions */
3002 -       if (dev->phy.rev >= 3) {
3003 +       if (phy->rev >= 19) {
3004 +               /* TODO */
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)
3029  {
3030 +       struct b43_phy *phy = &dev->phy;
3031         struct b43_phy_n *nphy = dev->phy.n;
3032         int i;
3033         int error = 0;
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);
3037         if (phy6or5x) {
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
3044                 }
3045         }
3046  
3047 -       b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8AA9);
3048 +       if (phy->rev >= 19) {
3049 +               /* TODO */
3050 +       } else if (phy->rev >= 7) {
3051 +               b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8AD9);
3052 +       } else {
3053 +               b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8AA9);
3054 +       }
3055  
3056 -       if (!dev->phy.is_40mhz)
3057 +       if (!b43_is_40mhz(dev))
3058                 freq = 2500;
3059         else
3060                 freq = 5000;
3061  
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);
3067         else
3068 -               error = b43_nphy_tx_tone(dev, freq, 250, true, false);
3069 +               error = b43_nphy_tx_tone(dev, freq, 250, true, false, false);
3070  
3071         if (error == 0) {
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);
3082                 } else {
3083                         length = 11;
3084                         if (dev->phy.rev < 3)
3085 @@ -4815,8 +5608,8 @@ static void b43_nphy_reapply_tx_cal_coef
3086         bool equal = true;
3087  
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))
3093                 return;
3094  
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
3097                         if (playtone) {
3098                                 ret = b43_nphy_tx_tone(dev, 4000,
3099                                                 (nphy->rxcalparams & 0xFFFF),
3100 -                                               false, false);
3101 +                                               false, false, true);
3102                                 playtone = false;
3103                         } else {
3104 -                               b43_nphy_run_samples(dev, 160, 0xFFFF, 0,
3105 -                                                       false, false);
3106 +                               b43_nphy_run_samples(dev, 160, 0xFFFF, 0, false,
3107 +                                                    false, true);
3108                         }
3109  
3110                         if (ret == 0) {
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)
3114  {
3115 +       if (dev->phy.rev >= 7)
3116 +               type = 0;
3117 +
3118         if (dev->phy.rev >= 3)
3119                 return b43_nphy_rev3_cal_rx_iq(dev, target, type, debug);
3120         else
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)
3124  {
3125 +       if (dev->phy.rev >= 7)
3126 +               return;
3127 +
3128         if (dev->phy.rev >= 3) {
3129                 if (!init)
3130                         return;
3131 @@ -5193,6 +5992,10 @@ static int b43_phy_initn(struct b43_wlde
3132  #endif
3133                 }
3134         }
3135 +       nphy->use_int_tx_iq_lo_cal = b43_nphy_ipa(dev) ||
3136 +               phy->rev >= 7 ||
3137 +               (phy->rev >= 5 &&
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);
3151 +               }
3152 +               if (phy->rev >= 19) {
3153 +                       /* TODO */
3154 +               }
3155 +
3156                 b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S0, 0);
3157                 b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S1, 0);
3158         } else {
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);
3162  
3163 -       b43_nphy_update_mimo_config(dev, nphy->preamble_override);
3164 +       if (phy->rev < 8)
3165 +               b43_nphy_update_mimo_config(dev, nphy->preamble_override);
3166 +
3167         b43_nphy_update_txrx_chain(dev);
3168  
3169         if (phy->rev < 2) {
3170 @@ -5271,10 +6086,12 @@ static int b43_phy_initn(struct b43_wlde
3171  
3172         b43_mac_phy_clock_set(dev, true);
3173  
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);
3183 +       }
3184  
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);
3193         if (phy->rev >= 3)
3194                 b43_nphy_spur_workaround(dev);
3195  
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;
3200 -
3201 -       u16 old_band_5ghz;
3202         u16 tmp16;
3203  
3204 -       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);
3226         }
3227  
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);
3231  
3232 -       b43_nphy_tx_lp_fbw(dev);
3233 +       b43_nphy_tx_lpf_bw(dev);
3234  
3235         if (dev->phy.rev >= 3 &&
3236             dev->phy.n->spur_avoid != B43_SPUR_AVOID_DISABLE) {
3237 -               bool avoid = false;
3238 +               u8 spuravoid = 0;
3239 +
3240                 if (dev->phy.n->spur_avoid == B43_SPUR_AVOID_FORCE) {
3241 -                       avoid = true;
3242 -               } else if (!b43_channel_type_is_40mhz(phy->channel_type)) {
3243 -                       if ((ch >= 5 && ch <= 8) || ch == 13 || ch == 14)
3244 -                               avoid = true;
3245 -               } else { /* 40MHz */
3246 -                       if (nphy->aband_spurwar_en &&
3247 -                           (ch == 38 || ch == 102 || ch == 118))
3248 -                               avoid = dev->dev->chip_id == 0x4716;
3249 -               }
3250 -
3251 -               b43_nphy_pmu_spur_avoid(dev, avoid);
3252 -
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);
3258 +                       spuravoid = 1;
3259 +               } else if (phy->rev >= 19) {
3260 +                       /* TODO */
3261 +               } else if (phy->rev >= 18) {
3262 +                       /* TODO */
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)
3270 +                                       spuravoid = 1;
3271 +                       } else { /* 40 MHz */
3272 +                               if (ch == 54)
3273 +                                       spuravoid = 1;
3274 +                       }
3275 +               } else {
3276 +                       if (!b43_is_40mhz(dev)) { /* 20MHz */
3277 +                               if ((ch >= 5 && ch <= 8) || ch == 13 || ch == 14)
3278 +                                       spuravoid = 1;
3279 +                       } else { /* 40MHz */
3280 +                               if (nphy->aband_spurwar_en &&
3281 +                                   (ch == 38 || ch == 102 || ch == 118))
3282 +                                       spuravoid = dev->dev->chip_id == 0x4716;
3283 +                       }
3284                 }
3285  
3286 +               b43_nphy_pmu_spur_avoid(dev, spuravoid);
3287 +
3288 +               b43_mac_switch_freq(dev, spuravoid);
3289 +
3290                 if (dev->phy.rev == 3 || dev->phy.rev == 4)
3291                         ; /* TODO: reset PLL */
3292  
3293 -               if (avoid)
3294 +               if (spuravoid)
3295                         b43_phy_set(dev, B43_NPHY_BBCFG, B43_NPHY_BBCFG_RSTRX);
3296                 else
3297                         b43_phy_mask(dev, B43_NPHY_BBCFG,
3298 @@ -5488,10 +6319,20 @@ static int b43_nphy_set_channel(struct b
3299  
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;
3304  
3305         u8 tmp;
3306  
3307 -       if (dev->phy.rev >= 3) {
3308 +       if (phy->rev >= 19) {
3309 +               return -ESRCH;
3310 +               /* TODO */
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)
3315 +                       return -ESRCH;
3316 +       } else if (phy->rev >= 3) {
3317                 tabent_r3 = b43_nphy_get_chantabent_rev3(dev,
3318                                                         channel->center_freq);
3319                 if (!tabent_r3)
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;
3325  
3326 +#if 0
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) */
3330 +#endif
3331  
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);
3346 +       }
3347  
3348 -       if (dev->phy.rev >= 3) {
3349 +       if (phy->rev >= 19) {
3350 +               /* TODO */
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);
3354 +
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);
3359 +               }
3360 +
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;
3378         }
3379 -
3380 -       nphy->init_por = true;
3381  }
3382  
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)
3386  {
3387         /* Register 1 is a 32-bit register. */
3388 -       B43_WARN_ON(reg == 1);
3389 +       B43_WARN_ON(dev->phy.rev < 7 && reg == 1);
3390  
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)
3395  {
3396         /* Register 1 is a 32-bit register. */
3397 -       B43_WARN_ON(reg == 1);
3398 +       B43_WARN_ON(dev->phy.rev < 7 && reg == 1);
3399  
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,
3404                                         bool blocked)
3405  {
3406 +       struct b43_phy *phy = &dev->phy;
3407 +
3408         if (b43_read32(dev, B43_MMIO_MACCTL) & B43_MACCTL_ENABLED)
3409                 b43err(dev->wl, "MAC not suspended\n");
3410  
3411         if (blocked) {
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) {
3416                         /* TODO */
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);
3426 +
3427                         b43_radio_mask(dev, 0x09, ~0x2);
3428  
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);
3432                 }
3433         } else {
3434 -               if (dev->phy.rev >= 7) {
3435 -                       b43_radio_2057_init(dev);
3436 +               if (phy->rev >= 19) {
3437 +                       /* TODO */
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);
3448                 } else {
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)
3453  {
3454 +       struct b43_phy *phy = &dev->phy;
3455         u16 override = on ? 0x0 : 0x7FFF;
3456         u16 core = on ? 0xD : 0x00FD;
3457  
3458 -       if (dev->phy.rev >= 3) {
3459 +       if (phy->rev >= 19) {
3460 +               /* TODO */
3461 +       } else if (phy->rev >= 3) {
3462                 if (on) {
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)
3484  
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)
3493 +
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)
3498  
3499  struct b43_wldev;
3500 @@ -931,11 +944,12 @@ struct b43_phy_n {
3501         u16 papd_epsilon_offset[2];
3502         s32 preamble_override;
3503         u32 bb_mult_save;
3504 -       bool init_por;
3505  
3506         bool gain_boost;
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;
3511  
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]
3517         }
3518  };
3519  
3520 -/* TX gain tables */
3521 +/* static tables, PHY revision >= 7 */
3522 +
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,
3637 +};
3638 +
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,
3705 +};
3706 +
3707 +/**************************************************
3708 + * TX gain tables
3709 + **************************************************/
3710 +
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,
3716  };
3717  
3718 -static const u32 b43_ntab_tx_gain_rev3plus_2ghz[] = {
3719 +/* EPA 2 GHz */
3720 +
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,
3727  };
3728  
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
3763 +};
3764 +
3765 +/* EPA 5 GHz */
3766 +
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,
3773  };
3774  
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,
3782  };
3783  
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
3818 +};
3819 +
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,
3826  };
3827  
3828 -static const u32 txpwrctrl_tx_gain_ipa[] = {
3829 +/* IPA 2 GHz */
3830 +
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,
3837  };
3838  
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,
3846  };
3847  
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,
3855  };
3856  
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,
3892 +};
3893 +
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,
3928 +};
3929 +
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,
3964 +};
3965 +
3966 +/* IPA 2 5Hz */
3967 +
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,
3974  };
3975  
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,
4010 +};
4011 +
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 },
4027  };
4028  
4029 @@ -3031,31 +3442,8 @@ void b43_ntab_write_bulk(struct b43_wlde
4030                 b43_ntab_write_bulk(dev, offset, ARRAY_SIZE(data), data); \
4031         } while (0)
4032  
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)
4035  {
4036 -       struct ssb_sprom *sprom = dev->dev->bus_sprom;
4037 -       u8 antswlut;
4038 -
4039 -       if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
4040 -               antswlut = sprom->fem.ghz5.antswlut;
4041 -       else
4042 -               antswlut = sprom->fem.ghz2.antswlut;
4043 -
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);
4066 +}
4067 +
4068 +static void b43_nphy_tables_init_rev7_volatile(struct b43_wldev *dev)
4069 +{
4070 +       struct ssb_sprom *sprom = dev->dev->bus_sprom;
4071 +       u8 antswlut;
4072 +       int core, offset, i;
4073 +
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 */
4078 +       };
4079 +
4080 +       if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
4081 +               antswlut = sprom->fem.ghz5.antswlut;
4082 +       else
4083 +               antswlut = sprom->fem.ghz2.antswlut;
4084 +
4085 +       switch (antswlut) {
4086 +       case 0:
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]);
4093 +                       }
4094 +               }
4095 +               break;
4096 +       default:
4097 +               b43err(dev->wl, "Unsupported antswlut: %d\n", antswlut);
4098 +               break;
4099 +       }
4100 +}
4101 +
4102 +static void b43_nphy_tables_init_rev16(struct b43_wldev *dev)
4103 +{
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);
4108 +       }
4109 +
4110 +       /* Volatile tables */
4111 +       b43_nphy_tables_init_rev7_volatile(dev);
4112 +}
4113 +
4114 +static void b43_nphy_tables_init_rev7(struct b43_wldev *dev)
4115 +{
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);
4133 +       }
4134 +
4135 +       /* Volatile tables */
4136 +       b43_nphy_tables_init_rev7_volatile(dev);
4137 +}
4138 +
4139 +static void b43_nphy_tables_init_rev3(struct b43_wldev *dev)
4140 +{
4141 +       struct ssb_sprom *sprom = dev->dev->bus_sprom;
4142 +       u8 antswlut;
4143 +
4144 +       if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
4145 +               antswlut = sprom->fem.ghz5.antswlut;
4146 +       else
4147 +               antswlut = sprom->fem.ghz2.antswlut;
4148 +
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);
4166 +       }
4167  
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)
4172  {
4173         /* Static tables */
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);
4203 +       }
4204  
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)
4210  {
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);
4218         else
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)
4223  {
4224 +       struct b43_phy *phy = &dev->phy;
4225 +
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;
4233 -               } else {
4234 -                       return txpwrctrl_tx_gain_ipa;
4235 +               switch (phy->rev) {
4236 +               case 17:
4237 +                       if (phy->radio_rev == 14)
4238 +                               return b43_ntab_tx_gain_ipa_2057_rev14_2g;
4239 +                       break;
4240 +               case 16:
4241 +                       if (phy->radio_rev == 9)
4242 +                               return b43_ntab_tx_gain_ipa_2057_rev9_2g;
4243 +                       break;
4244 +               case 8:
4245 +                       if (phy->radio_rev == 5)
4246 +                               return b43_ntab_tx_gain_ipa_2057_rev5_2g;
4247 +                       break;
4248 +               case 6:
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;
4252 +               case 5:
4253 +                       return b43_ntab_tx_gain_ipa_rev5_2g;
4254 +               case 4:
4255 +               case 3:
4256 +                       return b43_ntab_tx_gain_ipa_rev3_2g;
4257                 }
4258 +
4259 +               b43err(dev->wl,
4260 +                      "No 2GHz IPA gain table available for this device\n");
4261 +               return NULL;
4262         } else {
4263 -               return txpwrctrl_tx_gain_ipa_5g;
4264 +               switch (phy->rev) {
4265 +               case 16:
4266 +                       if (phy->radio_rev == 9)
4267 +                               return b43_ntab_tx_gain_ipa_2057_rev9_5g;
4268 +                       break;
4269 +               case 3 ... 6:
4270 +                       return b43_ntab_tx_gain_ipa_rev3_5g;
4271 +               }
4272 +
4273 +               b43err(dev->wl,
4274 +                      "No 5GHz IPA gain table available for this device\n");
4275 +               return NULL;
4276         }
4277  }
4278  
4279  const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev)
4280  {
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;
4284  
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) {
4293 +               case 6:
4294 +               case 5:
4295 +                       return b43_ntab_tx_gain_epa_rev5_5g;
4296 +               case 4:
4297                         return sprom->fem.ghz5.extpa_gain == 3 ?
4298 -                               b43_ntab_tx_gain_rev4_5ghz :
4299 -                               b43_ntab_tx_gain_rev4_5ghz; /* FIXME */
4300 -               else
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;
4304 +               case 3:
4305 +                       return b43_ntab_tx_gain_epa_rev3_5g;
4306 +               default:
4307 +                       b43err(dev->wl,
4308 +                              "No 5GHz EPA gain table available for this device\n");
4309 +                       return NULL;
4310 +               }
4311         } else {
4312 -               if (dev->phy.rev >= 5 && sprom->fem.ghz5.extpa_gain == 3)
4313 -                       return b43_ntab_tx_gain_rev3plus_2ghz; /* FIXME */
4314 -               else
4315 -                       return b43_ntab_tx_gain_rev3plus_2ghz;
4316 +               switch (phy->rev) {
4317 +               case 6:
4318 +               case 5:
4319 +                       if (sprom->fem.ghz5.extpa_gain == 3)
4320 +                               return b43_ntab_tx_gain_epa_rev3_hi_pwr_2g;
4321 +                       /* fall through */
4322 +               case 4:
4323 +               case 3:
4324 +                       return b43_ntab_tx_gain_epa_rev3_2g;
4325 +               default:
4326 +                       b43err(dev->wl,
4327 +                              "No 2GHz EPA gain table available for this device\n");
4328 +                       return NULL;
4329 +               }
4330         }
4331  }
4332  
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
4345  choice
4346         prompt "Supported bus types"
4347         depends on B43
4348 -       default B43_BCMA_AND_SSB
4349 +       default B43_BUSES_BCMA_AND_SSB
4350  
4351  config B43_BUSES_BCMA_AND_SSB
4352         bool "BCMA and SSB"
4353 @@ -123,6 +123,15 @@ config B43_PIO
4354         select SSB_BLOCKIO
4355         default y
4356  
4357 +config B43_PHY_G
4358 +       bool "Support for G-PHY (802.11g) devices"
4359 +       depends on B43 && B43_SSB
4360 +       default y
4361 +       ---help---
4362 +         This PHY type can be found in the following chipsets:
4363 +         PCI: BCM4306, BCM4311, BCM4318
4364 +         SoC: BCM4712, BCM5352E
4365 +
4366  config B43_PHY_N
4367         bool "Support for 802.11n (N-PHY) devices"
4368         depends on B43
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
4372         u8 target[3];
4373         s16 a1[3], b0[3], b1[3];
4374  
4375 -       u16 freq = dev->phy.channel_freq;
4376 +       u16 freq = dev->phy.chandef->chan->center_freq;
4377         int i, c;
4378  
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 {
4383   */
4384  void b43_phy_inita(struct b43_wldev *dev);
4385  
4386 -
4387 -struct b43_phy_operations;
4388 -extern const struct b43_phy_operations b43_phyops_a;
4389 -
4390  #endif /* LINUX_B43_PHY_A_H_ */
4391 --- a/drivers/net/wireless/b43/Makefile
4392 +++ b/drivers/net/wireless/b43/Makefile
4393 @@ -1,13 +1,11 @@
4394  b43-y                          += main.o
4395  b43-y                          += bus.o
4396 -b43-y                          += tables.o
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
4403 -b43-y                          += phy_g.o
4404 -b43-y                          += phy_a.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
4410  b43-y                          += sysfs.o
4411  b43-y                          += xmit.o
4412 -b43-y                          += lo.o
4413 -b43-y                          += wa.o
4414  b43-y                          += dma.o
4415  b43-y                          += pio.o
4416  b43-y                          += rfkill.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
4420  {//TODO
4421  }
4422  
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
4430 @@ -26,7 +26,7 @@
4431  #include "radio_2057.h"
4432  #include "phy_common.h"
4433  
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 },
4441  };
4442  
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 },
4450  };
4451  
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] = {
4458         { 0x1C2, 0x80 },
4459  };
4460  
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 },
4468  };
4469  
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 },
4479  };
4480 +*/
4481 +
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 },
4492 +};
4493 +
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 },
4500 +       { 0x1d4, 0x0f },
4501 +};
4502 +
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
4534 +
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
4555 +
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
4563 +
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[] = {
4566 +       {
4567 +               .freq                   = 2412,
4568 +               RADIOREGS7_2G(0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c,
4569 +                             0x09, 0x0d, 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61,
4570 +                             0x03, 0xff),
4571 +               PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
4572 +       },
4573 +       {
4574 +               .freq                   = 2417,
4575 +               RADIOREGS7_2G(0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71,
4576 +                             0x09, 0x0d, 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61,
4577 +                             0x03, 0xff),
4578 +               PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
4579 +       },
4580 +       {
4581 +               .freq                   = 2422,
4582 +               RADIOREGS7_2G(0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76,
4583 +                             0x09, 0x0d, 0x08, 0x0e, 0x61, 0x03, 0xef, 0x61,
4584 +                             0x03, 0xef),
4585 +               PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
4586 +       },
4587 +       {
4588 +               .freq                   = 2427,
4589 +               RADIOREGS7_2G(0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b,
4590 +                             0x09, 0x0c, 0x08, 0x0e, 0x61, 0x03, 0xdf, 0x61,
4591 +                             0x03, 0xdf),
4592 +               PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
4593 +       },
4594 +       {
4595 +               .freq                   = 2432,
4596 +               RADIOREGS7_2G(0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80,
4597 +                             0x09, 0x0c, 0x07, 0x0d, 0x61, 0x03, 0xcf, 0x61,
4598 +                             0x03, 0xcf),
4599 +               PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
4600 +       },
4601 +       {
4602 +               .freq                   = 2437,
4603 +               RADIOREGS7_2G(0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85,
4604 +                             0x09, 0x0c, 0x07, 0x0d, 0x61, 0x03, 0xbf, 0x61,
4605 +                             0x03, 0xbf),
4606 +               PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
4607 +       },
4608 +       {
4609 +               .freq                   = 2442,
4610 +               RADIOREGS7_2G(0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a,
4611 +                             0x09, 0x0b, 0x07, 0x0d, 0x61, 0x03, 0xaf, 0x61,
4612 +                             0x03, 0xaf),
4613 +               PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
4614 +       },
4615 +       {
4616 +               .freq                   = 2447,
4617 +               RADIOREGS7_2G(0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f,
4618 +                             0x09, 0x0b, 0x07, 0x0d, 0x61, 0x03, 0x9f, 0x61,
4619 +                             0x03, 0x9f),
4620 +               PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
4621 +       },
4622 +       {
4623 +               .freq                   = 2452,
4624 +               RADIOREGS7_2G(0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94,
4625 +                             0x09, 0x0b, 0x07, 0x0d, 0x61, 0x03, 0x8f, 0x61,
4626 +                             0x03, 0x8f),
4627 +               PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
4628 +       },
4629 +       {
4630 +               .freq                   = 2457,
4631 +               RADIOREGS7_2G(0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99,
4632 +                             0x09, 0x0b, 0x07, 0x0c, 0x61, 0x03, 0x7f, 0x61,
4633 +                             0x03, 0x7f),
4634 +               PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
4635 +       },
4636 +       {
4637 +               .freq                   = 2462,
4638 +               RADIOREGS7_2G(0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e,
4639 +                             0x09, 0x0b, 0x07, 0x0c, 0x61, 0x03, 0x6f, 0x61,
4640 +                             0x03, 0x6f),
4641 +               PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
4642 +       },
4643 +       {
4644 +               .freq                   = 2467,
4645 +               RADIOREGS7_2G(0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3,
4646 +                             0x09, 0x0b, 0x06, 0x0c, 0x61, 0x03, 0x5f, 0x61,
4647 +                             0x03, 0x5f),
4648 +               PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b),
4649 +       },
4650 +       {
4651 +               .freq                   = 2472,
4652 +               RADIOREGS7_2G(0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8,
4653 +                             0x09, 0x0a, 0x06, 0x0b, 0x61, 0x03, 0x4f, 0x61,
4654 +                             0x03, 0x4f),
4655 +               PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429),
4656 +       },
4657 +       {
4658 +               .freq                   = 2484,
4659 +               RADIOREGS7_2G(0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4,
4660 +                             0x09, 0x0a, 0x06, 0x0b, 0x61, 0x03, 0x3f, 0x61,
4661 +                             0x03, 0x3f),
4662 +               PHYREGS(0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424),
4663 +       }
4664 +};
4665 +
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[] = {
4668 +       {
4669 +               .freq                   = 2412,
4670 +               RADIOREGS7_2G(0x48, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x6c,
4671 +                             0x09, 0x0d, 0x09, 0x03, 0x21, 0x53, 0xff, 0x21,
4672 +                             0x53, 0xff),
4673 +               PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
4674 +       },
4675 +       {
4676 +               .freq                   = 2417,
4677 +               RADIOREGS7_2G(0x4b, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x71,
4678 +                             0x09, 0x0d, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
4679 +                             0x53, 0xff),
4680 +               PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
4681 +       },
4682 +       {
4683 +               .freq                   = 2422,
4684 +               RADIOREGS7_2G(0x4e, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x76,
4685 +                             0x09, 0x0d, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
4686 +                             0x53, 0xff),
4687 +               PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
4688 +       },
4689 +       {
4690 +               .freq                   = 2427,
4691 +               RADIOREGS7_2G(0x52, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x7b,
4692 +                             0x09, 0x0c, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
4693 +                             0x53, 0xff),
4694 +               PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
4695 +       },
4696 +       {
4697 +               .freq                   = 2432,
4698 +               RADIOREGS7_2G(0x55, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x80,
4699 +                             0x09, 0x0c, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
4700 +                             0x53, 0xff),
4701 +               PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
4702 +       },
4703 +       {
4704 +               .freq                   = 2437,
4705 +               RADIOREGS7_2G(0x58, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x85,
4706 +                             0x09, 0x0c, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
4707 +                             0x53, 0xff),
4708 +               PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
4709 +       },
4710 +       {
4711 +               .freq                   = 2442,
4712 +               RADIOREGS7_2G(0x5c, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x8a,
4713 +                             0x09, 0x0c, 0x08, 0x03, 0x21, 0x43, 0xff, 0x21,
4714 +                             0x43, 0xff),
4715 +               PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
4716 +       },
4717 +       {
4718 +               .freq                   = 2447,
4719 +               RADIOREGS7_2G(0x5f, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x8f,
4720 +                             0x09, 0x0c, 0x08, 0x03, 0x21, 0x43, 0xff, 0x21,
4721 +                             0x43, 0xff),
4722 +               PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
4723 +       },
4724 +       {
4725 +               .freq                   = 2452,
4726 +               RADIOREGS7_2G(0x62, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x94,
4727 +                             0x09, 0x0c, 0x08, 0x03, 0x21, 0x43, 0xff, 0x21,
4728 +                             0x43, 0xff),
4729 +               PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
4730 +       },
4731 +       {
4732 +               .freq                   = 2457,
4733 +               RADIOREGS7_2G(0x66, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x99,
4734 +                             0x09, 0x0b, 0x07, 0x03, 0x21, 0x43, 0xff, 0x21,
4735 +                             0x43, 0xff),
4736 +               PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
4737 +       },
4738 +       {
4739 +               .freq                   = 2462,
4740 +               RADIOREGS7_2G(0x69, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x9e,
4741 +                             0x09, 0x0b, 0x07, 0x03, 0x01, 0x43, 0xff, 0x01,
4742 +                             0x43, 0xff),
4743 +               PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
4744 +       },
4745 +};
4746 +
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[] = {
4749 +       {
4750 +               .freq                   = 2412,
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),
4756 +       },
4757 +       {
4758 +               .freq                   = 2417,
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),
4764 +       },
4765 +       {
4766 +               .freq                   = 2422,
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),
4772 +       },
4773 +       {
4774 +               .freq                   = 2427,
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),
4780 +       },
4781 +       {
4782 +               .freq                   = 2432,
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),
4788 +       },
4789 +       {
4790 +               .freq                   = 2437,
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),
4796 +       },
4797 +       {
4798 +               .freq                   = 2442,
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),
4804 +       },
4805 +       {
4806 +               .freq                   = 2447,
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),
4812 +       },
4813 +       {
4814 +               .freq                   = 2452,
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),
4820 +       },
4821 +       {
4822 +               .freq                   = 2457,
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),
4828 +       },
4829 +       {
4830 +               .freq                   = 2462,
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),
4836 +       },
4837 +       {
4838 +               .freq                   = 5180,
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),
4844 +       },
4845 +       {
4846 +               .freq                   = 5200,
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),
4852 +       },
4853 +       {
4854 +               .freq                   = 5220,
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),
4860 +       },
4861 +       {
4862 +               .freq                   = 5240,
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),
4868 +       },
4869 +       {
4870 +               .freq                   = 5745,
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),
4876 +       },
4877 +       {
4878 +               .freq                   = 5765,
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),
4884 +       },
4885 +       {
4886 +               .freq                   = 5785,
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),
4892 +       },
4893 +       {
4894 +               .freq                   = 5805,
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),
4900 +       },
4901 +       {
4902 +               .freq                   = 5825,
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),
4908 +       },
4909 +};
4910  
4911  void r2057_upload_inittabs(struct b43_wldev *dev)
4912  {
4913 @@ -109,33 +540,98 @@ void r2057_upload_inittabs(struct b43_wl
4914         u16 *table = NULL;
4915         u16 size, i;
4916  
4917 -       if (phy->rev == 7) {
4918 +       switch (phy->rev) {
4919 +       case 7:
4920                 table = r2057_rev4_init[0];
4921                 size = ARRAY_SIZE(r2057_rev4_init);
4922 -       } else if (phy->rev == 8 || phy->rev == 9) {
4923 +               break;
4924 +       case 8:
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);
4929 -                       } else {
4930 -                               table = r2057_rev5a_init[0];
4931 -                               size = ARRAY_SIZE(r2057_rev5a_init);
4932 -                       }
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);
4941                 }
4942 +               break;
4943 +       case 9:
4944 +               if (phy->radio_rev == 5) {
4945 +                       table = r2057_rev5a_init[0];
4946 +                       size = ARRAY_SIZE(r2057_rev5a_init);
4947 +               }
4948 +               break;
4949 +       case 16:
4950 +               if (phy->radio_rev == 9) {
4951 +                       table = r2057_rev9_init[0];
4952 +                       size = ARRAY_SIZE(r2057_rev9_init);
4953 +               }
4954 +               break;
4955 +       case 17:
4956 +               if (phy->radio_rev == 14) {
4957 +                       table = r2057_rev14_init[0];
4958 +                       size = ARRAY_SIZE(r2057_rev14_init);
4959 +               }
4960 +               break;
4961         }
4962  
4963 +       B43_WARN_ON(!table);
4964 +
4965         if (table) {
4966 -               for (i = 0; i < 10; i++) {
4967 -                       pr_info("radio_write 0x%X ", *table);
4968 -                       table++;
4969 -                       pr_info("0x%X\n", *table);
4970 -                       table++;
4971 +               for (i = 0; i < size; i++, table += 2)
4972 +                       b43_radio_write(dev, table[0], table[1]);
4973 +       }
4974 +}
4975 +
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)
4979 +{
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;
4984 +
4985 +       *tabent_r7 = NULL;
4986 +       *tabent_r7_2g = NULL;
4987 +
4988 +       switch (phy->rev) {
4989 +       case 8:
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);
4993 +               }
4994 +               break;
4995 +       case 16:
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);
4999 +               }
5000 +               break;
5001 +       case 17:
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);
5005 +               }
5006 +               break;
5007 +       default:
5008 +               break;
5009 +       }
5010 +
5011 +       if (e_r7) {
5012 +               for (i = 0; i < len; i++, e_r7++) {
5013 +                       if (e_r7->freq == freq) {
5014 +                               *tabent_r7 = e_r7;
5015 +                               return;
5016 +                       }
5017 +               }
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;
5022 +                               return;
5023 +                       }
5024                 }
5025 +       } else {
5026 +               B43_WARN_ON(1);
5027         }
5028  }
5029 --- a/drivers/net/wireless/b43/radio_2057.h
5030 +++ b/drivers/net/wireless/b43/radio_2057.h
5031 @@ -84,6 +84,8 @@
5032  #define R2057_CMOSBUF_RX_RCCR                  0x04c
5033  #define R2057_LOGEN_SEL_PKDET                  0x04d
5034  #define R2057_CMOSBUF_SHAREIQ_PTAT             0x04e
5035 +
5036 +/* MISC core 0 */
5037  #define R2057_RXTXBIAS_CONFIG_CORE0            0x04f
5038  #define R2057_TXGM_TXRF_PUS_CORE0              0x050
5039  #define R2057_TXGM_IDAC_BLEED_CORE0            0x051
5040 @@ -204,6 +206,8 @@
5041  #define R2057_RXBB_GPAIOSEL_RXLPF_RCCAL_CORE0  0x0d1
5042  #define R2057_LPF_GAIN_CORE0                   0x0d2
5043  #define R2057_DACBUF_IDACS_BW_CORE0            0x0d3
5044 +
5045 +/* MISC core 1 */
5046  #define R2057_RXTXBIAS_CONFIG_CORE1            0x0d4
5047  #define R2057_TXGM_TXRF_PUS_CORE1              0x0d5
5048  #define R2057_TXGM_IDAC_BLEED_CORE1            0x0d6
5049 @@ -324,6 +328,7 @@
5050  #define R2057_RXBB_GPAIOSEL_RXLPF_RCCAL_CORE1  0x156
5051  #define R2057_LPF_GAIN_CORE1                   0x157
5052  #define R2057_DACBUF_IDACS_BW_CORE1            0x158
5053 +
5054  #define R2057_DACBUF_VINCM_CORE1               0x159
5055  #define R2057_RCCAL_START_R1_Q1_P1             0x15a
5056  #define R2057_RCCAL_X1                         0x15b
5057 @@ -345,6 +350,8 @@
5058  #define R2057_RCCAL_BCAP_VAL                   0x16b
5059  #define R2057_RCCAL_HPC_VAL                    0x16c
5060  #define R2057_RCCAL_OVERRIDES                  0x16d
5061 +
5062 +/* TX core 0 */
5063  #define R2057_TX0_IQCAL_GAIN_BW                        0x170
5064  #define R2057_TX0_LOFT_FINE_I                  0x171
5065  #define R2057_TX0_LOFT_FINE_Q                  0x172
5066 @@ -362,6 +369,8 @@
5067  #define R2057_TX0_TXRXCOUPLE_2G_PWRUP          0x17e
5068  #define R2057_TX0_TXRXCOUPLE_5G_ATTEN          0x17f
5069  #define R2057_TX0_TXRXCOUPLE_5G_PWRUP          0x180
5070 +
5071 +/* TX core 1 */
5072  #define R2057_TX1_IQCAL_GAIN_BW                        0x190
5073  #define R2057_TX1_LOFT_FINE_I                  0x191
5074  #define R2057_TX1_LOFT_FINE_Q                  0x192
5075 @@ -379,6 +388,7 @@
5076  #define R2057_TX1_TXRXCOUPLE_2G_PWRUP          0x19e
5077  #define R2057_TX1_TXRXCOUPLE_5G_ATTEN          0x19f
5078  #define R2057_TX1_TXRXCOUPLE_5G_PWRUP          0x1a0
5079 +
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 @@
5084  
5085  #define R2057_VCM_MASK                         0x7
5086  
5087 +struct b43_nphy_chantabent_rev7 {
5088 +       /* The channel frequency in MHz */
5089 +       u16 freq;
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;
5121 +};
5122 +
5123 +struct b43_nphy_chantabent_rev7_2g {
5124 +       /* The channel frequency in MHz */
5125 +       u16 freq;
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;
5147 +};
5148 +
5149  void r2057_upload_inittabs(struct b43_wldev *dev);
5150  
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);
5154 +
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)
5161  
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 */
5165 +
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(
5172  }
5173  
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)
5177  {
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;
5181  
5182         switch (plcp->raw[0] & 0xF) {
5183         case 0xB:
5184 @@ -767,7 +768,7 @@ void b43_rx(struct b43_wldev *dev, struc
5185  
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));
5190         else
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=
5196  B43_SDIO=
5197  B43_BCMA_PIO=
5198  B43_PIO=
5199 +B43_PHY_G=
5200  B43_PHY_N=
5201  B43_PHY_LP=
5202  B43_PHY_HT=