9b4e85da3fb9aedd3f83fdb17365b7665b2d4eee
[15.05/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-15
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 @@ -331,6 +338,14 @@ static struct ieee80211_supported_band b
30         .n_bitrates     = b43_g_ratetable_size,
31  };
32  
33 +static struct ieee80211_supported_band b43_band_2ghz_limited = {
34 +       .band           = IEEE80211_BAND_2GHZ,
35 +       .channels       = b43_2ghz_chantable,
36 +       .n_channels     = b43_2ghz_chantable_limited_size,
37 +       .bitrates       = b43_g_ratetable,
38 +       .n_bitrates     = b43_g_ratetable_size,
39 +};
40 +
41  static void b43_wireless_core_exit(struct b43_wldev *dev);
42  static int b43_wireless_core_init(struct b43_wldev *dev);
43  static struct b43_wldev * b43_wireless_core_stop(struct b43_wldev *dev);
44 @@ -2201,52 +2216,82 @@ err_format:
45         return -EPROTO;
46  }
47  
48 +/* http://bcm-v4.sipsolutions.net/802.11/Init/Firmware */
49  static int b43_try_request_fw(struct b43_request_fw_context *ctx)
50  {
51         struct b43_wldev *dev = ctx->dev;
52         struct b43_firmware *fw = &ctx->dev->fw;
53 +       struct b43_phy *phy = &dev->phy;
54         const u8 rev = ctx->dev->dev->core_rev;
55         const char *filename;
56 -       u32 tmshigh;
57         int err;
58  
59 -       /* Files for HT and LCN were found by trying one by one */
60 -
61         /* Get microcode */
62 -       if ((rev >= 5) && (rev <= 10)) {
63 -               filename = "ucode5";
64 -       } else if ((rev >= 11) && (rev <= 12)) {
65 -               filename = "ucode11";
66 -       } else if (rev == 13) {
67 -               filename = "ucode13";
68 -       } else if (rev == 14) {
69 -               filename = "ucode14";
70 -       } else if (rev == 15) {
71 +       filename = NULL;
72 +       switch (rev) {
73 +       case 42:
74 +               if (phy->type == B43_PHYTYPE_AC)
75 +                       filename = "ucode42";
76 +               break;
77 +       case 40:
78 +               if (phy->type == B43_PHYTYPE_AC)
79 +                       filename = "ucode40";
80 +               break;
81 +       case 33:
82 +               if (phy->type == B43_PHYTYPE_LCN40)
83 +                       filename = "ucode33_lcn40";
84 +               break;
85 +       case 30:
86 +               if (phy->type == B43_PHYTYPE_N)
87 +                       filename = "ucode30_mimo";
88 +               break;
89 +       case 29:
90 +               if (phy->type == B43_PHYTYPE_HT)
91 +                       filename = "ucode29_mimo";
92 +               break;
93 +       case 26:
94 +               if (phy->type == B43_PHYTYPE_HT)
95 +                       filename = "ucode26_mimo";
96 +               break;
97 +       case 28:
98 +       case 25:
99 +               if (phy->type == B43_PHYTYPE_N)
100 +                       filename = "ucode25_mimo";
101 +               else if (phy->type == B43_PHYTYPE_LCN)
102 +                       filename = "ucode25_lcn";
103 +               break;
104 +       case 24:
105 +               if (phy->type == B43_PHYTYPE_LCN)
106 +                       filename = "ucode24_lcn";
107 +               break;
108 +       case 23:
109 +               if (phy->type == B43_PHYTYPE_N)
110 +                       filename = "ucode16_mimo";
111 +               break;
112 +       case 16 ... 19:
113 +               if (phy->type == B43_PHYTYPE_N)
114 +                       filename = "ucode16_mimo";
115 +               else if (phy->type == B43_PHYTYPE_LP)
116 +                       filename = "ucode16_lp";
117 +               break;
118 +       case 15:
119                 filename = "ucode15";
120 -       } else {
121 -               switch (dev->phy.type) {
122 -               case B43_PHYTYPE_N:
123 -                       if (rev >= 16)
124 -                               filename = "ucode16_mimo";
125 -                       else
126 -                               goto err_no_ucode;
127 -                       break;
128 -               case B43_PHYTYPE_HT:
129 -                       if (rev == 29)
130 -                               filename = "ucode29_mimo";
131 -                       else
132 -                               goto err_no_ucode;
133 -                       break;
134 -               case B43_PHYTYPE_LCN:
135 -                       if (rev == 24)
136 -                               filename = "ucode24_mimo";
137 -                       else
138 -                               goto err_no_ucode;
139 -                       break;
140 -               default:
141 -                       goto err_no_ucode;
142 -               }
143 +               break;
144 +       case 14:
145 +               filename = "ucode14";
146 +               break;
147 +       case 13:
148 +               filename = "ucode13";
149 +               break;
150 +       case 11 ... 12:
151 +               filename = "ucode11";
152 +               break;
153 +       case 5 ... 10:
154 +               filename = "ucode5";
155 +               break;
156         }
157 +       if (!filename)
158 +               goto err_no_ucode;
159         err = b43_do_request_fw(ctx, filename, &fw->ucode, true);
160         if (err)
161                 goto err_load;
162 @@ -2268,117 +2313,121 @@ static int b43_try_request_fw(struct b43
163                 goto err_load;
164  
165         /* Get initvals */
166 +       filename = NULL;
167         switch (dev->phy.type) {
168 -       case B43_PHYTYPE_A:
169 -               if ((rev >= 5) && (rev <= 10)) {
170 -                       tmshigh = ssb_read32(dev->dev->sdev, SSB_TMSHIGH);
171 -                       if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY)
172 -                               filename = "a0g1initvals5";
173 -                       else
174 -                               filename = "a0g0initvals5";
175 -               } else
176 -                       goto err_no_initvals;
177 -               break;
178         case B43_PHYTYPE_G:
179 -               if ((rev >= 5) && (rev <= 10))
180 -                       filename = "b0g0initvals5";
181 -               else if (rev >= 13)
182 +               if (rev == 13)
183                         filename = "b0g0initvals13";
184 -               else
185 -                       goto err_no_initvals;
186 +               else if (rev >= 5 && rev <= 10)
187 +                       filename = "b0g0initvals5";
188                 break;
189         case B43_PHYTYPE_N:
190 -               if (rev >= 16)
191 +               if (rev == 30)
192 +                       filename = "n16initvals30";
193 +               else if (rev == 28 || rev == 25)
194 +                       filename = "n0initvals25";
195 +               else if (rev == 24)
196 +                       filename = "n0initvals24";
197 +               else if (rev == 23)
198 +                       filename = "n0initvals16"; /* What about n0initvals22? */
199 +               else if (rev >= 16 && rev <= 18)
200                         filename = "n0initvals16";
201 -               else if ((rev >= 11) && (rev <= 12))
202 +               else if (rev >= 11 && rev <= 12)
203                         filename = "n0initvals11";
204 -               else
205 -                       goto err_no_initvals;
206                 break;
207         case B43_PHYTYPE_LP:
208 -               if (rev == 13)
209 -                       filename = "lp0initvals13";
210 +               if (rev >= 16 && rev <= 18)
211 +                       filename = "lp0initvals16";
212 +               else if (rev == 15)
213 +                       filename = "lp0initvals15";
214                 else if (rev == 14)
215                         filename = "lp0initvals14";
216 -               else if (rev >= 15)
217 -                       filename = "lp0initvals15";
218 -               else
219 -                       goto err_no_initvals;
220 +               else if (rev == 13)
221 +                       filename = "lp0initvals13";
222                 break;
223         case B43_PHYTYPE_HT:
224                 if (rev == 29)
225                         filename = "ht0initvals29";
226 -               else
227 -                       goto err_no_initvals;
228 +               else if (rev == 26)
229 +                       filename = "ht0initvals26";
230                 break;
231         case B43_PHYTYPE_LCN:
232                 if (rev == 24)
233                         filename = "lcn0initvals24";
234 -               else
235 -                       goto err_no_initvals;
236                 break;
237 -       default:
238 -               goto err_no_initvals;
239 +       case B43_PHYTYPE_LCN40:
240 +               if (rev == 33)
241 +                       filename = "lcn400initvals33";
242 +               break;
243 +       case B43_PHYTYPE_AC:
244 +               if (rev == 42)
245 +                       filename = "ac1initvals42";
246 +               else if (rev == 40)
247 +                       filename = "ac0initvals40";
248 +               break;
249         }
250 +       if (!filename)
251 +               goto err_no_initvals;
252         err = b43_do_request_fw(ctx, filename, &fw->initvals, false);
253         if (err)
254                 goto err_load;
255  
256         /* Get bandswitch initvals */
257 +       filename = NULL;
258         switch (dev->phy.type) {
259 -       case B43_PHYTYPE_A:
260 -               if ((rev >= 5) && (rev <= 10)) {
261 -                       tmshigh = ssb_read32(dev->dev->sdev, SSB_TMSHIGH);
262 -                       if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY)
263 -                               filename = "a0g1bsinitvals5";
264 -                       else
265 -                               filename = "a0g0bsinitvals5";
266 -               } else if (rev >= 11)
267 -                       filename = NULL;
268 -               else
269 -                       goto err_no_initvals;
270 -               break;
271         case B43_PHYTYPE_G:
272 -               if ((rev >= 5) && (rev <= 10))
273 +               if (rev == 13)
274 +                       filename = "b0g0bsinitvals13";
275 +               else if (rev >= 5 && rev <= 10)
276                         filename = "b0g0bsinitvals5";
277 -               else if (rev >= 11)
278 -                       filename = NULL;
279 -               else
280 -                       goto err_no_initvals;
281                 break;
282         case B43_PHYTYPE_N:
283 -               if (rev >= 16)
284 +               if (rev == 30)
285 +                       filename = "n16bsinitvals30";
286 +               else if (rev == 28 || rev == 25)
287 +                       filename = "n0bsinitvals25";
288 +               else if (rev == 24)
289 +                       filename = "n0bsinitvals24";
290 +               else if (rev == 23)
291 +                       filename = "n0bsinitvals16"; /* What about n0bsinitvals22? */
292 +               else if (rev >= 16 && rev <= 18)
293                         filename = "n0bsinitvals16";
294 -               else if ((rev >= 11) && (rev <= 12))
295 +               else if (rev >= 11 && rev <= 12)
296                         filename = "n0bsinitvals11";
297 -               else
298 -                       goto err_no_initvals;
299                 break;
300         case B43_PHYTYPE_LP:
301 -               if (rev == 13)
302 -                       filename = "lp0bsinitvals13";
303 +               if (rev >= 16 && rev <= 18)
304 +                       filename = "lp0bsinitvals16";
305 +               else if (rev == 15)
306 +                       filename = "lp0bsinitvals15";
307                 else if (rev == 14)
308                         filename = "lp0bsinitvals14";
309 -               else if (rev >= 15)
310 -                       filename = "lp0bsinitvals15";
311 -               else
312 -                       goto err_no_initvals;
313 +               else if (rev == 13)
314 +                       filename = "lp0bsinitvals13";
315                 break;
316         case B43_PHYTYPE_HT:
317                 if (rev == 29)
318                         filename = "ht0bsinitvals29";
319 -               else
320 -                       goto err_no_initvals;
321 +               else if (rev == 26)
322 +                       filename = "ht0bsinitvals26";
323                 break;
324         case B43_PHYTYPE_LCN:
325                 if (rev == 24)
326                         filename = "lcn0bsinitvals24";
327 -               else
328 -                       goto err_no_initvals;
329                 break;
330 -       default:
331 -               goto err_no_initvals;
332 +       case B43_PHYTYPE_LCN40:
333 +               if (rev == 33)
334 +                       filename = "lcn400bsinitvals33";
335 +               break;
336 +       case B43_PHYTYPE_AC:
337 +               if (rev == 42)
338 +                       filename = "ac1bsinitvals42";
339 +               else if (rev == 40)
340 +                       filename = "ac0bsinitvals40";
341 +               break;
342         }
343 +       if (!filename)
344 +               goto err_no_initvals;
345         err = b43_do_request_fw(ctx, filename, &fw->initvals_band, false);
346         if (err)
347                 goto err_load;
348 @@ -2915,6 +2964,45 @@ void b43_mac_phy_clock_set(struct b43_wl
349         }
350  }
351  
352 +/* brcms_b_switch_macfreq */
353 +void b43_mac_switch_freq(struct b43_wldev *dev, u8 spurmode)
354 +{
355 +       u16 chip_id = dev->dev->chip_id;
356 +
357 +       if (chip_id == BCMA_CHIP_ID_BCM43217 ||
358 +           chip_id == BCMA_CHIP_ID_BCM43222 ||
359 +           chip_id == BCMA_CHIP_ID_BCM43224 ||
360 +           chip_id == BCMA_CHIP_ID_BCM43225 ||
361 +           chip_id == BCMA_CHIP_ID_BCM43227 ||
362 +           chip_id == BCMA_CHIP_ID_BCM43228) {
363 +               switch (spurmode) {
364 +               case 2: /* 126 Mhz */
365 +                       b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x2082);
366 +                       b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
367 +                       break;
368 +               case 1: /* 123 Mhz */
369 +                       b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x5341);
370 +                       b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
371 +                       break;
372 +               default: /* 120 Mhz */
373 +                       b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x8889);
374 +                       b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
375 +                       break;
376 +               }
377 +       } else if (dev->phy.type == B43_PHYTYPE_LCN) {
378 +               switch (spurmode) {
379 +               case 1: /* 82 Mhz */
380 +                       b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x7CE0);
381 +                       b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0xC);
382 +                       break;
383 +               default: /* 80 Mhz */
384 +                       b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0xCCCD);
385 +                       b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0xC);
386 +                       break;
387 +               }
388 +       }
389 +}
390 +
391  static void b43_adjust_opmode(struct b43_wldev *dev)
392  {
393         struct b43_wl *wl = dev->wl;
394 @@ -3742,7 +3830,9 @@ static int b43_switch_band(struct b43_wl
395         b43dbg(dev->wl, "Switching to %s GHz band\n",
396                band_to_string(chan->band));
397  
398 -       b43_software_rfkill(dev, true);
399 +       /* Some new devices don't need disabling radio for band switching */
400 +       if (!(phy->type == B43_PHYTYPE_N && phy->rev >= 3))
401 +               b43_software_rfkill(dev, true);
402  
403         phy->gmode = gmode;
404         b43_phy_put_into_reset(dev);
405 @@ -3796,38 +3886,29 @@ static void b43_set_retry_limits(struct
406  static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
407  {
408         struct b43_wl *wl = hw_to_b43_wl(hw);
409 -       struct b43_wldev *dev;
410 -       struct b43_phy *phy;
411 +       struct b43_wldev *dev = wl->current_dev;
412 +       struct b43_phy *phy = &dev->phy;
413         struct ieee80211_conf *conf = &hw->conf;
414         int antenna;
415         int err = 0;
416 -       bool reload_bss = false;
417  
418         mutex_lock(&wl->mutex);
419 -
420 -       dev = wl->current_dev;
421 -
422         b43_mac_suspend(dev);
423  
424 -       /* Switch the band (if necessary). This might change the active core. */
425 -       err = b43_switch_band(dev, conf->chandef.chan);
426 -       if (err)
427 -               goto out_unlock_mutex;
428 +       if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
429 +               phy->chandef = &conf->chandef;
430 +               phy->channel = conf->chandef.chan->hw_value;
431  
432 -       /* Need to reload all settings if the core changed */
433 -       if (dev != wl->current_dev) {
434 -               dev = wl->current_dev;
435 -               changed = ~0;
436 -               reload_bss = true;
437 -       }
438 +               /* Switch the band (if necessary). */
439 +               err = b43_switch_band(dev, conf->chandef.chan);
440 +               if (err)
441 +                       goto out_mac_enable;
442  
443 -       phy = &dev->phy;
444 -
445 -       if (conf_is_ht(conf))
446 -               phy->is_40mhz =
447 -                       (conf_is_ht40_minus(conf) || conf_is_ht40_plus(conf));
448 -       else
449 -               phy->is_40mhz = false;
450 +               /* Switch to the requested channel.
451 +                * The firmware takes care of races with the TX handler.
452 +                */
453 +               b43_switch_channel(dev, phy->channel);
454 +       }
455  
456         if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
457                 b43_set_retry_limits(dev, conf->short_frame_max_tx_count,
458 @@ -3836,11 +3917,6 @@ static int b43_op_config(struct ieee8021
459         if (!changed)
460                 goto out_mac_enable;
461  
462 -       /* Switch to the requested channel.
463 -        * The firmware takes care of races with the TX handler. */
464 -       if (conf->chandef.chan->hw_value != phy->channel)
465 -               b43_switch_channel(dev, conf->chandef.chan->hw_value);
466 -
467         dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_MONITOR);
468  
469         /* Adjust the desired TX power level. */
470 @@ -3876,12 +3952,8 @@ static int b43_op_config(struct ieee8021
471  
472  out_mac_enable:
473         b43_mac_enable(dev);
474 -out_unlock_mutex:
475         mutex_unlock(&wl->mutex);
476  
477 -       if (wl->vif && reload_bss)
478 -               b43_op_bss_info_changed(hw, wl->vif, &wl->vif->bss_conf, ~0);
479 -
480         return err;
481  }
482  
483 @@ -4307,13 +4379,15 @@ static char *b43_phy_name(struct b43_wld
484  static int b43_phy_versioning(struct b43_wldev *dev)
485  {
486         struct b43_phy *phy = &dev->phy;
487 +       const u8 core_rev = dev->dev->core_rev;
488         u32 tmp;
489         u8 analog_type;
490         u8 phy_type;
491         u8 phy_rev;
492         u16 radio_manuf;
493 -       u16 radio_ver;
494 +       u16 radio_id;
495         u16 radio_rev;
496 +       u8 radio_ver;
497         int unsupported = 0;
498  
499         /* Get PHY versioning */
500 @@ -4321,23 +4395,23 @@ static int b43_phy_versioning(struct b43
501         analog_type = (tmp & B43_PHYVER_ANALOG) >> B43_PHYVER_ANALOG_SHIFT;
502         phy_type = (tmp & B43_PHYVER_TYPE) >> B43_PHYVER_TYPE_SHIFT;
503         phy_rev = (tmp & B43_PHYVER_VERSION);
504 +
505 +       /* LCNXN is continuation of N which run out of revisions */
506 +       if (phy_type == B43_PHYTYPE_LCNXN) {
507 +               phy_type = B43_PHYTYPE_N;
508 +               phy_rev += 16;
509 +       }
510 +
511         switch (phy_type) {
512 -       case B43_PHYTYPE_A:
513 -               if (phy_rev >= 4)
514 -                       unsupported = 1;
515 -               break;
516 -       case B43_PHYTYPE_B:
517 -               if (phy_rev != 2 && phy_rev != 4 && phy_rev != 6
518 -                   && phy_rev != 7)
519 -                       unsupported = 1;
520 -               break;
521 +#ifdef CPTCFG_B43_PHY_G
522         case B43_PHYTYPE_G:
523                 if (phy_rev > 9)
524                         unsupported = 1;
525                 break;
526 +#endif
527  #ifdef CPTCFG_B43_PHY_N
528         case B43_PHYTYPE_N:
529 -               if (phy_rev > 9)
530 +               if (phy_rev >= 19)
531                         unsupported = 1;
532                 break;
533  #endif
534 @@ -4372,7 +4446,17 @@ static int b43_phy_versioning(struct b43
535                 analog_type, phy_type, b43_phy_name(dev, phy_type), phy_rev);
536  
537         /* Get RADIO versioning */
538 -       if (dev->dev->core_rev >= 24) {
539 +       if (core_rev == 40 || core_rev == 42) {
540 +               radio_manuf = 0x17F;
541 +
542 +               b43_write16(dev, B43_MMIO_RADIO24_CONTROL, 0);
543 +               radio_rev = b43_read16(dev, B43_MMIO_RADIO24_DATA);
544 +
545 +               b43_write16(dev, B43_MMIO_RADIO24_CONTROL, 1);
546 +               radio_id = b43_read16(dev, B43_MMIO_RADIO24_DATA);
547 +
548 +               radio_ver = 0; /* Is there version somewhere? */
549 +       } else if (core_rev >= 24) {
550                 u16 radio24[3];
551  
552                 for (tmp = 0; tmp < 3; tmp++) {
553 @@ -4380,12 +4464,10 @@ static int b43_phy_versioning(struct b43
554                         radio24[tmp] = b43_read16(dev, B43_MMIO_RADIO24_DATA);
555                 }
556  
557 -               /* Broadcom uses "id" for our "ver" and has separated "ver" */
558 -               /* radio_ver = (radio24[0] & 0xF0) >> 4; */
559 -
560                 radio_manuf = 0x17F;
561 -               radio_ver = (radio24[2] << 8) | radio24[1];
562 +               radio_id = (radio24[2] << 8) | radio24[1];
563                 radio_rev = (radio24[0] & 0xF);
564 +               radio_ver = (radio24[0] & 0xF0) >> 4;
565         } else {
566                 if (dev->dev->chip_id == 0x4317) {
567                         if (dev->dev->chip_rev == 0)
568 @@ -4404,15 +4486,16 @@ static int b43_phy_versioning(struct b43
569                                 << 16;
570                 }
571                 radio_manuf = (tmp & 0x00000FFF);
572 -               radio_ver = (tmp & 0x0FFFF000) >> 12;
573 +               radio_id = (tmp & 0x0FFFF000) >> 12;
574                 radio_rev = (tmp & 0xF0000000) >> 28;
575 +               radio_ver = 0; /* Probably not available on old hw */
576         }
577  
578         if (radio_manuf != 0x17F /* Broadcom */)
579                 unsupported = 1;
580         switch (phy_type) {
581         case B43_PHYTYPE_A:
582 -               if (radio_ver != 0x2060)
583 +               if (radio_id != 0x2060)
584                         unsupported = 1;
585                 if (radio_rev != 1)
586                         unsupported = 1;
587 @@ -4420,43 +4503,49 @@ static int b43_phy_versioning(struct b43
588                         unsupported = 1;
589                 break;
590         case B43_PHYTYPE_B:
591 -               if ((radio_ver & 0xFFF0) != 0x2050)
592 +               if ((radio_id & 0xFFF0) != 0x2050)
593                         unsupported = 1;
594                 break;
595         case B43_PHYTYPE_G:
596 -               if (radio_ver != 0x2050)
597 +               if (radio_id != 0x2050)
598                         unsupported = 1;
599                 break;
600         case B43_PHYTYPE_N:
601 -               if (radio_ver != 0x2055 && radio_ver != 0x2056)
602 +               if (radio_id != 0x2055 && radio_id != 0x2056 &&
603 +                   radio_id != 0x2057)
604 +                       unsupported = 1;
605 +               if (radio_id == 0x2057 &&
606 +                   !(radio_rev == 9 || radio_rev == 14))
607                         unsupported = 1;
608                 break;
609         case B43_PHYTYPE_LP:
610 -               if (radio_ver != 0x2062 && radio_ver != 0x2063)
611 +               if (radio_id != 0x2062 && radio_id != 0x2063)
612                         unsupported = 1;
613                 break;
614         case B43_PHYTYPE_HT:
615 -               if (radio_ver != 0x2059)
616 +               if (radio_id != 0x2059)
617                         unsupported = 1;
618                 break;
619         case B43_PHYTYPE_LCN:
620 -               if (radio_ver != 0x2064)
621 +               if (radio_id != 0x2064)
622                         unsupported = 1;
623                 break;
624         default:
625                 B43_WARN_ON(1);
626         }
627         if (unsupported) {
628 -               b43err(dev->wl, "FOUND UNSUPPORTED RADIO "
629 -                      "(Manuf 0x%X, Version 0x%X, Revision %u)\n",
630 -                      radio_manuf, radio_ver, radio_rev);
631 +               b43err(dev->wl,
632 +                      "FOUND UNSUPPORTED RADIO (Manuf 0x%X, ID 0x%X, Revision %u, Version %u)\n",
633 +                      radio_manuf, radio_id, radio_rev, radio_ver);
634                 return -EOPNOTSUPP;
635         }
636 -       b43dbg(dev->wl, "Found Radio: Manuf 0x%X, Version 0x%X, Revision %u\n",
637 -              radio_manuf, radio_ver, radio_rev);
638 +       b43info(dev->wl,
639 +               "Found Radio: Manuf 0x%X, ID 0x%X, Revision %u, Version %u\n",
640 +               radio_manuf, radio_id, radio_rev, radio_ver);
641  
642 +       /* FIXME: b43 treats "id" as "ver" and ignores the real "ver" */
643         phy->radio_manuf = radio_manuf;
644 -       phy->radio_ver = radio_ver;
645 +       phy->radio_ver = radio_id;
646         phy->radio_rev = radio_rev;
647  
648         phy->analog = analog_type;
649 @@ -5064,9 +5153,16 @@ static int b43_setup_bands(struct b43_wl
650                            bool have_2ghz_phy, bool have_5ghz_phy)
651  {
652         struct ieee80211_hw *hw = dev->wl->hw;
653 +       struct b43_phy *phy = &dev->phy;
654 +       bool limited_2g;
655 +
656 +       /* We don't support all 2 GHz channels on some devices */
657 +       limited_2g = phy->radio_ver == 0x2057 &&
658 +                    (phy->radio_rev == 9 || phy->radio_rev == 14);
659  
660         if (have_2ghz_phy)
661 -               hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &b43_band_2GHz;
662 +               hw->wiphy->bands[IEEE80211_BAND_2GHZ] = limited_2g ?
663 +                       &b43_band_2ghz_limited : &b43_band_2GHz;
664         if (dev->phy.type == B43_PHYTYPE_N) {
665                 if (have_5ghz_phy)
666                         hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &b43_band_5GHz_nphy;
667 @@ -5164,6 +5260,7 @@ static void b43_supported_bands(struct b
668  static int b43_wireless_core_attach(struct b43_wldev *dev)
669  {
670         struct b43_wl *wl = dev->wl;
671 +       struct b43_phy *phy = &dev->phy;
672         int err;
673         u32 tmp;
674         bool have_2ghz_phy = false, have_5ghz_phy = false;
675 @@ -5181,6 +5278,8 @@ static int b43_wireless_core_attach(stru
676                 goto out;
677         }
678  
679 +       phy->do_full_init = true;
680 +
681         /* Try to guess supported bands for the first init needs */
682         switch (dev->dev->bus_type) {
683  #ifdef CPTCFG_B43_BCMA
684 @@ -5214,14 +5313,16 @@ static int b43_wireless_core_attach(stru
685         b43_supported_bands(dev, &have_2ghz_phy, &have_5ghz_phy);
686  
687         /* We don't support 5 GHz on some PHYs yet */
688 -       switch (dev->phy.type) {
689 -       case B43_PHYTYPE_A:
690 -       case B43_PHYTYPE_G:
691 -       case B43_PHYTYPE_N:
692 -       case B43_PHYTYPE_LP:
693 -       case B43_PHYTYPE_HT:
694 -               b43warn(wl, "5 GHz band is unsupported on this PHY\n");
695 -               have_5ghz_phy = false;
696 +       if (have_5ghz_phy) {
697 +               switch (dev->phy.type) {
698 +               case B43_PHYTYPE_A:
699 +               case B43_PHYTYPE_G:
700 +               case B43_PHYTYPE_N:
701 +               case B43_PHYTYPE_LP:
702 +               case B43_PHYTYPE_HT:
703 +                       b43warn(wl, "5 GHz band is unsupported on this PHY\n");
704 +                       have_5ghz_phy = false;
705 +               }
706         }
707  
708         if (!have_2ghz_phy && !have_5ghz_phy) {
709 --- a/drivers/net/wireless/b43/main.h
710 +++ b/drivers/net/wireless/b43/main.h
711 @@ -99,6 +99,7 @@ void b43_power_saving_ctl_bits(struct b4
712  void b43_mac_suspend(struct b43_wldev *dev);
713  void b43_mac_enable(struct b43_wldev *dev);
714  void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on);
715 +void b43_mac_switch_freq(struct b43_wldev *dev, u8 spurmode);
716  
717  
718  struct b43_request_fw_context;
719 --- a/drivers/net/wireless/b43/phy_common.c
720 +++ b/drivers/net/wireless/b43/phy_common.c
721 @@ -45,11 +45,10 @@ int b43_phy_allocate(struct b43_wldev *d
722         phy->ops = NULL;
723  
724         switch (phy->type) {
725 -       case B43_PHYTYPE_A:
726 -               phy->ops = &b43_phyops_a;
727 -               break;
728         case B43_PHYTYPE_G:
729 +#ifdef CPTCFG_B43_PHY_G
730                 phy->ops = &b43_phyops_g;
731 +#endif
732                 break;
733         case B43_PHYTYPE_N:
734  #ifdef CPTCFG_B43_PHY_N
735 @@ -94,18 +93,25 @@ int b43_phy_init(struct b43_wldev *dev)
736         const struct b43_phy_operations *ops = phy->ops;
737         int err;
738  
739 -       phy->channel = ops->get_default_chan(dev);
740 +       /* During PHY init we need to use some channel. On the first init this
741 +        * function is called *before* b43_op_config, so our pointer is NULL.
742 +        */
743 +       if (!phy->chandef) {
744 +               phy->chandef = &dev->wl->hw->conf.chandef;
745 +               phy->channel = phy->chandef->chan->hw_value;
746 +       }
747  
748         phy->ops->switch_analog(dev, true);
749         b43_software_rfkill(dev, false);
750 +
751         err = ops->init(dev);
752         if (err) {
753                 b43err(dev->wl, "PHY init failed\n");
754                 goto err_block_rf;
755         }
756 -       /* Make sure to switch hardware and firmware (SHM) to
757 -        * the default channel. */
758 -       err = b43_switch_channel(dev, ops->get_default_chan(dev));
759 +       phy->do_full_init = false;
760 +
761 +       err = b43_switch_channel(dev, phy->channel);
762         if (err) {
763                 b43err(dev->wl, "PHY init: Channel switch to default failed\n");
764                 goto err_phy_exit;
765 @@ -114,6 +120,7 @@ int b43_phy_init(struct b43_wldev *dev)
766         return 0;
767  
768  err_phy_exit:
769 +       phy->do_full_init = true;
770         if (ops->exit)
771                 ops->exit(dev);
772  err_block_rf:
773 @@ -127,6 +134,7 @@ void b43_phy_exit(struct b43_wldev *dev)
774         const struct b43_phy_operations *ops = dev->phy.ops;
775  
776         b43_software_rfkill(dev, true);
777 +       dev->phy.do_full_init = true;
778         if (ops->exit)
779                 ops->exit(dev);
780  }
781 @@ -403,9 +411,6 @@ int b43_switch_channel(struct b43_wldev
782         u16 channelcookie, savedcookie;
783         int err;
784  
785 -       if (new_channel == B43_DEFAULT_CHANNEL)
786 -               new_channel = phy->ops->get_default_chan(dev);
787 -
788         /* First we set the channel radio code to prevent the
789          * firmware from sending ghost packets.
790          */
791 @@ -423,7 +428,6 @@ int b43_switch_channel(struct b43_wldev
792         if (err)
793                 goto err_restore_cookie;
794  
795 -       dev->phy.channel = new_channel;
796         /* Wait for the radio to tune to the channel and stabilize. */
797         msleep(8);
798  
799 @@ -542,10 +546,9 @@ void b43_phyop_switch_analog_generic(str
800  }
801  
802  
803 -bool b43_channel_type_is_40mhz(enum nl80211_channel_type channel_type)
804 +bool b43_is_40mhz(struct b43_wldev *dev)
805  {
806 -       return (channel_type == NL80211_CHAN_HT40MINUS ||
807 -               channel_type == NL80211_CHAN_HT40PLUS);
808 +       return dev->phy.chandef->width == NL80211_CHAN_WIDTH_40;
809  }
810  
811  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/BmacPhyClkFgc */
812 --- a/drivers/net/wireless/b43/phy_common.h
813 +++ b/drivers/net/wireless/b43/phy_common.h
814 @@ -228,12 +228,12 @@ struct b43_phy {
815         bool supports_2ghz;
816         bool supports_5ghz;
817  
818 -       /* HT info */
819 -       bool is_40mhz;
820 -
821         /* Is GMODE (2 GHz mode) bit enabled? */
822         bool gmode;
823  
824 +       /* After power reset full init has to be performed */
825 +       bool do_full_init;
826 +
827         /* Analog Type */
828         u8 analog;
829         /* B43_PHYTYPE_ */
830 @@ -264,9 +264,8 @@ struct b43_phy {
831         unsigned long next_txpwr_check_time;
832  
833         /* Current channel */
834 +       struct cfg80211_chan_def *chandef;
835         unsigned int channel;
836 -       u16 channel_freq;
837 -       enum nl80211_channel_type channel_type;
838  
839         /* PHY TX errors counter. */
840         atomic_t txerr_cnt;
841 @@ -397,10 +396,6 @@ void b43_phy_take_out_of_reset(struct b4
842   * b43_switch_channel - Switch to another channel
843   */
844  int b43_switch_channel(struct b43_wldev *dev, unsigned int new_channel);
845 -/**
846 - * B43_DEFAULT_CHANNEL - Switch to the default channel.
847 - */
848 -#define B43_DEFAULT_CHANNEL    UINT_MAX
849  
850  /**
851   * b43_software_rfkill - Turn the radio ON or OFF in software.
852 @@ -451,7 +446,7 @@ int b43_phy_shm_tssi_read(struct b43_wld
853   */
854  void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on);
855  
856 -bool b43_channel_type_is_40mhz(enum nl80211_channel_type channel_type);
857 +bool b43_is_40mhz(struct b43_wldev *dev);
858  
859  void b43_phy_force_clock(struct b43_wldev *dev, bool force);
860  
861 --- a/drivers/net/wireless/b43/phy_lcn.c
862 +++ b/drivers/net/wireless/b43/phy_lcn.c
863 @@ -54,39 +54,6 @@ enum lcn_sense_type {
864         B43_SENSE_VBAT,
865  };
866  
867 -/* In theory it's PHY common function, move if needed */
868 -/* brcms_b_switch_macfreq */
869 -static void b43_phy_switch_macfreq(struct b43_wldev *dev, u8 spurmode)
870 -{
871 -       if (dev->dev->chip_id == 43224 || dev->dev->chip_id == 43225) {
872 -               switch (spurmode) {
873 -               case 2:         /* 126 Mhz */
874 -                       b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x2082);
875 -                       b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
876 -                       break;
877 -               case 1:         /* 123 Mhz */
878 -                       b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x5341);
879 -                       b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
880 -                       break;
881 -               default:        /* 120 Mhz */
882 -                       b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x8889);
883 -                       b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
884 -                       break;
885 -               }
886 -       } else if (dev->phy.type == B43_PHYTYPE_LCN) {
887 -               switch (spurmode) {
888 -               case 1:         /* 82 Mhz */
889 -                       b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x7CE0);
890 -                       b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0xC);
891 -                       break;
892 -               default:        /* 80 Mhz */
893 -                       b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0xCCCD);
894 -                       b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0xC);
895 -                       break;
896 -               }
897 -       }
898 -}
899 -
900  /**************************************************
901   * Radio 2064.
902   **************************************************/
903 @@ -609,7 +576,7 @@ static void b43_phy_lcn_txrx_spur_avoida
904                 b43_phy_write(dev, 0x93b, ((0 << 13) + 23));
905                 b43_phy_write(dev, 0x93c, ((0 << 13) + 1989));
906         }
907 -       b43_phy_switch_macfreq(dev, enable);
908 +       b43_mac_switch_freq(dev, enable);
909  }
910  
911  /**************************************************
912 --- a/drivers/net/wireless/b43/phy_n.c
913 +++ b/drivers/net/wireless/b43/phy_n.c
914 @@ -36,6 +36,7 @@
915  #include "main.h"
916  
917  struct nphy_txgains {
918 +       u16 tx_lpf[2];
919         u16 txgm[2];
920         u16 pga[2];
921         u16 pad[2];
922 @@ -43,6 +44,7 @@ struct nphy_txgains {
923  };
924  
925  struct nphy_iqcal_params {
926 +       u16 tx_lpf;
927         u16 txgm;
928         u16 pga;
929         u16 pad;
930 @@ -69,6 +71,14 @@ enum b43_nphy_rf_sequence {
931         B43_RFSEQ_UPDATE_GAINU,
932  };
933  
934 +enum n_rf_ctl_over_cmd {
935 +       N_RF_CTL_OVER_CMD_RXRF_PU = 0,
936 +       N_RF_CTL_OVER_CMD_RX_PU = 1,
937 +       N_RF_CTL_OVER_CMD_TX_PU = 2,
938 +       N_RF_CTL_OVER_CMD_RX_GAIN = 3,
939 +       N_RF_CTL_OVER_CMD_TX_GAIN = 4,
940 +};
941 +
942  enum n_intc_override {
943         N_INTC_OVERRIDE_OFF = 0,
944         N_INTC_OVERRIDE_TRSW = 1,
945 @@ -140,11 +150,19 @@ ok:
946         b43_phy_write(dev, B43_NPHY_RFSEQMODE, seq_mode);
947  }
948  
949 +static void b43_nphy_rf_ctl_override_rev19(struct b43_wldev *dev, u16 field,
950 +                                          u16 value, u8 core, bool off,
951 +                                          u8 override_id)
952 +{
953 +       /* TODO */
954 +}
955 +
956  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverrideRev7 */
957  static void b43_nphy_rf_ctl_override_rev7(struct b43_wldev *dev, u16 field,
958                                           u16 value, u8 core, bool off,
959                                           u8 override)
960  {
961 +       struct b43_phy *phy = &dev->phy;
962         const struct nphy_rf_control_override_rev7 *e;
963         u16 en_addrs[3][2] = {
964                 { 0x0E7, 0x0EC }, { 0x342, 0x343 }, { 0x346, 0x347 }
965 @@ -154,6 +172,11 @@ static void b43_nphy_rf_ctl_override_rev
966         u16 val_addr;
967         u8 i;
968  
969 +       if (phy->rev >= 19 || phy->rev < 3) {
970 +               B43_WARN_ON(1);
971 +               return;
972 +       }
973 +
974         /* Remember: we can get NULL! */
975         e = b43_nphy_get_rf_ctl_over_rev7(dev, field, override);
976  
977 @@ -181,6 +204,50 @@ static void b43_nphy_rf_ctl_override_rev
978         }
979  }
980  
981 +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverideOneToMany */
982 +static void b43_nphy_rf_ctl_override_one_to_many(struct b43_wldev *dev,
983 +                                                enum n_rf_ctl_over_cmd cmd,
984 +                                                u16 value, u8 core, bool off)
985 +{
986 +       struct b43_phy *phy = &dev->phy;
987 +       u16 tmp;
988 +
989 +       B43_WARN_ON(phy->rev < 7);
990 +
991 +       switch (cmd) {
992 +       case N_RF_CTL_OVER_CMD_RXRF_PU:
993 +               b43_nphy_rf_ctl_override_rev7(dev, 0x20, value, core, off, 1);
994 +               b43_nphy_rf_ctl_override_rev7(dev, 0x10, value, core, off, 1);
995 +               b43_nphy_rf_ctl_override_rev7(dev, 0x08, value, core, off, 1);
996 +               break;
997 +       case N_RF_CTL_OVER_CMD_RX_PU:
998 +               b43_nphy_rf_ctl_override_rev7(dev, 0x4, value, core, off, 1);
999 +               b43_nphy_rf_ctl_override_rev7(dev, 0x2, value, core, off, 1);
1000 +               b43_nphy_rf_ctl_override_rev7(dev, 0x1, value, core, off, 1);
1001 +               b43_nphy_rf_ctl_override_rev7(dev, 0x2, value, core, off, 2);
1002 +               b43_nphy_rf_ctl_override_rev7(dev, 0x0800, value, core, off, 1);
1003 +               break;
1004 +       case N_RF_CTL_OVER_CMD_TX_PU:
1005 +               b43_nphy_rf_ctl_override_rev7(dev, 0x4, value, core, off, 0);
1006 +               b43_nphy_rf_ctl_override_rev7(dev, 0x2, value, core, off, 1);
1007 +               b43_nphy_rf_ctl_override_rev7(dev, 0x1, value, core, off, 2);
1008 +               b43_nphy_rf_ctl_override_rev7(dev, 0x0800, value, core, off, 1);
1009 +               break;
1010 +       case N_RF_CTL_OVER_CMD_RX_GAIN:
1011 +               tmp = value & 0xFF;
1012 +               b43_nphy_rf_ctl_override_rev7(dev, 0x0800, tmp, core, off, 0);
1013 +               tmp = value >> 8;
1014 +               b43_nphy_rf_ctl_override_rev7(dev, 0x6000, tmp, core, off, 0);
1015 +               break;
1016 +       case N_RF_CTL_OVER_CMD_TX_GAIN:
1017 +               tmp = value & 0x7FFF;
1018 +               b43_nphy_rf_ctl_override_rev7(dev, 0x1000, tmp, core, off, 0);
1019 +               tmp = value >> 14;
1020 +               b43_nphy_rf_ctl_override_rev7(dev, 0x4000, tmp, core, off, 0);
1021 +               break;
1022 +       }
1023 +}
1024 +
1025  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverride */
1026  static void b43_nphy_rf_ctl_override(struct b43_wldev *dev, u16 field,
1027                                      u16 value, u8 core, bool off)
1028 @@ -264,6 +331,8 @@ static void b43_nphy_rf_ctl_intc_overrid
1029         u16 reg, tmp, tmp2, val;
1030         int core;
1031  
1032 +       /* TODO: What about rev19+? Revs 3+ and 7+ are a bit similar */
1033 +
1034         for (core = 0; core < 2; core++) {
1035                 if ((core_sel == 1 && core != 0) ||
1036                     (core_sel == 2 && core != 1))
1037 @@ -505,6 +574,14 @@ static void b43_nphy_stay_in_carrier_sea
1038         }
1039  }
1040  
1041 +/* http://bcm-v4.sipsolutions.net/PHY/N/Read_Lpf_Bw_Ctl */
1042 +static u16 b43_nphy_read_lpf_ctl(struct b43_wldev *dev, u16 offset)
1043 +{
1044 +       if (!offset)
1045 +               offset = b43_is_40mhz(dev) ? 0x159 : 0x154;
1046 +       return b43_ntab_read(dev, B43_NTAB16(7, offset)) & 0x7;
1047 +}
1048 +
1049  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/AdjustLnaGainTbl */
1050  static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev)
1051  {
1052 @@ -590,44 +667,270 @@ static void b43_nphy_set_rf_sequence(str
1053   * Radio 0x2057
1054   **************************************************/
1055  
1056 -/* http://bcm-v4.sipsolutions.net/PHY/radio2057_rcal */
1057 +static void b43_radio_2057_chantab_upload(struct b43_wldev *dev,
1058 +                                         const struct b43_nphy_chantabent_rev7 *e_r7,
1059 +                                         const struct b43_nphy_chantabent_rev7_2g *e_r7_2g)
1060 +{
1061 +       if (e_r7_2g) {
1062 +               b43_radio_write(dev, R2057_VCOCAL_COUNTVAL0, e_r7_2g->radio_vcocal_countval0);
1063 +               b43_radio_write(dev, R2057_VCOCAL_COUNTVAL1, e_r7_2g->radio_vcocal_countval1);
1064 +               b43_radio_write(dev, R2057_RFPLL_REFMASTER_SPAREXTALSIZE, e_r7_2g->radio_rfpll_refmaster_sparextalsize);
1065 +               b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_R1, e_r7_2g->radio_rfpll_loopfilter_r1);
1066 +               b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C2, e_r7_2g->radio_rfpll_loopfilter_c2);
1067 +               b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C1, e_r7_2g->radio_rfpll_loopfilter_c1);
1068 +               b43_radio_write(dev, R2057_CP_KPD_IDAC, e_r7_2g->radio_cp_kpd_idac);
1069 +               b43_radio_write(dev, R2057_RFPLL_MMD0, e_r7_2g->radio_rfpll_mmd0);
1070 +               b43_radio_write(dev, R2057_RFPLL_MMD1, e_r7_2g->radio_rfpll_mmd1);
1071 +               b43_radio_write(dev, R2057_VCOBUF_TUNE, e_r7_2g->radio_vcobuf_tune);
1072 +               b43_radio_write(dev, R2057_LOGEN_MX2G_TUNE, e_r7_2g->radio_logen_mx2g_tune);
1073 +               b43_radio_write(dev, R2057_LOGEN_INDBUF2G_TUNE, e_r7_2g->radio_logen_indbuf2g_tune);
1074 +               b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE0, e_r7_2g->radio_txmix2g_tune_boost_pu_core0);
1075 +               b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE0, e_r7_2g->radio_pad2g_tune_pus_core0);
1076 +               b43_radio_write(dev, R2057_LNA2G_TUNE_CORE0, e_r7_2g->radio_lna2g_tune_core0);
1077 +               b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE1, e_r7_2g->radio_txmix2g_tune_boost_pu_core1);
1078 +               b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE1, e_r7_2g->radio_pad2g_tune_pus_core1);
1079 +               b43_radio_write(dev, R2057_LNA2G_TUNE_CORE1, e_r7_2g->radio_lna2g_tune_core1);
1080 +
1081 +       } else {
1082 +               b43_radio_write(dev, R2057_VCOCAL_COUNTVAL0, e_r7->radio_vcocal_countval0);
1083 +               b43_radio_write(dev, R2057_VCOCAL_COUNTVAL1, e_r7->radio_vcocal_countval1);
1084 +               b43_radio_write(dev, R2057_RFPLL_REFMASTER_SPAREXTALSIZE, e_r7->radio_rfpll_refmaster_sparextalsize);
1085 +               b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_R1, e_r7->radio_rfpll_loopfilter_r1);
1086 +               b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C2, e_r7->radio_rfpll_loopfilter_c2);
1087 +               b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C1, e_r7->radio_rfpll_loopfilter_c1);
1088 +               b43_radio_write(dev, R2057_CP_KPD_IDAC, e_r7->radio_cp_kpd_idac);
1089 +               b43_radio_write(dev, R2057_RFPLL_MMD0, e_r7->radio_rfpll_mmd0);
1090 +               b43_radio_write(dev, R2057_RFPLL_MMD1, e_r7->radio_rfpll_mmd1);
1091 +               b43_radio_write(dev, R2057_VCOBUF_TUNE, e_r7->radio_vcobuf_tune);
1092 +               b43_radio_write(dev, R2057_LOGEN_MX2G_TUNE, e_r7->radio_logen_mx2g_tune);
1093 +               b43_radio_write(dev, R2057_LOGEN_MX5G_TUNE, e_r7->radio_logen_mx5g_tune);
1094 +               b43_radio_write(dev, R2057_LOGEN_INDBUF2G_TUNE, e_r7->radio_logen_indbuf2g_tune);
1095 +               b43_radio_write(dev, R2057_LOGEN_INDBUF5G_TUNE, e_r7->radio_logen_indbuf5g_tune);
1096 +               b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE0, e_r7->radio_txmix2g_tune_boost_pu_core0);
1097 +               b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE0, e_r7->radio_pad2g_tune_pus_core0);
1098 +               b43_radio_write(dev, R2057_PGA_BOOST_TUNE_CORE0, e_r7->radio_pga_boost_tune_core0);
1099 +               b43_radio_write(dev, R2057_TXMIX5G_BOOST_TUNE_CORE0, e_r7->radio_txmix5g_boost_tune_core0);
1100 +               b43_radio_write(dev, R2057_PAD5G_TUNE_MISC_PUS_CORE0, e_r7->radio_pad5g_tune_misc_pus_core0);
1101 +               b43_radio_write(dev, R2057_LNA2G_TUNE_CORE0, e_r7->radio_lna2g_tune_core0);
1102 +               b43_radio_write(dev, R2057_LNA5G_TUNE_CORE0, e_r7->radio_lna5g_tune_core0);
1103 +               b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE1, e_r7->radio_txmix2g_tune_boost_pu_core1);
1104 +               b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE1, e_r7->radio_pad2g_tune_pus_core1);
1105 +               b43_radio_write(dev, R2057_PGA_BOOST_TUNE_CORE1, e_r7->radio_pga_boost_tune_core1);
1106 +               b43_radio_write(dev, R2057_TXMIX5G_BOOST_TUNE_CORE1, e_r7->radio_txmix5g_boost_tune_core1);
1107 +               b43_radio_write(dev, R2057_PAD5G_TUNE_MISC_PUS_CORE1, e_r7->radio_pad5g_tune_misc_pus_core1);
1108 +               b43_radio_write(dev, R2057_LNA2G_TUNE_CORE1, e_r7->radio_lna2g_tune_core1);
1109 +               b43_radio_write(dev, R2057_LNA5G_TUNE_CORE1, e_r7->radio_lna5g_tune_core1);
1110 +       }
1111 +}
1112 +
1113 +static void b43_radio_2057_setup(struct b43_wldev *dev,
1114 +                                const struct b43_nphy_chantabent_rev7 *tabent_r7,
1115 +                                const struct b43_nphy_chantabent_rev7_2g *tabent_r7_2g)
1116 +{
1117 +       struct b43_phy *phy = &dev->phy;
1118 +
1119 +       b43_radio_2057_chantab_upload(dev, tabent_r7, tabent_r7_2g);
1120 +
1121 +       switch (phy->radio_rev) {
1122 +       case 0 ... 4:
1123 +       case 6:
1124 +               if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
1125 +                       b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_R1, 0x3f);
1126 +                       b43_radio_write(dev, R2057_CP_KPD_IDAC, 0x3f);
1127 +                       b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C1, 0x8);
1128 +                       b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C2, 0x8);
1129 +               } else {
1130 +                       b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_R1, 0x1f);
1131 +                       b43_radio_write(dev, R2057_CP_KPD_IDAC, 0x3f);
1132 +                       b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C1, 0x8);
1133 +                       b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C2, 0x8);
1134 +               }
1135 +               break;
1136 +       case 9: /* e.g. PHY rev 16 */
1137 +               b43_radio_write(dev, R2057_LOGEN_PTAT_RESETS, 0x20);
1138 +               b43_radio_write(dev, R2057_VCOBUF_IDACS, 0x18);
1139 +               if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
1140 +                       b43_radio_write(dev, R2057_LOGEN_PTAT_RESETS, 0x38);
1141 +                       b43_radio_write(dev, R2057_VCOBUF_IDACS, 0x0f);
1142 +
1143 +                       if (b43_is_40mhz(dev)) {
1144 +                               /* TODO */
1145 +                       } else {
1146 +                               b43_radio_write(dev,
1147 +                                               R2057_PAD_BIAS_FILTER_BWS_CORE0,
1148 +                                               0x3c);
1149 +                               b43_radio_write(dev,
1150 +                                               R2057_PAD_BIAS_FILTER_BWS_CORE1,
1151 +                                               0x3c);
1152 +                       }
1153 +               }
1154 +               break;
1155 +       case 14: /* 2 GHz only */
1156 +               b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_R1, 0x1b);
1157 +               b43_radio_write(dev, R2057_CP_KPD_IDAC, 0x3f);
1158 +               b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C1, 0x1f);
1159 +               b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C2, 0x1f);
1160 +               break;
1161 +       }
1162 +
1163 +       if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
1164 +               u16 txmix2g_tune_boost_pu = 0;
1165 +               u16 pad2g_tune_pus = 0;
1166 +
1167 +               if (b43_nphy_ipa(dev)) {
1168 +                       switch (phy->radio_rev) {
1169 +                       case 9:
1170 +                               txmix2g_tune_boost_pu = 0x0041;
1171 +                               /* TODO */
1172 +                               break;
1173 +                       case 14:
1174 +                               txmix2g_tune_boost_pu = 0x21;
1175 +                               pad2g_tune_pus = 0x23;
1176 +                               break;
1177 +                       }
1178 +               }
1179 +
1180 +               if (txmix2g_tune_boost_pu)
1181 +                       b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE0,
1182 +                                       txmix2g_tune_boost_pu);
1183 +               if (pad2g_tune_pus)
1184 +                       b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE0,
1185 +                                       pad2g_tune_pus);
1186 +               if (txmix2g_tune_boost_pu)
1187 +                       b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE1,
1188 +                                       txmix2g_tune_boost_pu);
1189 +               if (pad2g_tune_pus)
1190 +                       b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE1,
1191 +                                       pad2g_tune_pus);
1192 +       }
1193 +
1194 +       usleep_range(50, 100);
1195 +
1196 +       /* VCO calibration */
1197 +       b43_radio_mask(dev, R2057_RFPLL_MISC_EN, ~0x01);
1198 +       b43_radio_mask(dev, R2057_RFPLL_MISC_CAL_RESETN, ~0x04);
1199 +       b43_radio_set(dev, R2057_RFPLL_MISC_CAL_RESETN, 0x4);
1200 +       b43_radio_set(dev, R2057_RFPLL_MISC_EN, 0x01);
1201 +       usleep_range(300, 600);
1202 +}
1203 +
1204 +/* Calibrate resistors in LPF of PLL?
1205 + * http://bcm-v4.sipsolutions.net/PHY/radio205x_rcal
1206 + */
1207  static u8 b43_radio_2057_rcal(struct b43_wldev *dev)
1208  {
1209         struct b43_phy *phy = &dev->phy;
1210 +       u16 saved_regs_phy[12];
1211 +       u16 saved_regs_phy_rf[6];
1212 +       u16 saved_regs_radio[2] = { };
1213 +       static const u16 phy_to_store[] = {
1214 +               B43_NPHY_RFCTL_RSSIO1, B43_NPHY_RFCTL_RSSIO2,
1215 +               B43_NPHY_RFCTL_LUT_TRSW_LO1, B43_NPHY_RFCTL_LUT_TRSW_LO2,
1216 +               B43_NPHY_RFCTL_RXG1, B43_NPHY_RFCTL_RXG2,
1217 +               B43_NPHY_RFCTL_TXG1, B43_NPHY_RFCTL_TXG2,
1218 +               B43_NPHY_REV7_RF_CTL_MISC_REG3, B43_NPHY_REV7_RF_CTL_MISC_REG4,
1219 +               B43_NPHY_REV7_RF_CTL_MISC_REG5, B43_NPHY_REV7_RF_CTL_MISC_REG6,
1220 +       };
1221 +       static const u16 phy_to_store_rf[] = {
1222 +               B43_NPHY_REV3_RFCTL_OVER0, B43_NPHY_REV3_RFCTL_OVER1,
1223 +               B43_NPHY_REV7_RF_CTL_OVER3, B43_NPHY_REV7_RF_CTL_OVER4,
1224 +               B43_NPHY_REV7_RF_CTL_OVER5, B43_NPHY_REV7_RF_CTL_OVER6,
1225 +       };
1226         u16 tmp;
1227 +       int i;
1228  
1229 -       if (phy->radio_rev == 5) {
1230 -               b43_phy_mask(dev, 0x342, ~0x2);
1231 +       /* Save */
1232 +       for (i = 0; i < ARRAY_SIZE(phy_to_store); i++)
1233 +               saved_regs_phy[i] = b43_phy_read(dev, phy_to_store[i]);
1234 +       for (i = 0; i < ARRAY_SIZE(phy_to_store_rf); i++)
1235 +               saved_regs_phy_rf[i] = b43_phy_read(dev, phy_to_store_rf[i]);
1236 +
1237 +       /* Set */
1238 +       for (i = 0; i < ARRAY_SIZE(phy_to_store); i++)
1239 +               b43_phy_write(dev, phy_to_store[i], 0);
1240 +       b43_phy_write(dev, B43_NPHY_REV3_RFCTL_OVER0, 0x07ff);
1241 +       b43_phy_write(dev, B43_NPHY_REV3_RFCTL_OVER1, 0x07ff);
1242 +       b43_phy_write(dev, B43_NPHY_REV7_RF_CTL_OVER3, 0x07ff);
1243 +       b43_phy_write(dev, B43_NPHY_REV7_RF_CTL_OVER4, 0x07ff);
1244 +       b43_phy_write(dev, B43_NPHY_REV7_RF_CTL_OVER5, 0x007f);
1245 +       b43_phy_write(dev, B43_NPHY_REV7_RF_CTL_OVER6, 0x007f);
1246 +
1247 +       switch (phy->radio_rev) {
1248 +       case 5:
1249 +               b43_phy_mask(dev, B43_NPHY_REV7_RF_CTL_OVER3, ~0x2);
1250                 udelay(10);
1251                 b43_radio_set(dev, R2057_IQTEST_SEL_PU, 0x1);
1252 -               b43_radio_maskset(dev, 0x1ca, ~0x2, 0x1);
1253 +               b43_radio_maskset(dev, R2057v7_IQTEST_SEL_PU2, ~0x2, 0x1);
1254 +               break;
1255 +       case 9:
1256 +               b43_phy_set(dev, B43_NPHY_REV7_RF_CTL_OVER3, 0x2);
1257 +               b43_phy_set(dev, B43_NPHY_REV7_RF_CTL_MISC_REG3, 0x2);
1258 +               saved_regs_radio[0] = b43_radio_read(dev, R2057_IQTEST_SEL_PU);
1259 +               b43_radio_write(dev, R2057_IQTEST_SEL_PU, 0x11);
1260 +               break;
1261 +       case 14:
1262 +               saved_regs_radio[0] = b43_radio_read(dev, R2057_IQTEST_SEL_PU);
1263 +               saved_regs_radio[1] = b43_radio_read(dev, R2057v7_IQTEST_SEL_PU2);
1264 +               b43_phy_set(dev, B43_NPHY_REV7_RF_CTL_MISC_REG3, 0x2);
1265 +               b43_phy_set(dev, B43_NPHY_REV7_RF_CTL_OVER3, 0x2);
1266 +               b43_radio_write(dev, R2057v7_IQTEST_SEL_PU2, 0x2);
1267 +               b43_radio_write(dev, R2057_IQTEST_SEL_PU, 0x1);
1268 +               break;
1269         }
1270  
1271 +       /* Enable */
1272         b43_radio_set(dev, R2057_RCAL_CONFIG, 0x1);
1273         udelay(10);
1274 -       b43_radio_set(dev, R2057_RCAL_CONFIG, 0x3);
1275 -       if (!b43_radio_wait_value(dev, R2057_RCCAL_N1_1, 1, 1, 100, 1000000)) {
1276 +
1277 +       /* Start */
1278 +       b43_radio_set(dev, R2057_RCAL_CONFIG, 0x2);
1279 +       usleep_range(100, 200);
1280 +
1281 +       /* Stop */
1282 +       b43_radio_mask(dev, R2057_RCAL_CONFIG, ~0x2);
1283 +
1284 +       /* Wait and check for result */
1285 +       if (!b43_radio_wait_value(dev, R2057_RCAL_STATUS, 1, 1, 100, 1000000)) {
1286                 b43err(dev->wl, "Radio 0x2057 rcal timeout\n");
1287                 return 0;
1288         }
1289 -       b43_radio_mask(dev, R2057_RCAL_CONFIG, ~0x2);
1290         tmp = b43_radio_read(dev, R2057_RCAL_STATUS) & 0x3E;
1291 +
1292 +       /* Disable */
1293         b43_radio_mask(dev, R2057_RCAL_CONFIG, ~0x1);
1294  
1295 -       if (phy->radio_rev == 5) {
1296 -               b43_radio_mask(dev, R2057_IPA2G_CASCONV_CORE0, ~0x1);
1297 -               b43_radio_mask(dev, 0x1ca, ~0x2);
1298 -       }
1299 -       if (phy->radio_rev <= 4 || phy->radio_rev == 6) {
1300 +       /* Restore */
1301 +       for (i = 0; i < ARRAY_SIZE(phy_to_store_rf); i++)
1302 +               b43_phy_write(dev, phy_to_store_rf[i], saved_regs_phy_rf[i]);
1303 +       for (i = 0; i < ARRAY_SIZE(phy_to_store); i++)
1304 +               b43_phy_write(dev, phy_to_store[i], saved_regs_phy[i]);
1305 +
1306 +       switch (phy->radio_rev) {
1307 +       case 0 ... 4:
1308 +       case 6:
1309                 b43_radio_maskset(dev, R2057_TEMPSENSE_CONFIG, ~0x3C, tmp);
1310                 b43_radio_maskset(dev, R2057_BANDGAP_RCAL_TRIM, ~0xF0,
1311                                   tmp << 2);
1312 +               break;
1313 +       case 5:
1314 +               b43_radio_mask(dev, R2057_IPA2G_CASCONV_CORE0, ~0x1);
1315 +               b43_radio_mask(dev, R2057v7_IQTEST_SEL_PU2, ~0x2);
1316 +               break;
1317 +       case 9:
1318 +               b43_radio_write(dev, R2057_IQTEST_SEL_PU, saved_regs_radio[0]);
1319 +               break;
1320 +       case 14:
1321 +               b43_radio_write(dev, R2057_IQTEST_SEL_PU, saved_regs_radio[0]);
1322 +               b43_radio_write(dev, R2057v7_IQTEST_SEL_PU2, saved_regs_radio[1]);
1323 +               break;
1324         }
1325  
1326         return tmp & 0x3e;
1327  }
1328  
1329 -/* http://bcm-v4.sipsolutions.net/PHY/radio2057_rccal */
1330 +/* Calibrate the internal RC oscillator?
1331 + * http://bcm-v4.sipsolutions.net/PHY/radio2057_rccal
1332 + */
1333  static u16 b43_radio_2057_rccal(struct b43_wldev *dev)
1334  {
1335         struct b43_phy *phy = &dev->phy;
1336 @@ -635,49 +938,76 @@ static u16 b43_radio_2057_rccal(struct b
1337                         phy->radio_rev == 6);
1338         u16 tmp;
1339  
1340 +       /* Setup cal */
1341         if (special) {
1342                 b43_radio_write(dev, R2057_RCCAL_MASTER, 0x61);
1343                 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xC0);
1344         } else {
1345 -               b43_radio_write(dev, 0x1AE, 0x61);
1346 -               b43_radio_write(dev, R2057_RCCAL_TRC0, 0xE1);
1347 +               b43_radio_write(dev, R2057v7_RCCAL_MASTER, 0x61);
1348 +               b43_radio_write(dev, R2057_RCCAL_TRC0, 0xE9);
1349         }
1350         b43_radio_write(dev, R2057_RCCAL_X1, 0x6E);
1351 +
1352 +       /* Start, wait, stop */
1353         b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x55);
1354 -       if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 1, 1, 500,
1355 +       if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 2, 2, 500,
1356                                   5000000))
1357                 b43dbg(dev->wl, "Radio 0x2057 rccal timeout\n");
1358 +       usleep_range(35, 70);
1359         b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x15);
1360 +       usleep_range(70, 140);
1361 +
1362 +       /* Setup cal */
1363         if (special) {
1364                 b43_radio_write(dev, R2057_RCCAL_MASTER, 0x69);
1365                 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xB0);
1366         } else {
1367 -               b43_radio_write(dev, 0x1AE, 0x69);
1368 +               b43_radio_write(dev, R2057v7_RCCAL_MASTER, 0x69);
1369                 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xD5);
1370         }
1371         b43_radio_write(dev, R2057_RCCAL_X1, 0x6E);
1372 +
1373 +       /* Start, wait, stop */
1374 +       usleep_range(35, 70);
1375         b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x55);
1376 -       if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 1, 1, 500,
1377 +       usleep_range(70, 140);
1378 +       if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 2, 2, 500,
1379                                   5000000))
1380                 b43dbg(dev->wl, "Radio 0x2057 rccal timeout\n");
1381 +       usleep_range(35, 70);
1382         b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x15);
1383 +       usleep_range(70, 140);
1384 +
1385 +       /* Setup cal */
1386         if (special) {
1387                 b43_radio_write(dev, R2057_RCCAL_MASTER, 0x73);
1388                 b43_radio_write(dev, R2057_RCCAL_X1, 0x28);
1389                 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xB0);
1390         } else {
1391 -               b43_radio_write(dev, 0x1AE, 0x73);
1392 +               b43_radio_write(dev, R2057v7_RCCAL_MASTER, 0x73);
1393                 b43_radio_write(dev, R2057_RCCAL_X1, 0x6E);
1394                 b43_radio_write(dev, R2057_RCCAL_TRC0, 0x99);
1395         }
1396 +
1397 +       /* Start, wait, stop */
1398 +       usleep_range(35, 70);
1399         b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x55);
1400 -       if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 1, 1, 500,
1401 +       usleep_range(70, 140);
1402 +       if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 2, 2, 500,
1403                                   5000000)) {
1404                 b43err(dev->wl, "Radio 0x2057 rcal timeout\n");
1405                 return 0;
1406         }
1407         tmp = b43_radio_read(dev, R2057_RCCAL_DONE_OSCCAP);
1408 +       usleep_range(35, 70);
1409         b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x15);
1410 +       usleep_range(70, 140);
1411 +
1412 +       if (special)
1413 +               b43_radio_mask(dev, R2057_RCCAL_MASTER, ~0x1);
1414 +       else
1415 +               b43_radio_mask(dev, R2057v7_RCCAL_MASTER, ~0x1);
1416 +
1417         return tmp;
1418  }
1419  
1420 @@ -694,19 +1024,20 @@ static void b43_radio_2057_init_post(str
1421  {
1422         b43_radio_set(dev, R2057_XTALPUOVR_PINCTRL, 0x1);
1423  
1424 +       if (0) /* FIXME: Is this BCM43217 specific? */
1425 +               b43_radio_set(dev, R2057_XTALPUOVR_PINCTRL, 0x2);
1426 +
1427         b43_radio_set(dev, R2057_RFPLL_MISC_CAL_RESETN, 0x78);
1428         b43_radio_set(dev, R2057_XTAL_CONFIG2, 0x80);
1429         mdelay(2);
1430         b43_radio_mask(dev, R2057_RFPLL_MISC_CAL_RESETN, ~0x78);
1431         b43_radio_mask(dev, R2057_XTAL_CONFIG2, ~0x80);
1432  
1433 -       if (dev->phy.n->init_por) {
1434 +       if (dev->phy.do_full_init) {
1435                 b43_radio_2057_rcal(dev);
1436                 b43_radio_2057_rccal(dev);
1437         }
1438         b43_radio_mask(dev, R2057_RFPLL_MASTER, ~0x8);
1439 -
1440 -       dev->phy.n->init_por = false;
1441  }
1442  
1443  /* http://bcm-v4.sipsolutions.net/802.11/Radio/2057/Init */
1444 @@ -800,6 +1131,7 @@ static void b43_chantab_radio_2056_uploa
1445  static void b43_radio_2056_setup(struct b43_wldev *dev,
1446                                 const struct b43_nphy_channeltab_entry_rev3 *e)
1447  {
1448 +       struct b43_phy *phy = &dev->phy;
1449         struct ssb_sprom *sprom = dev->dev->bus_sprom;
1450         enum ieee80211_band band = b43_current_band(dev->wl);
1451         u16 offset;
1452 @@ -897,7 +1229,7 @@ static void b43_radio_2056_setup(struct
1453                                         offset | B2056_TX_MIXG_BOOST_TUNE,
1454                                         mixg_boost);
1455                         } else {
1456 -                               bias = dev->phy.is_40mhz ? 0x40 : 0x20;
1457 +                               bias = b43_is_40mhz(dev) ? 0x40 : 0x20;
1458                                 b43_radio_write(dev,
1459                                         offset | B2056_TX_INTPAG_IMAIN_STAT,
1460                                         bias);
1461 @@ -911,7 +1243,7 @@ static void b43_radio_2056_setup(struct
1462                         b43_radio_write(dev, offset | B2056_TX_PA_SPARE1, 0xee);
1463                 }
1464         } else if (dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ) {
1465 -               u16 freq = dev->phy.channel_freq;
1466 +               u16 freq = phy->chandef->chan->center_freq;
1467                 if (freq < 5100) {
1468                         paa_boost = 0xA;
1469                         pada_boost = 0x77;
1470 @@ -1028,7 +1360,7 @@ static void b43_radio_init2056_post(stru
1471         b43_radio_mask(dev, B2056_SYN_COM_RESET, ~0x2);
1472         b43_radio_mask(dev, B2056_SYN_PLL_MAST2, ~0xFC);
1473         b43_radio_mask(dev, B2056_SYN_RCCAL_CTRL0, ~0x1);
1474 -       if (dev->phy.n->init_por)
1475 +       if (dev->phy.do_full_init)
1476                 b43_radio_2056_rcal(dev);
1477  }
1478  
1479 @@ -1041,8 +1373,6 @@ static void b43_radio_init2056(struct b4
1480         b43_radio_init2056_pre(dev);
1481         b2056_upload_inittabs(dev, 0, 0);
1482         b43_radio_init2056_post(dev);
1483 -
1484 -       dev->phy.n->init_por = false;
1485  }
1486  
1487  /**************************************************
1488 @@ -1214,8 +1544,7 @@ static u16 b43_nphy_gen_load_samples(str
1489         u16 bw, len, rot, angle;
1490         struct b43_c32 *samples;
1491  
1492 -
1493 -       bw = (dev->phy.is_40mhz) ? 40 : 20;
1494 +       bw = b43_is_40mhz(dev) ? 40 : 20;
1495         len = bw << 3;
1496  
1497         if (test) {
1498 @@ -1224,7 +1553,7 @@ static u16 b43_nphy_gen_load_samples(str
1499                 else
1500                         bw = 80;
1501  
1502 -               if (dev->phy.is_40mhz)
1503 +               if (b43_is_40mhz(dev))
1504                         bw <<= 1;
1505  
1506                 len = bw << 1;
1507 @@ -1252,8 +1581,10 @@ static u16 b43_nphy_gen_load_samples(str
1508  
1509  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RunSamples */
1510  static void b43_nphy_run_samples(struct b43_wldev *dev, u16 samps, u16 loops,
1511 -                                       u16 wait, bool iqmode, bool dac_test)
1512 +                                u16 wait, bool iqmode, bool dac_test,
1513 +                                bool modify_bbmult)
1514  {
1515 +       struct b43_phy *phy = &dev->phy;
1516         struct b43_phy_n *nphy = dev->phy.n;
1517         int i;
1518         u16 seq_mode;
1519 @@ -1261,17 +1592,35 @@ static void b43_nphy_run_samples(struct
1520  
1521         b43_nphy_stay_in_carrier_search(dev, true);
1522  
1523 +       if (phy->rev >= 7) {
1524 +               bool lpf_bw3, lpf_bw4;
1525 +
1526 +               lpf_bw3 = b43_phy_read(dev, B43_NPHY_REV7_RF_CTL_OVER3) & 0x80;
1527 +               lpf_bw4 = b43_phy_read(dev, B43_NPHY_REV7_RF_CTL_OVER3) & 0x80;
1528 +
1529 +               if (lpf_bw3 || lpf_bw4) {
1530 +                       /* TODO */
1531 +               } else {
1532 +                       u16 value = b43_nphy_read_lpf_ctl(dev, 0);
1533 +                       if (phy->rev >= 19)
1534 +                               b43_nphy_rf_ctl_override_rev19(dev, 0x80, value,
1535 +                                                              0, false, 1);
1536 +                       else
1537 +                               b43_nphy_rf_ctl_override_rev7(dev, 0x80, value,
1538 +                                                             0, false, 1);
1539 +                       nphy->lpf_bw_overrode_for_sample_play = true;
1540 +               }
1541 +       }
1542 +
1543         if ((nphy->bb_mult_save & 0x80000000) == 0) {
1544                 tmp = b43_ntab_read(dev, B43_NTAB16(15, 87));
1545                 nphy->bb_mult_save = (tmp & 0xFFFF) | 0x80000000;
1546         }
1547  
1548 -       /* TODO: add modify_bbmult argument */
1549 -       if (!dev->phy.is_40mhz)
1550 -               tmp = 0x6464;
1551 -       else
1552 -               tmp = 0x4747;
1553 -       b43_ntab_write(dev, B43_NTAB16(15, 87), tmp);
1554 +       if (modify_bbmult) {
1555 +               tmp = !b43_is_40mhz(dev) ? 0x6464 : 0x4747;
1556 +               b43_ntab_write(dev, B43_NTAB16(15, 87), tmp);
1557 +       }
1558  
1559         b43_phy_write(dev, B43_NPHY_SAMP_DEPCNT, (samps - 1));
1560  
1561 @@ -1289,10 +1638,8 @@ static void b43_nphy_run_samples(struct
1562                 b43_phy_mask(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x7FFF);
1563                 b43_phy_set(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8000);
1564         } else {
1565 -               if (dac_test)
1566 -                       b43_phy_write(dev, B43_NPHY_SAMP_CMD, 5);
1567 -               else
1568 -                       b43_phy_write(dev, B43_NPHY_SAMP_CMD, 1);
1569 +               tmp = dac_test ? 5 : 1;
1570 +               b43_phy_write(dev, B43_NPHY_SAMP_CMD, tmp);
1571         }
1572         for (i = 0; i < 100; i++) {
1573                 if (!(b43_phy_read(dev, B43_NPHY_RFSEQST) & 1)) {
1574 @@ -1392,6 +1739,12 @@ static void b43_nphy_scale_offset_rssi(s
1575         }
1576  }
1577  
1578 +static void b43_nphy_rssi_select_rev19(struct b43_wldev *dev, u8 code,
1579 +                                      enum n_rssi_type rssi_type)
1580 +{
1581 +       /* TODO */
1582 +}
1583 +
1584  static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code,
1585                                       enum n_rssi_type rssi_type)
1586  {
1587 @@ -1461,13 +1814,15 @@ static void b43_nphy_rev3_rssi_select(st
1588                                         enum ieee80211_band band =
1589                                                 b43_current_band(dev->wl);
1590  
1591 -                                       if (b43_nphy_ipa(dev))
1592 -                                               val = (band == IEEE80211_BAND_5GHZ) ? 0xC : 0xE;
1593 -                                       else
1594 -                                               val = 0x11;
1595 -                                       reg = (i == 0) ? 0x2000 : 0x3000;
1596 -                                       reg |= B2055_PADDRV;
1597 -                                       b43_radio_write(dev, reg, val);
1598 +                                       if (dev->phy.rev < 7) {
1599 +                                               if (b43_nphy_ipa(dev))
1600 +                                                       val = (band == IEEE80211_BAND_5GHZ) ? 0xC : 0xE;
1601 +                                               else
1602 +                                                       val = 0x11;
1603 +                                               reg = (i == 0) ? B2056_TX0 : B2056_TX1;
1604 +                                               reg |= B2056_TX_TX_SSI_MUX;
1605 +                                               b43_radio_write(dev, reg, val);
1606 +                                       }
1607  
1608                                         reg = (i == 0) ?
1609                                                 B43_NPHY_AFECTL_OVER1 :
1610 @@ -1554,7 +1909,9 @@ static void b43_nphy_rev2_rssi_select(st
1611  static void b43_nphy_rssi_select(struct b43_wldev *dev, u8 code,
1612                                  enum n_rssi_type type)
1613  {
1614 -       if (dev->phy.rev >= 3)
1615 +       if (dev->phy.rev >= 19)
1616 +               b43_nphy_rssi_select_rev19(dev, code, type);
1617 +       else if (dev->phy.rev >= 3)
1618                 b43_nphy_rev3_rssi_select(dev, code, type);
1619         else
1620                 b43_nphy_rev2_rssi_select(dev, code, type);
1621 @@ -1598,6 +1955,8 @@ static int b43_nphy_poll_rssi(struct b43
1622         u16 save_regs_phy[9];
1623         u16 s[2];
1624  
1625 +       /* TODO: rev7+ is treated like rev3+, what about rev19+? */
1626 +
1627         if (dev->phy.rev >= 3) {
1628                 save_regs_phy[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
1629                 save_regs_phy[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
1630 @@ -1679,6 +2038,7 @@ static int b43_nphy_poll_rssi(struct b43
1631  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */
1632  static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
1633  {
1634 +       struct b43_phy *phy = &dev->phy;
1635         struct b43_phy_n *nphy = dev->phy.n;
1636  
1637         u16 saved_regs_phy_rfctl[2];
1638 @@ -1696,12 +2056,14 @@ static void b43_nphy_rev3_rssi_cal(struc
1639                 B43_NPHY_AFECTL_OVER1, B43_NPHY_AFECTL_OVER,
1640                 B43_NPHY_AFECTL_C1, B43_NPHY_AFECTL_C2,
1641                 B43_NPHY_TXF_40CO_B1S1, B43_NPHY_RFCTL_OVER,
1642 -               0x342, 0x343, 0x346, 0x347,
1643 +               B43_NPHY_REV7_RF_CTL_OVER3, B43_NPHY_REV7_RF_CTL_OVER4,
1644 +               B43_NPHY_REV7_RF_CTL_OVER5, B43_NPHY_REV7_RF_CTL_OVER6,
1645                 0x2ff,
1646                 B43_NPHY_TXF_40CO_B1S0, B43_NPHY_TXF_40CO_B32S1,
1647                 B43_NPHY_RFCTL_CMD,
1648                 B43_NPHY_RFCTL_LUT_TRSW_UP1, B43_NPHY_RFCTL_LUT_TRSW_UP2,
1649 -               0x340, 0x341, 0x344, 0x345,
1650 +               B43_NPHY_REV7_RF_CTL_MISC_REG3, B43_NPHY_REV7_RF_CTL_MISC_REG4,
1651 +               B43_NPHY_REV7_RF_CTL_MISC_REG5, B43_NPHY_REV7_RF_CTL_MISC_REG6,
1652                 B43_NPHY_RFCTL_RSSIO1, B43_NPHY_RFCTL_RSSIO2
1653         };
1654         u16 *regs_to_store;
1655 @@ -1748,9 +2110,24 @@ static void b43_nphy_rev3_rssi_cal(struc
1656         b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_TRSW, 1, 7);
1657  
1658         if (dev->phy.rev >= 7) {
1659 -               /* TODO */
1660 +               b43_nphy_rf_ctl_override_one_to_many(dev,
1661 +                                                    N_RF_CTL_OVER_CMD_RXRF_PU,
1662 +                                                    0, 0, false);
1663 +               b43_nphy_rf_ctl_override_one_to_many(dev,
1664 +                                                    N_RF_CTL_OVER_CMD_RX_PU,
1665 +                                                    1, 0, false);
1666 +               b43_nphy_rf_ctl_override_rev7(dev, 0x80, 1, 0, false, 0);
1667 +               b43_nphy_rf_ctl_override_rev7(dev, 0x80, 1, 0, false, 0);
1668                 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
1669 +                       b43_nphy_rf_ctl_override_rev7(dev, 0x20, 0, 0, false,
1670 +                                                     0);
1671 +                       b43_nphy_rf_ctl_override_rev7(dev, 0x10, 1, 0, false,
1672 +                                                     0);
1673                 } else {
1674 +                       b43_nphy_rf_ctl_override_rev7(dev, 0x10, 0, 0, false,
1675 +                                                     0);
1676 +                       b43_nphy_rf_ctl_override_rev7(dev, 0x20, 1, 0, false,
1677 +                                                     0);
1678                 }
1679         } else {
1680                 b43_nphy_rf_ctl_override(dev, 0x1, 0, 0, false);
1681 @@ -1779,7 +2156,10 @@ static void b43_nphy_rev3_rssi_cal(struc
1682                 /* Grab RSSI results for every possible VCM */
1683                 for (vcm = 0; vcm < 8; vcm++) {
1684                         if (dev->phy.rev >= 7)
1685 -                               ;
1686 +                               b43_radio_maskset(dev,
1687 +                                                 core ? R2057_NB_MASTER_CORE1 :
1688 +                                                        R2057_NB_MASTER_CORE0,
1689 +                                                 ~R2057_VCM_MASK, vcm);
1690                         else
1691                                 b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC,
1692                                                   0xE3, vcm << 2);
1693 @@ -1810,7 +2190,10 @@ static void b43_nphy_rev3_rssi_cal(struc
1694  
1695                 /* Select the best VCM */
1696                 if (dev->phy.rev >= 7)
1697 -                       ;
1698 +                       b43_radio_maskset(dev,
1699 +                                         core ? R2057_NB_MASTER_CORE1 :
1700 +                                                R2057_NB_MASTER_CORE0,
1701 +                                         ~R2057_VCM_MASK, vcm);
1702                 else
1703                         b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC,
1704                                           0xE3, vcm_final << 2);
1705 @@ -1880,6 +2263,10 @@ static void b43_nphy_rev3_rssi_cal(struc
1706                 rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G;
1707         }
1708         if (dev->phy.rev >= 7) {
1709 +               rssical_radio_regs[0] = b43_radio_read(dev,
1710 +                                                      R2057_NB_MASTER_CORE0);
1711 +               rssical_radio_regs[1] = b43_radio_read(dev,
1712 +                                                      R2057_NB_MASTER_CORE1);
1713         } else {
1714                 rssical_radio_regs[0] = b43_radio_read(dev, B2056_RX0 |
1715                                                        B2056_RX_RSSI_MISC);
1716 @@ -1901,9 +2288,9 @@ static void b43_nphy_rev3_rssi_cal(struc
1717  
1718         /* Remember for which channel we store configuration */
1719         if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
1720 -               nphy->rssical_chanspec_2G.center_freq = dev->phy.channel_freq;
1721 +               nphy->rssical_chanspec_2G.center_freq = phy->chandef->chan->center_freq;
1722         else
1723 -               nphy->rssical_chanspec_5G.center_freq = dev->phy.channel_freq;
1724 +               nphy->rssical_chanspec_5G.center_freq = phy->chandef->chan->center_freq;
1725  
1726         /* End of calibration, restore configuration */
1727         b43_nphy_classifier(dev, 7, class);
1728 @@ -2080,7 +2467,9 @@ static void b43_nphy_rev2_rssi_cal(struc
1729   */
1730  static void b43_nphy_rssi_cal(struct b43_wldev *dev)
1731  {
1732 -       if (dev->phy.rev >= 3) {
1733 +       if (dev->phy.rev >= 19) {
1734 +               /* TODO */
1735 +       } else if (dev->phy.rev >= 3) {
1736                 b43_nphy_rev3_rssi_cal(dev);
1737         } else {
1738                 b43_nphy_rev2_rssi_cal(dev, N_RSSI_NB);
1739 @@ -2093,7 +2482,21 @@ static void b43_nphy_rssi_cal(struct b43
1740   * Workarounds
1741   **************************************************/
1742  
1743 -static void b43_nphy_gain_ctl_workarounds_rev3plus(struct b43_wldev *dev)
1744 +static void b43_nphy_gain_ctl_workarounds_rev19(struct b43_wldev *dev)
1745 +{
1746 +       /* TODO */
1747 +}
1748 +
1749 +static void b43_nphy_gain_ctl_workarounds_rev7(struct b43_wldev *dev)
1750 +{
1751 +       struct b43_phy *phy = &dev->phy;
1752 +
1753 +       switch (phy->rev) {
1754 +       /* TODO */
1755 +       }
1756 +}
1757 +
1758 +static void b43_nphy_gain_ctl_workarounds_rev3(struct b43_wldev *dev)
1759  {
1760         struct ssb_sprom *sprom = dev->dev->bus_sprom;
1761  
1762 @@ -2196,7 +2599,7 @@ static void b43_nphy_gain_ctl_workaround
1763         b43_phy_write(dev, B43_NPHY_C1_NBCLIPTHRES, 0x84);
1764         b43_phy_write(dev, B43_NPHY_C2_NBCLIPTHRES, 0x84);
1765  
1766 -       if (!dev->phy.is_40mhz) {
1767 +       if (!b43_is_40mhz(dev)) {
1768                 /* Set dwell lengths */
1769                 b43_phy_write(dev, B43_NPHY_CLIP1_NBDWELL_LEN, 0x002B);
1770                 b43_phy_write(dev, B43_NPHY_CLIP2_NBDWELL_LEN, 0x002B);
1771 @@ -2210,7 +2613,7 @@ static void b43_nphy_gain_ctl_workaround
1772         b43_phy_maskset(dev, B43_NPHY_C2_CLIPWBTHRES,
1773                         ~B43_NPHY_C2_CLIPWBTHRES_CLIP2, 21);
1774  
1775 -       if (!dev->phy.is_40mhz) {
1776 +       if (!b43_is_40mhz(dev)) {
1777                 b43_phy_maskset(dev, B43_NPHY_C1_CGAINI,
1778                         ~B43_NPHY_C1_CGAINI_GAINBKOFF, 0x1);
1779                 b43_phy_maskset(dev, B43_NPHY_C2_CGAINI,
1780 @@ -2225,12 +2628,12 @@ static void b43_nphy_gain_ctl_workaround
1781  
1782         if (nphy->gain_boost) {
1783                 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ &&
1784 -                       dev->phy.is_40mhz)
1785 +                   b43_is_40mhz(dev))
1786                         code = 4;
1787                 else
1788                         code = 5;
1789         } else {
1790 -               code = dev->phy.is_40mhz ? 6 : 7;
1791 +               code = b43_is_40mhz(dev) ? 6 : 7;
1792         }
1793  
1794         /* Set HPVGA2 index */
1795 @@ -2290,46 +2693,54 @@ static void b43_nphy_gain_ctl_workaround
1796  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */
1797  static void b43_nphy_gain_ctl_workarounds(struct b43_wldev *dev)
1798  {
1799 -       if (dev->phy.rev >= 7)
1800 -               ; /* TODO */
1801 +       if (dev->phy.rev >= 19)
1802 +               b43_nphy_gain_ctl_workarounds_rev19(dev);
1803 +       else if (dev->phy.rev >= 7)
1804 +               b43_nphy_gain_ctl_workarounds_rev7(dev);
1805         else if (dev->phy.rev >= 3)
1806 -               b43_nphy_gain_ctl_workarounds_rev3plus(dev);
1807 +               b43_nphy_gain_ctl_workarounds_rev3(dev);
1808         else
1809                 b43_nphy_gain_ctl_workarounds_rev1_2(dev);
1810  }
1811  
1812 -/* http://bcm-v4.sipsolutions.net/PHY/N/Read_Lpf_Bw_Ctl */
1813 -static u16 b43_nphy_read_lpf_ctl(struct b43_wldev *dev, u16 offset)
1814 -{
1815 -       if (!offset)
1816 -               offset = (dev->phy.is_40mhz) ? 0x159 : 0x154;
1817 -       return b43_ntab_read(dev, B43_NTAB16(7, offset)) & 0x7;
1818 -}
1819 -
1820  static void b43_nphy_workarounds_rev7plus(struct b43_wldev *dev)
1821  {
1822         struct ssb_sprom *sprom = dev->dev->bus_sprom;
1823         struct b43_phy *phy = &dev->phy;
1824  
1825 +       /* TX to RX */
1826 +       u8 tx2rx_events[7] = { 4, 3, 5, 2, 1, 8, 31, };
1827 +       u8 tx2rx_delays[7] = { 8, 4, 4, 4, 4, 6, 1, };
1828 +       /* RX to TX */
1829         u8 rx2tx_events_ipa[9] = { 0x0, 0x1, 0x2, 0x8, 0x5, 0x6, 0xF, 0x3,
1830                                         0x1F };
1831         u8 rx2tx_delays_ipa[9] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 };
1832  
1833 -       u16 ntab7_15e_16e[] = { 0x10f, 0x10f };
1834 +       static const u16 ntab7_15e_16e[] = { 0, 0x10f, 0x10f };
1835         u8 ntab7_138_146[] = { 0x11, 0x11 };
1836         u8 ntab7_133[] = { 0x77, 0x11, 0x11 };
1837  
1838 -       u16 lpf_20, lpf_40, lpf_11b;
1839 -       u16 bcap_val, bcap_val_11b, bcap_val_11n_20, bcap_val_11n_40;
1840 -       u16 scap_val, scap_val_11b, scap_val_11n_20, scap_val_11n_40;
1841 +       u16 lpf_ofdm_20mhz[2], lpf_ofdm_40mhz[2], lpf_11b[2];
1842 +       u16 bcap_val;
1843 +       s16 bcap_val_11b[2], bcap_val_11n_20[2], bcap_val_11n_40[2];
1844 +       u16 scap_val;
1845 +       s16 scap_val_11b[2], scap_val_11n_20[2], scap_val_11n_40[2];
1846         bool rccal_ovrd = false;
1847  
1848 -       u16 rx2tx_lut_20_11b, rx2tx_lut_20_11n, rx2tx_lut_40_11n;
1849         u16 bias, conv, filt;
1850  
1851 +       u32 noise_tbl[2];
1852 +
1853         u32 tmp32;
1854         u8 core;
1855  
1856 +       b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x0125);
1857 +       b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x01b3);
1858 +       b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x0105);
1859 +       b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x016e);
1860 +       b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0x00cd);
1861 +       b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x0020);
1862 +
1863         if (phy->rev == 7) {
1864                 b43_phy_set(dev, B43_NPHY_FINERX2_CGC, 0x10);
1865                 b43_phy_maskset(dev, B43_NPHY_FREQGAIN0, 0xFF80, 0x0020);
1866 @@ -2349,11 +2760,18 @@ static void b43_nphy_workarounds_rev7plu
1867                 b43_phy_maskset(dev, B43_NPHY_FREQGAIN7, 0xFF80, 0x0040);
1868                 b43_phy_maskset(dev, B43_NPHY_FREQGAIN7, 0x80FF, 0x4000);
1869         }
1870 -       if (phy->rev <= 8) {
1871 +
1872 +       if (phy->rev >= 16) {
1873 +               b43_phy_write(dev, B43_NPHY_FORCEFRONT0, 0x7ff);
1874 +               b43_phy_write(dev, B43_NPHY_FORCEFRONT1, 0x7ff);
1875 +       } else if (phy->rev <= 8) {
1876                 b43_phy_write(dev, B43_NPHY_FORCEFRONT0, 0x1B0);
1877                 b43_phy_write(dev, B43_NPHY_FORCEFRONT1, 0x1B0);
1878         }
1879 -       if (phy->rev >= 8)
1880 +
1881 +       if (phy->rev >= 16)
1882 +               b43_phy_maskset(dev, B43_NPHY_TXTAILCNT, ~0xFF, 0xa0);
1883 +       else if (phy->rev >= 8)
1884                 b43_phy_maskset(dev, B43_NPHY_TXTAILCNT, ~0xFF, 0x72);
1885  
1886         b43_ntab_write(dev, B43_NTAB16(8, 0x00), 2);
1887 @@ -2361,9 +2779,11 @@ static void b43_nphy_workarounds_rev7plu
1888         tmp32 = b43_ntab_read(dev, B43_NTAB32(30, 0));
1889         tmp32 &= 0xffffff;
1890         b43_ntab_write(dev, B43_NTAB32(30, 0), tmp32);
1891 -       b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x15e), 2, ntab7_15e_16e);
1892 -       b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x16e), 2, ntab7_15e_16e);
1893 +       b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x15d), 3, ntab7_15e_16e);
1894 +       b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x16d), 3, ntab7_15e_16e);
1895  
1896 +       b43_nphy_set_rf_sequence(dev, 1, tx2rx_events, tx2rx_delays,
1897 +                                ARRAY_SIZE(tx2rx_events));
1898         if (b43_nphy_ipa(dev))
1899                 b43_nphy_set_rf_sequence(dev, 0, rx2tx_events_ipa,
1900                                 rx2tx_delays_ipa, ARRAY_SIZE(rx2tx_events_ipa));
1901 @@ -2371,84 +2791,176 @@ static void b43_nphy_workarounds_rev7plu
1902         b43_phy_maskset(dev, B43_NPHY_EPS_OVERRIDEI_0, 0x3FFF, 0x4000);
1903         b43_phy_maskset(dev, B43_NPHY_EPS_OVERRIDEI_1, 0x3FFF, 0x4000);
1904  
1905 -       lpf_20 = b43_nphy_read_lpf_ctl(dev, 0x154);
1906 -       lpf_40 = b43_nphy_read_lpf_ctl(dev, 0x159);
1907 -       lpf_11b = b43_nphy_read_lpf_ctl(dev, 0x152);
1908 +       for (core = 0; core < 2; core++) {
1909 +               lpf_ofdm_20mhz[core] = b43_nphy_read_lpf_ctl(dev, 0x154 + core * 0x10);
1910 +               lpf_ofdm_40mhz[core] = b43_nphy_read_lpf_ctl(dev, 0x159 + core * 0x10);
1911 +               lpf_11b[core] = b43_nphy_read_lpf_ctl(dev, 0x152 + core * 0x10);
1912 +       }
1913 +
1914 +       bcap_val = b43_radio_read(dev, R2057_RCCAL_BCAP_VAL);
1915 +       scap_val = b43_radio_read(dev, R2057_RCCAL_SCAP_VAL);
1916 +
1917         if (b43_nphy_ipa(dev)) {
1918 -               if ((phy->radio_rev == 5 && phy->is_40mhz) ||
1919 -                   phy->radio_rev == 7 || phy->radio_rev == 8) {
1920 -                       bcap_val = b43_radio_read(dev, 0x16b);
1921 -                       scap_val = b43_radio_read(dev, 0x16a);
1922 -                       scap_val_11b = scap_val;
1923 -                       bcap_val_11b = bcap_val;
1924 -                       if (phy->radio_rev == 5 && phy->is_40mhz) {
1925 -                               scap_val_11n_20 = scap_val;
1926 -                               bcap_val_11n_20 = bcap_val;
1927 -                               scap_val_11n_40 = bcap_val_11n_40 = 0xc;
1928 +               bool ghz2 = b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ;
1929 +
1930 +               switch (phy->radio_rev) {
1931 +               case 5:
1932 +                       /* Check radio version (to be 0) by PHY rev for now */
1933 +                       if (phy->rev == 8 && b43_is_40mhz(dev)) {
1934 +                               for (core = 0; core < 2; core++) {
1935 +                                       scap_val_11b[core] = scap_val;
1936 +                                       bcap_val_11b[core] = bcap_val;
1937 +                                       scap_val_11n_20[core] = scap_val;
1938 +                                       bcap_val_11n_20[core] = bcap_val;
1939 +                                       scap_val_11n_40[core] = 0xc;
1940 +                                       bcap_val_11n_40[core] = 0xc;
1941 +                               }
1942 +
1943                                 rccal_ovrd = true;
1944 -                       } else { /* Rev 7/8 */
1945 -                               lpf_20 = 4;
1946 -                               lpf_11b = 1;
1947 +                       }
1948 +                       if (phy->rev == 9) {
1949 +                               /* TODO: Radio version 1 (e.g. BCM5357B0) */
1950 +                       }
1951 +                       break;
1952 +               case 7:
1953 +               case 8:
1954 +                       for (core = 0; core < 2; core++) {
1955 +                               scap_val_11b[core] = scap_val;
1956 +                               bcap_val_11b[core] = bcap_val;
1957 +                               lpf_ofdm_20mhz[core] = 4;
1958 +                               lpf_11b[core] = 1;
1959                                 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
1960 -                                       scap_val_11n_20 = 0xc;
1961 -                                       bcap_val_11n_20 = 0xc;
1962 -                                       scap_val_11n_40 = 0xa;
1963 -                                       bcap_val_11n_40 = 0xa;
1964 +                                       scap_val_11n_20[core] = 0xc;
1965 +                                       bcap_val_11n_20[core] = 0xc;
1966 +                                       scap_val_11n_40[core] = 0xa;
1967 +                                       bcap_val_11n_40[core] = 0xa;
1968                                 } else {
1969 -                                       scap_val_11n_20 = 0x14;
1970 -                                       bcap_val_11n_20 = 0x14;
1971 -                                       scap_val_11n_40 = 0xf;
1972 -                                       bcap_val_11n_40 = 0xf;
1973 +                                       scap_val_11n_20[core] = 0x14;
1974 +                                       bcap_val_11n_20[core] = 0x14;
1975 +                                       scap_val_11n_40[core] = 0xf;
1976 +                                       bcap_val_11n_40[core] = 0xf;
1977                                 }
1978 -                               rccal_ovrd = true;
1979                         }
1980 +
1981 +                       rccal_ovrd = true;
1982 +                       break;
1983 +               case 9:
1984 +                       for (core = 0; core < 2; core++) {
1985 +                               bcap_val_11b[core] = bcap_val;
1986 +                               scap_val_11b[core] = scap_val;
1987 +                               lpf_11b[core] = 1;
1988 +
1989 +                               if (ghz2) {
1990 +                                       bcap_val_11n_20[core] = bcap_val + 13;
1991 +                                       scap_val_11n_20[core] = scap_val + 15;
1992 +                               } else {
1993 +                                       bcap_val_11n_20[core] = bcap_val + 14;
1994 +                                       scap_val_11n_20[core] = scap_val + 15;
1995 +                               }
1996 +                               lpf_ofdm_20mhz[core] = 4;
1997 +
1998 +                               if (ghz2) {
1999 +                                       bcap_val_11n_40[core] = bcap_val - 7;
2000 +                                       scap_val_11n_40[core] = scap_val - 5;
2001 +                               } else {
2002 +                                       bcap_val_11n_40[core] = bcap_val + 2;
2003 +                                       scap_val_11n_40[core] = scap_val + 4;
2004 +                               }
2005 +                               lpf_ofdm_40mhz[core] = 4;
2006 +                       }
2007 +
2008 +                       rccal_ovrd = true;
2009 +                       break;
2010 +               case 14:
2011 +                       for (core = 0; core < 2; core++) {
2012 +                               bcap_val_11b[core] = bcap_val;
2013 +                               scap_val_11b[core] = scap_val;
2014 +                               lpf_11b[core] = 1;
2015 +                       }
2016 +
2017 +                       bcap_val_11n_20[0] = bcap_val + 20;
2018 +                       scap_val_11n_20[0] = scap_val + 20;
2019 +                       lpf_ofdm_20mhz[0] = 3;
2020 +
2021 +                       bcap_val_11n_20[1] = bcap_val + 16;
2022 +                       scap_val_11n_20[1] = scap_val + 16;
2023 +                       lpf_ofdm_20mhz[1] = 3;
2024 +
2025 +                       bcap_val_11n_40[0] = bcap_val + 20;
2026 +                       scap_val_11n_40[0] = scap_val + 20;
2027 +                       lpf_ofdm_40mhz[0] = 4;
2028 +
2029 +                       bcap_val_11n_40[1] = bcap_val + 10;
2030 +                       scap_val_11n_40[1] = scap_val + 10;
2031 +                       lpf_ofdm_40mhz[1] = 4;
2032 +
2033 +                       rccal_ovrd = true;
2034 +                       break;
2035                 }
2036         } else {
2037                 if (phy->radio_rev == 5) {
2038 -                       lpf_20 = 1;
2039 -                       lpf_40 = 3;
2040 -                       bcap_val = b43_radio_read(dev, 0x16b);
2041 -                       scap_val = b43_radio_read(dev, 0x16a);
2042 -                       scap_val_11b = scap_val;
2043 -                       bcap_val_11b = bcap_val;
2044 -                       scap_val_11n_20 = 0x11;
2045 -                       scap_val_11n_40 = 0x11;
2046 -                       bcap_val_11n_20 = 0x13;
2047 -                       bcap_val_11n_40 = 0x13;
2048 +                       for (core = 0; core < 2; core++) {
2049 +                               lpf_ofdm_20mhz[core] = 1;
2050 +                               lpf_ofdm_40mhz[core] = 3;
2051 +                               scap_val_11b[core] = scap_val;
2052 +                               bcap_val_11b[core] = bcap_val;
2053 +                               scap_val_11n_20[core] = 0x11;
2054 +                               scap_val_11n_40[core] = 0x11;
2055 +                               bcap_val_11n_20[core] = 0x13;
2056 +                               bcap_val_11n_40[core] = 0x13;
2057 +                       }
2058 +
2059                         rccal_ovrd = true;
2060                 }
2061         }
2062         if (rccal_ovrd) {
2063 -               rx2tx_lut_20_11b = (bcap_val_11b << 8) |
2064 -                                  (scap_val_11b << 3) |
2065 -                                  lpf_11b;
2066 -               rx2tx_lut_20_11n = (bcap_val_11n_20 << 8) |
2067 -                                  (scap_val_11n_20 << 3) |
2068 -                                  lpf_20;
2069 -               rx2tx_lut_40_11n = (bcap_val_11n_40 << 8) |
2070 -                                  (scap_val_11n_40 << 3) |
2071 -                                  lpf_40;
2072 +               u16 rx2tx_lut_20_11b[2], rx2tx_lut_20_11n[2], rx2tx_lut_40_11n[2];
2073 +               u8 rx2tx_lut_extra = 1;
2074 +
2075 +               for (core = 0; core < 2; core++) {
2076 +                       bcap_val_11b[core] = clamp_val(bcap_val_11b[core], 0, 0x1f);
2077 +                       scap_val_11b[core] = clamp_val(scap_val_11b[core], 0, 0x1f);
2078 +                       bcap_val_11n_20[core] = clamp_val(bcap_val_11n_20[core], 0, 0x1f);
2079 +                       scap_val_11n_20[core] = clamp_val(scap_val_11n_20[core], 0, 0x1f);
2080 +                       bcap_val_11n_40[core] = clamp_val(bcap_val_11n_40[core], 0, 0x1f);
2081 +                       scap_val_11n_40[core] = clamp_val(scap_val_11n_40[core], 0, 0x1f);
2082 +
2083 +                       rx2tx_lut_20_11b[core] = (rx2tx_lut_extra << 13) |
2084 +                                                (bcap_val_11b[core] << 8) |
2085 +                                                (scap_val_11b[core] << 3) |
2086 +                                                lpf_11b[core];
2087 +                       rx2tx_lut_20_11n[core] = (rx2tx_lut_extra << 13) |
2088 +                                                (bcap_val_11n_20[core] << 8) |
2089 +                                                (scap_val_11n_20[core] << 3) |
2090 +                                                lpf_ofdm_20mhz[core];
2091 +                       rx2tx_lut_40_11n[core] = (rx2tx_lut_extra << 13) |
2092 +                                                (bcap_val_11n_40[core] << 8) |
2093 +                                                (scap_val_11n_40[core] << 3) |
2094 +                                                lpf_ofdm_40mhz[core];
2095 +               }
2096 +
2097                 for (core = 0; core < 2; core++) {
2098                         b43_ntab_write(dev, B43_NTAB16(7, 0x152 + core * 16),
2099 -                                      rx2tx_lut_20_11b);
2100 +                                      rx2tx_lut_20_11b[core]);
2101                         b43_ntab_write(dev, B43_NTAB16(7, 0x153 + core * 16),
2102 -                                      rx2tx_lut_20_11n);
2103 +                                      rx2tx_lut_20_11n[core]);
2104                         b43_ntab_write(dev, B43_NTAB16(7, 0x154 + core * 16),
2105 -                                      rx2tx_lut_20_11n);
2106 +                                      rx2tx_lut_20_11n[core]);
2107                         b43_ntab_write(dev, B43_NTAB16(7, 0x155 + core * 16),
2108 -                                      rx2tx_lut_40_11n);
2109 +                                      rx2tx_lut_40_11n[core]);
2110                         b43_ntab_write(dev, B43_NTAB16(7, 0x156 + core * 16),
2111 -                                      rx2tx_lut_40_11n);
2112 +                                      rx2tx_lut_40_11n[core]);
2113                         b43_ntab_write(dev, B43_NTAB16(7, 0x157 + core * 16),
2114 -                                      rx2tx_lut_40_11n);
2115 +                                      rx2tx_lut_40_11n[core]);
2116                         b43_ntab_write(dev, B43_NTAB16(7, 0x158 + core * 16),
2117 -                                      rx2tx_lut_40_11n);
2118 +                                      rx2tx_lut_40_11n[core]);
2119                         b43_ntab_write(dev, B43_NTAB16(7, 0x159 + core * 16),
2120 -                                      rx2tx_lut_40_11n);
2121 +                                      rx2tx_lut_40_11n[core]);
2122                 }
2123 -               b43_nphy_rf_ctl_override_rev7(dev, 16, 1, 3, false, 2);
2124         }
2125 +
2126         b43_phy_write(dev, 0x32F, 0x3);
2127 +
2128         if (phy->radio_rev == 4 || phy->radio_rev == 6)
2129                 b43_nphy_rf_ctl_override_rev7(dev, 4, 1, 3, false, 0);
2130  
2131 @@ -2496,7 +3008,8 @@ static void b43_nphy_workarounds_rev7plu
2132                                                                 0x7f);
2133                                 }
2134                         }
2135 -                       if (phy->radio_rev == 3) {
2136 +                       switch (phy->radio_rev) {
2137 +                       case 3:
2138                                 for (core = 0; core < 2; core++) {
2139                                         if (core == 0) {
2140                                                 b43_radio_write(dev, 0x64,
2141 @@ -2522,17 +3035,34 @@ static void b43_nphy_workarounds_rev7plu
2142                                                                 0x3E);
2143                                         }
2144                                 }
2145 -                       } else if (phy->radio_rev == 7 || phy->radio_rev == 8) {
2146 -                               if (!phy->is_40mhz) {
2147 +                               break;
2148 +                       case 7:
2149 +                       case 8:
2150 +                               if (!b43_is_40mhz(dev)) {
2151                                         b43_radio_write(dev, 0x5F, 0x14);
2152                                         b43_radio_write(dev, 0xE8, 0x12);
2153                                 } else {
2154                                         b43_radio_write(dev, 0x5F, 0x16);
2155                                         b43_radio_write(dev, 0xE8, 0x16);
2156                                 }
2157 +                               break;
2158 +                       case 14:
2159 +                               for (core = 0; core < 2; core++) {
2160 +                                       int o = core ? 0x85 : 0;
2161 +
2162 +                                       b43_radio_write(dev, o + R2057_IPA2G_CASCONV_CORE0, 0x13);
2163 +                                       b43_radio_write(dev, o + R2057_TXMIX2G_TUNE_BOOST_PU_CORE0, 0x21);
2164 +                                       b43_radio_write(dev, o + R2057_IPA2G_BIAS_FILTER_CORE0, 0xff);
2165 +                                       b43_radio_write(dev, o + R2057_PAD2G_IDACS_CORE0, 0x88);
2166 +                                       b43_radio_write(dev, o + R2057_PAD2G_TUNE_PUS_CORE0, 0x23);
2167 +                                       b43_radio_write(dev, o + R2057_IPA2G_IMAIN_CORE0, 0x16);
2168 +                                       b43_radio_write(dev, o + R2057_PAD_BIAS_FILTER_BWS_CORE0, 0x3e);
2169 +                                       b43_radio_write(dev, o + R2057_BACKUP1_CORE0, 0x10);
2170 +                               }
2171 +                               break;
2172                         }
2173                 } else {
2174 -                       u16 freq = phy->channel_freq;
2175 +                       u16 freq = phy->chandef->chan->center_freq;
2176                         if ((freq >= 5180 && freq <= 5230) ||
2177                             (freq >= 5745 && freq <= 5805)) {
2178                                 b43_radio_write(dev, 0x7D, 0xFF);
2179 @@ -2577,8 +3107,8 @@ static void b43_nphy_workarounds_rev7plu
2180                 b43_phy_set(dev, B43_NPHY_AFECTL_OVER1, 0x1);
2181                 b43_phy_mask(dev, B43_NPHY_AFECTL_C2, ~0x1);
2182                 b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x1);
2183 -               b43_ntab_write(dev, B43_NTAB16(8, 0x05), 0x20);
2184 -               b43_ntab_write(dev, B43_NTAB16(8, 0x15), 0x20);
2185 +               b43_ntab_write(dev, B43_NTAB16(8, 0x05), 0);
2186 +               b43_ntab_write(dev, B43_NTAB16(8, 0x15), 0);
2187  
2188                 b43_phy_mask(dev, B43_NPHY_AFECTL_C1, ~0x4);
2189                 b43_phy_mask(dev, B43_NPHY_AFECTL_OVER1, ~0x4);
2190 @@ -2589,20 +3119,20 @@ static void b43_nphy_workarounds_rev7plu
2191         b43_phy_write(dev, B43_NPHY_ENDROP_TLEN, 0x2);
2192  
2193         b43_ntab_write(dev, B43_NTAB32(16, 0x100), 20);
2194 -       b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x138), 2, ntab7_138_146);
2195 +       b43_ntab_write_bulk(dev, B43_NTAB8(7, 0x138), 2, ntab7_138_146);
2196         b43_ntab_write(dev, B43_NTAB16(7, 0x141), 0x77);
2197 -       b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x133), 3, ntab7_133);
2198 -       b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x146), 2, ntab7_138_146);
2199 +       b43_ntab_write_bulk(dev, B43_NTAB8(7, 0x133), 3, ntab7_133);
2200 +       b43_ntab_write_bulk(dev, B43_NTAB8(7, 0x146), 2, ntab7_138_146);
2201         b43_ntab_write(dev, B43_NTAB16(7, 0x123), 0x77);
2202         b43_ntab_write(dev, B43_NTAB16(7, 0x12A), 0x77);
2203  
2204 -       if (!phy->is_40mhz) {
2205 -               b43_ntab_write(dev, B43_NTAB32(16, 0x03), 0x18D);
2206 -               b43_ntab_write(dev, B43_NTAB32(16, 0x7F), 0x18D);
2207 -       } else {
2208 -               b43_ntab_write(dev, B43_NTAB32(16, 0x03), 0x14D);
2209 -               b43_ntab_write(dev, B43_NTAB32(16, 0x7F), 0x14D);
2210 -       }
2211 +       b43_ntab_read_bulk(dev, B43_NTAB32(16, 0x02), 1, noise_tbl);
2212 +       noise_tbl[1] = b43_is_40mhz(dev) ? 0x14D : 0x18D;
2213 +       b43_ntab_write_bulk(dev, B43_NTAB32(16, 0x02), 2, noise_tbl);
2214 +
2215 +       b43_ntab_read_bulk(dev, B43_NTAB32(16, 0x7E), 1, noise_tbl);
2216 +       noise_tbl[1] = b43_is_40mhz(dev) ? 0x14D : 0x18D;
2217 +       b43_ntab_write_bulk(dev, B43_NTAB32(16, 0x7E), 2, noise_tbl);
2218  
2219         b43_nphy_gain_ctl_workarounds(dev);
2220  
2221 @@ -2695,7 +3225,7 @@ static void b43_nphy_workarounds_rev3plu
2222  
2223         b43_phy_maskset(dev, B43_NPHY_SGILTRNOFFSET, 0xF0FF, 0x0700);
2224  
2225 -       if (!dev->phy.is_40mhz) {
2226 +       if (!b43_is_40mhz(dev)) {
2227                 b43_ntab_write(dev, B43_NTAB32(16, 3), 0x18D);
2228                 b43_ntab_write(dev, B43_NTAB32(16, 127), 0x18D);
2229         } else {
2230 @@ -2930,6 +3460,7 @@ static void b43_nphy_workarounds(struct
2231         b43_phy_set(dev, B43_NPHY_IQFLIP,
2232                     B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2);
2233  
2234 +       /* TODO: rev19+ */
2235         if (dev->phy.rev >= 7)
2236                 b43_nphy_workarounds_rev7plus(dev);
2237         else if (dev->phy.rev >= 3)
2238 @@ -2950,12 +3481,13 @@ static void b43_nphy_workarounds(struct
2239   * http://bcm-v4.sipsolutions.net/802.11/PHY/N/TXTone
2240   */
2241  static int b43_nphy_tx_tone(struct b43_wldev *dev, u32 freq, u16 max_val,
2242 -                               bool iqmode, bool dac_test)
2243 +                           bool iqmode, bool dac_test, bool modify_bbmult)
2244  {
2245         u16 samp = b43_nphy_gen_load_samples(dev, freq, max_val, dac_test);
2246         if (samp == 0)
2247                 return -1;
2248 -       b43_nphy_run_samples(dev, samp, 0xFFFF, 0, iqmode, dac_test);
2249 +       b43_nphy_run_samples(dev, samp, 0xFFFF, 0, iqmode, dac_test,
2250 +                            modify_bbmult);
2251         return 0;
2252  }
2253  
2254 @@ -2990,6 +3522,7 @@ static void b43_nphy_update_txrx_chain(s
2255  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/stop-playback */
2256  static void b43_nphy_stop_playback(struct b43_wldev *dev)
2257  {
2258 +       struct b43_phy *phy = &dev->phy;
2259         struct b43_phy_n *nphy = dev->phy.n;
2260         u16 tmp;
2261  
2262 @@ -3010,6 +3543,15 @@ static void b43_nphy_stop_playback(struc
2263                 nphy->bb_mult_save = 0;
2264         }
2265  
2266 +       if (phy->rev >= 7) {
2267 +               if (phy->rev >= 19)
2268 +                       b43_nphy_rf_ctl_override_rev19(dev, 0x80, 0, 0, true,
2269 +                                                      1);
2270 +               else
2271 +                       b43_nphy_rf_ctl_override_rev7(dev, 0x80, 0, 0, true, 1);
2272 +               nphy->lpf_bw_overrode_for_sample_play = false;
2273 +       }
2274 +
2275         if (nphy->hang_avoid)
2276                 b43_nphy_stay_in_carrier_search(dev, 0);
2277  }
2278 @@ -3019,16 +3561,23 @@ static void b43_nphy_iq_cal_gain_params(
2279                                         struct nphy_txgains target,
2280                                         struct nphy_iqcal_params *params)
2281  {
2282 +       struct b43_phy *phy = &dev->phy;
2283         int i, j, indx;
2284         u16 gain;
2285  
2286         if (dev->phy.rev >= 3) {
2287 +               params->tx_lpf = target.tx_lpf[core]; /* Rev 7+ */
2288                 params->txgm = target.txgm[core];
2289                 params->pga = target.pga[core];
2290                 params->pad = target.pad[core];
2291                 params->ipa = target.ipa[core];
2292 -               params->cal_gain = (params->txgm << 12) | (params->pga << 8) |
2293 -                                       (params->pad << 4) | (params->ipa);
2294 +               if (phy->rev >= 19) {
2295 +                       /* TODO */
2296 +               } else if (phy->rev >= 7) {
2297 +                       params->cal_gain = (params->txgm << 12) | (params->pga << 8) | (params->pad << 3) | (params->ipa) | (params->tx_lpf << 15);
2298 +               } else {
2299 +                       params->cal_gain = (params->txgm << 12) | (params->pga << 8) | (params->pad << 4) | (params->ipa);
2300 +               }
2301                 for (j = 0; j < 5; j++)
2302                         params->ncorr[j] = 0x79;
2303         } else {
2304 @@ -3069,6 +3618,7 @@ static enum b43_txpwr_result b43_nphy_op
2305  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlEnable */
2306  static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable)
2307  {
2308 +       struct b43_phy *phy = &dev->phy;
2309         struct b43_phy_n *nphy = dev->phy.n;
2310         u8 i;
2311         u16 bmask, val, tmp;
2312 @@ -3118,7 +3668,7 @@ static void b43_nphy_tx_power_ctrl(struc
2313                         b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3,
2314                                 ~B43_NPHY_BPHY_CTL3_SCALE, 0x5A);
2315  
2316 -               if (dev->phy.rev < 2 && dev->phy.is_40mhz)
2317 +               if (dev->phy.rev < 2 && b43_is_40mhz(dev))
2318                         b43_hf_write(dev, b43_hf_read(dev) | B43_HF_TSSIRPSMW);
2319         } else {
2320                 b43_ntab_write_bulk(dev, B43_NTAB16(26, 64), 84,
2321 @@ -3138,12 +3688,25 @@ static void b43_nphy_tx_power_ctrl(struc
2322                 b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD, ~(bmask), val);
2323  
2324                 if (band == IEEE80211_BAND_5GHZ) {
2325 -                       b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD,
2326 -                                       ~B43_NPHY_TXPCTL_CMD_INIT, 0x64);
2327 -                       if (dev->phy.rev > 1)
2328 +                       if (phy->rev >= 19) {
2329 +                               /* TODO */
2330 +                       } else if (phy->rev >= 7) {
2331 +                               b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD,
2332 +                                               ~B43_NPHY_TXPCTL_CMD_INIT,
2333 +                                               0x32);
2334                                 b43_phy_maskset(dev, B43_NPHY_TXPCTL_INIT,
2335                                                 ~B43_NPHY_TXPCTL_INIT_PIDXI1,
2336 +                                               0x32);
2337 +                       } else {
2338 +                               b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD,
2339 +                                               ~B43_NPHY_TXPCTL_CMD_INIT,
2340                                                 0x64);
2341 +                               if (phy->rev > 1)
2342 +                                       b43_phy_maskset(dev,
2343 +                                                       B43_NPHY_TXPCTL_INIT,
2344 +                                                       ~B43_NPHY_TXPCTL_INIT_PIDXI1,
2345 +                                                       0x64);
2346 +                       }
2347                 }
2348  
2349                 if (dev->phy.rev >= 3) {
2350 @@ -3160,6 +3723,10 @@ static void b43_nphy_tx_power_ctrl(struc
2351                         }
2352                 }
2353  
2354 +               if (phy->rev >= 7) {
2355 +                       /* TODO */
2356 +               }
2357 +
2358                 if (dev->phy.rev >= 3) {
2359                         b43_phy_mask(dev, B43_NPHY_AFECTL_OVER1, ~0x100);
2360                         b43_phy_mask(dev, B43_NPHY_AFECTL_OVER, ~0x100);
2361 @@ -3172,7 +3739,7 @@ static void b43_nphy_tx_power_ctrl(struc
2362                 else if (dev->phy.rev < 2)
2363                         b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3, ~0xFF, 0x40);
2364  
2365 -               if (dev->phy.rev < 2 && dev->phy.is_40mhz)
2366 +               if (dev->phy.rev < 2 && b43_is_40mhz(dev))
2367                         b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_TSSIRPSMW);
2368  
2369                 if (b43_nphy_ipa(dev)) {
2370 @@ -3188,18 +3755,20 @@ static void b43_nphy_tx_power_ctrl(struc
2371  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrFix */
2372  static void b43_nphy_tx_power_fix(struct b43_wldev *dev)
2373  {
2374 +       struct b43_phy *phy = &dev->phy;
2375         struct b43_phy_n *nphy = dev->phy.n;
2376         struct ssb_sprom *sprom = dev->dev->bus_sprom;
2377  
2378         u8 txpi[2], bbmult, i;
2379         u16 tmp, radio_gain, dac_gain;
2380 -       u16 freq = dev->phy.channel_freq;
2381 +       u16 freq = phy->chandef->chan->center_freq;
2382         u32 txgain;
2383         /* u32 gaintbl; rev3+ */
2384  
2385         if (nphy->hang_avoid)
2386                 b43_nphy_stay_in_carrier_search(dev, 1);
2387  
2388 +       /* TODO: rev19+ */
2389         if (dev->phy.rev >= 7) {
2390                 txpi[0] = txpi[1] = 30;
2391         } else if (dev->phy.rev >= 3) {
2392 @@ -3238,7 +3807,11 @@ static void b43_nphy_tx_power_fix(struct
2393         */
2394  
2395         for (i = 0; i < 2; i++) {
2396 -               txgain = *(b43_nphy_get_tx_gain_table(dev) + txpi[i]);
2397 +               const u32 *table = b43_nphy_get_tx_gain_table(dev);
2398 +
2399 +               if (!table)
2400 +                       break;
2401 +               txgain = *(table + txpi[i]);
2402  
2403                 if (dev->phy.rev >= 3)
2404                         radio_gain = (txgain >> 16) & 0x1FFFF;
2405 @@ -3298,7 +3871,9 @@ static void b43_nphy_ipa_internal_tssi_s
2406         u8 core;
2407         u16 r; /* routing */
2408  
2409 -       if (phy->rev >= 7) {
2410 +       if (phy->rev >= 19) {
2411 +               /* TODO */
2412 +       } else if (phy->rev >= 7) {
2413                 for (core = 0; core < 2; core++) {
2414                         r = core ? 0x190 : 0x170;
2415                         if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
2416 @@ -3386,24 +3961,32 @@ static void b43_nphy_tx_power_ctl_idle_t
2417         if (b43_nphy_ipa(dev))
2418                 b43_nphy_ipa_internal_tssi_setup(dev);
2419  
2420 -       if (phy->rev >= 7)
2421 +       if (phy->rev >= 19)
2422 +               b43_nphy_rf_ctl_override_rev19(dev, 0x2000, 0, 3, false, 0);
2423 +       else if (phy->rev >= 7)
2424                 b43_nphy_rf_ctl_override_rev7(dev, 0x2000, 0, 3, false, 0);
2425         else if (phy->rev >= 3)
2426                 b43_nphy_rf_ctl_override(dev, 0x2000, 0, 3, false);
2427  
2428         b43_nphy_stop_playback(dev);
2429 -       b43_nphy_tx_tone(dev, 0xFA0, 0, false, false);
2430 +       b43_nphy_tx_tone(dev, 4000, 0, false, false, false);
2431         udelay(20);
2432         tmp = b43_nphy_poll_rssi(dev, N_RSSI_TSSI_2G, rssi, 1);
2433         b43_nphy_stop_playback(dev);
2434 +
2435         b43_nphy_rssi_select(dev, 0, N_RSSI_W1);
2436  
2437 -       if (phy->rev >= 7)
2438 +       if (phy->rev >= 19)
2439 +               b43_nphy_rf_ctl_override_rev19(dev, 0x2000, 0, 3, true, 0);
2440 +       else if (phy->rev >= 7)
2441                 b43_nphy_rf_ctl_override_rev7(dev, 0x2000, 0, 3, true, 0);
2442         else if (phy->rev >= 3)
2443                 b43_nphy_rf_ctl_override(dev, 0x2000, 0, 3, true);
2444  
2445 -       if (phy->rev >= 3) {
2446 +       if (phy->rev >= 19) {
2447 +               /* TODO */
2448 +               return;
2449 +       } else if (phy->rev >= 3) {
2450                 nphy->pwr_ctl_info[0].idle_tssi_5g = (tmp >> 24) & 0xFF;
2451                 nphy->pwr_ctl_info[1].idle_tssi_5g = (tmp >> 8) & 0xFF;
2452         } else {
2453 @@ -3443,21 +4026,21 @@ static void b43_nphy_tx_prepare_adjusted
2454                 delta = 0;
2455                 switch (stf_mode) {
2456                 case 0:
2457 -                       if (dev->phy.is_40mhz && dev->phy.rev >= 5) {
2458 +                       if (b43_is_40mhz(dev) && dev->phy.rev >= 5) {
2459                                 idx = 68;
2460                         } else {
2461                                 delta = 1;
2462 -                               idx = dev->phy.is_40mhz ? 52 : 4;
2463 +                               idx = b43_is_40mhz(dev) ? 52 : 4;
2464                         }
2465                         break;
2466                 case 1:
2467 -                       idx = dev->phy.is_40mhz ? 76 : 28;
2468 +                       idx = b43_is_40mhz(dev) ? 76 : 28;
2469                         break;
2470                 case 2:
2471 -                       idx = dev->phy.is_40mhz ? 84 : 36;
2472 +                       idx = b43_is_40mhz(dev) ? 84 : 36;
2473                         break;
2474                 case 3:
2475 -                       idx = dev->phy.is_40mhz ? 92 : 44;
2476 +                       idx = b43_is_40mhz(dev) ? 92 : 44;
2477                         break;
2478                 }
2479  
2480 @@ -3478,6 +4061,7 @@ static void b43_nphy_tx_prepare_adjusted
2481  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlSetup */
2482  static void b43_nphy_tx_power_ctl_setup(struct b43_wldev *dev)
2483  {
2484 +       struct b43_phy *phy = &dev->phy;
2485         struct b43_phy_n *nphy = dev->phy.n;
2486         struct ssb_sprom *sprom = dev->dev->bus_sprom;
2487  
2488 @@ -3487,7 +4071,7 @@ static void b43_nphy_tx_power_ctl_setup(
2489         s32 num, den, pwr;
2490         u32 regval[64];
2491  
2492 -       u16 freq = dev->phy.channel_freq;
2493 +       u16 freq = phy->chandef->chan->center_freq;
2494         u16 tmp;
2495         u16 r; /* routing */
2496         u8 i, c;
2497 @@ -3594,7 +4178,9 @@ static void b43_nphy_tx_power_ctl_setup(
2498                 udelay(1);
2499         }
2500  
2501 -       if (dev->phy.rev >= 7) {
2502 +       if (phy->rev >= 19) {
2503 +               /* TODO */
2504 +       } else if (phy->rev >= 7) {
2505                 b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD,
2506                                 ~B43_NPHY_TXPCTL_CMD_INIT, 0x19);
2507                 b43_phy_maskset(dev, B43_NPHY_TXPCTL_INIT,
2508 @@ -3651,27 +4237,36 @@ static void b43_nphy_tx_gain_table_uploa
2509         int i;
2510  
2511         table = b43_nphy_get_tx_gain_table(dev);
2512 +       if (!table)
2513 +               return;
2514 +
2515         b43_ntab_write_bulk(dev, B43_NTAB32(26, 192), 128, table);
2516         b43_ntab_write_bulk(dev, B43_NTAB32(27, 192), 128, table);
2517  
2518 -       if (phy->rev >= 3) {
2519 +       if (phy->rev < 3)
2520 +               return;
2521 +
2522  #if 0
2523 -               nphy->gmval = (table[0] >> 16) & 0x7000;
2524 +       nphy->gmval = (table[0] >> 16) & 0x7000;
2525  #endif
2526  
2527 -               for (i = 0; i < 128; i++) {
2528 +       for (i = 0; i < 128; i++) {
2529 +               if (phy->rev >= 19) {
2530 +                       /* TODO */
2531 +                       return;
2532 +               } else if (phy->rev >= 7) {
2533 +                       /* TODO */
2534 +                       return;
2535 +               } else {
2536                         pga_gain = (table[i] >> 24) & 0xF;
2537                         if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
2538 -                               rfpwr_offset =
2539 -                                b43_ntab_papd_pga_gain_delta_ipa_2g[pga_gain];
2540 +                               rfpwr_offset = b43_ntab_papd_pga_gain_delta_ipa_2g[pga_gain];
2541                         else
2542 -                               rfpwr_offset =
2543 -                                0; /* FIXME */
2544 -                       b43_ntab_write(dev, B43_NTAB32(26, 576 + i),
2545 -                                      rfpwr_offset);
2546 -                       b43_ntab_write(dev, B43_NTAB32(27, 576 + i),
2547 -                                      rfpwr_offset);
2548 +                               rfpwr_offset = 0; /* FIXME */
2549                 }
2550 +
2551 +               b43_ntab_write(dev, B43_NTAB32(26, 576 + i), rfpwr_offset);
2552 +               b43_ntab_write(dev, B43_NTAB32(27, 576 + i), rfpwr_offset);
2553         }
2554  }
2555  
2556 @@ -3688,7 +4283,9 @@ static void b43_nphy_pa_override(struct
2557                 nphy->rfctrl_intc2_save = b43_phy_read(dev,
2558                                                        B43_NPHY_RFCTL_INTC2);
2559                 band = b43_current_band(dev->wl);
2560 -               if (dev->phy.rev >= 3) {
2561 +               if (dev->phy.rev >= 7) {
2562 +                       tmp = 0x1480;
2563 +               } else if (dev->phy.rev >= 3) {
2564                         if (band == IEEE80211_BAND_5GHZ)
2565                                 tmp = 0x600;
2566                         else
2567 @@ -3709,21 +4306,28 @@ static void b43_nphy_pa_override(struct
2568         }
2569  }
2570  
2571 -/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxLpFbw */
2572 -static void b43_nphy_tx_lp_fbw(struct b43_wldev *dev)
2573 +/*
2574 + * TX low-pass filter bandwidth setup
2575 + * http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxLpFbw
2576 + */
2577 +static void b43_nphy_tx_lpf_bw(struct b43_wldev *dev)
2578  {
2579         u16 tmp;
2580  
2581 -       if (dev->phy.rev >= 3) {
2582 -               if (b43_nphy_ipa(dev)) {
2583 -                       tmp = 4;
2584 -                       b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S2,
2585 -                             (((((tmp << 3) | tmp) << 3) | tmp) << 3) | tmp);
2586 -               }
2587 +       if (dev->phy.rev < 3 || dev->phy.rev >= 7)
2588 +               return;
2589 +
2590 +       if (b43_nphy_ipa(dev))
2591 +               tmp = b43_is_40mhz(dev) ? 5 : 4;
2592 +       else
2593 +               tmp = b43_is_40mhz(dev) ? 3 : 1;
2594 +       b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S2,
2595 +                     (tmp << 9) | (tmp << 6) | (tmp << 3) | tmp);
2596  
2597 -               tmp = 1;
2598 +       if (b43_nphy_ipa(dev)) {
2599 +               tmp = b43_is_40mhz(dev) ? 4 : 1;
2600                 b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S2,
2601 -                             (((((tmp << 3) | tmp) << 3) | tmp) << 3) | tmp);
2602 +                             (tmp << 9) | (tmp << 6) | (tmp << 3) | tmp);
2603         }
2604  }
2605  
2606 @@ -3996,7 +4600,7 @@ static void b43_nphy_spur_workaround(str
2607  
2608         if (nphy->gband_spurwar_en) {
2609                 /* TODO: N PHY Adjust Analog Pfbw (7) */
2610 -               if (channel == 11 && dev->phy.is_40mhz)
2611 +               if (channel == 11 && b43_is_40mhz(dev))
2612                         ; /* TODO: N PHY Adjust Min Noise Var(2, tone, noise)*/
2613                 else
2614                         ; /* TODO: N PHY Adjust Min Noise Var(0, NULL, NULL)*/
2615 @@ -4128,7 +4732,13 @@ static void b43_nphy_restore_rssi_cal(st
2616                 rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G;
2617         }
2618  
2619 -       if (dev->phy.rev >= 7) {
2620 +       if (dev->phy.rev >= 19) {
2621 +               /* TODO */
2622 +       } else if (dev->phy.rev >= 7) {
2623 +               b43_radio_maskset(dev, R2057_NB_MASTER_CORE0, ~R2057_VCM_MASK,
2624 +                                 rssical_radio_regs[0]);
2625 +               b43_radio_maskset(dev, R2057_NB_MASTER_CORE1, ~R2057_VCM_MASK,
2626 +                                 rssical_radio_regs[1]);
2627         } else {
2628                 b43_radio_maskset(dev, B2056_RX0 | B2056_RX_RSSI_MISC, 0xE3,
2629                                   rssical_radio_regs[0]);
2630 @@ -4152,15 +4762,78 @@ static void b43_nphy_restore_rssi_cal(st
2631         b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Y, rssical_phy_regs[11]);
2632  }
2633  
2634 +static void b43_nphy_tx_cal_radio_setup_rev19(struct b43_wldev *dev)
2635 +{
2636 +       /* TODO */
2637 +}
2638 +
2639 +static void b43_nphy_tx_cal_radio_setup_rev7(struct b43_wldev *dev)
2640 +{
2641 +       struct b43_phy *phy = &dev->phy;
2642 +       struct b43_phy_n *nphy = dev->phy.n;
2643 +       u16 *save = nphy->tx_rx_cal_radio_saveregs;
2644 +       int core, off;
2645 +       u16 r, tmp;
2646 +
2647 +       for (core = 0; core < 2; core++) {
2648 +               r = core ? 0x20 : 0;
2649 +               off = core * 11;
2650 +
2651 +               save[off + 0] = b43_radio_read(dev, r + R2057_TX0_TX_SSI_MASTER);
2652 +               save[off + 1] = b43_radio_read(dev, r + R2057_TX0_IQCAL_VCM_HG);
2653 +               save[off + 2] = b43_radio_read(dev, r + R2057_TX0_IQCAL_IDAC);
2654 +               save[off + 3] = b43_radio_read(dev, r + R2057_TX0_TSSI_VCM);
2655 +               save[off + 4] = 0;
2656 +               save[off + 5] = b43_radio_read(dev, r + R2057_TX0_TX_SSI_MUX);
2657 +               if (phy->radio_rev != 5)
2658 +                       save[off + 6] = b43_radio_read(dev, r + R2057_TX0_TSSIA);
2659 +               save[off + 7] = b43_radio_read(dev, r + R2057_TX0_TSSIG);
2660 +               save[off + 8] = b43_radio_read(dev, r + R2057_TX0_TSSI_MISC1);
2661 +
2662 +               if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
2663 +                       b43_radio_write(dev, r + R2057_TX0_TX_SSI_MASTER, 0xA);
2664 +                       b43_radio_write(dev, r + R2057_TX0_IQCAL_VCM_HG, 0x43);
2665 +                       b43_radio_write(dev, r + R2057_TX0_IQCAL_IDAC, 0x55);
2666 +                       b43_radio_write(dev, r + R2057_TX0_TSSI_VCM, 0);
2667 +                       b43_radio_write(dev, r + R2057_TX0_TSSIG, 0);
2668 +                       if (nphy->use_int_tx_iq_lo_cal) {
2669 +                               b43_radio_write(dev, r + R2057_TX0_TX_SSI_MUX, 0x4);
2670 +                               tmp = true ? 0x31 : 0x21; /* TODO */
2671 +                               b43_radio_write(dev, r + R2057_TX0_TSSIA, tmp);
2672 +                       }
2673 +                       b43_radio_write(dev, r + R2057_TX0_TSSI_MISC1, 0x00);
2674 +               } else {
2675 +                       b43_radio_write(dev, r + R2057_TX0_TX_SSI_MASTER, 0x6);
2676 +                       b43_radio_write(dev, r + R2057_TX0_IQCAL_VCM_HG, 0x43);
2677 +                       b43_radio_write(dev, r + R2057_TX0_IQCAL_IDAC, 0x55);
2678 +                       b43_radio_write(dev, r + R2057_TX0_TSSI_VCM, 0);
2679 +
2680 +                       if (phy->radio_rev != 5)
2681 +                               b43_radio_write(dev, r + R2057_TX0_TSSIA, 0);
2682 +                       if (nphy->use_int_tx_iq_lo_cal) {
2683 +                               b43_radio_write(dev, r + R2057_TX0_TX_SSI_MUX, 0x6);
2684 +                               tmp = true ? 0x31 : 0x21; /* TODO */
2685 +                               b43_radio_write(dev, r + R2057_TX0_TSSIG, tmp);
2686 +                       }
2687 +                       b43_radio_write(dev, r + R2057_TX0_TSSI_MISC1, 0);
2688 +               }
2689 +       }
2690 +}
2691 +
2692  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalRadioSetup */
2693  static void b43_nphy_tx_cal_radio_setup(struct b43_wldev *dev)
2694  {
2695 +       struct b43_phy *phy = &dev->phy;
2696         struct b43_phy_n *nphy = dev->phy.n;
2697         u16 *save = nphy->tx_rx_cal_radio_saveregs;
2698         u16 tmp;
2699         u8 offset, i;
2700  
2701 -       if (dev->phy.rev >= 3) {
2702 +       if (phy->rev >= 19) {
2703 +               b43_nphy_tx_cal_radio_setup_rev19(dev);
2704 +       } else if (phy->rev >= 7) {
2705 +               b43_nphy_tx_cal_radio_setup_rev7(dev);
2706 +       } else if (phy->rev >= 3) {
2707             for (i = 0; i < 2; i++) {
2708                 tmp = (i == 0) ? 0x2000 : 0x3000;
2709                 offset = i * 11;
2710 @@ -4269,41 +4942,61 @@ static void b43_nphy_update_tx_cal_ladde
2711         }
2712  }
2713  
2714 +static void b43_nphy_pa_set_tx_dig_filter(struct b43_wldev *dev, u16 offset,
2715 +                                         const s16 *filter)
2716 +{
2717 +       int i;
2718 +
2719 +       offset = B43_PHY_N(offset);
2720 +
2721 +       for (i = 0; i < 15; i++, offset++)
2722 +               b43_phy_write(dev, offset, filter[i]);
2723 +}
2724 +
2725  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ExtPaSetTxDigiFilts */
2726  static void b43_nphy_ext_pa_set_tx_dig_filters(struct b43_wldev *dev)
2727  {
2728 -       int i;
2729 -       for (i = 0; i < 15; i++)
2730 -               b43_phy_write(dev, B43_PHY_N(0x2C5 + i),
2731 -                               tbl_tx_filter_coef_rev4[2][i]);
2732 +       b43_nphy_pa_set_tx_dig_filter(dev, 0x2C5,
2733 +                                     tbl_tx_filter_coef_rev4[2]);
2734  }
2735  
2736  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/IpaSetTxDigiFilts */
2737  static void b43_nphy_int_pa_set_tx_dig_filters(struct b43_wldev *dev)
2738  {
2739 -       int i, j;
2740         /* B43_NPHY_TXF_20CO_S0A1, B43_NPHY_TXF_40CO_S0A1, unknown */
2741         static const u16 offset[] = { 0x186, 0x195, 0x2C5 };
2742 +       static const s16 dig_filter_phy_rev16[] = {
2743 +               -375, 136, -407, 208, -1527,
2744 +               956, 93, 186, 93, 230,
2745 +               -44, 230, 201, -191, 201,
2746 +       };
2747 +       int i;
2748  
2749         for (i = 0; i < 3; i++)
2750 -               for (j = 0; j < 15; j++)
2751 -                       b43_phy_write(dev, B43_PHY_N(offset[i] + j),
2752 -                                       tbl_tx_filter_coef_rev4[i][j]);
2753 -
2754 -       if (dev->phy.is_40mhz) {
2755 -               for (j = 0; j < 15; j++)
2756 -                       b43_phy_write(dev, B43_PHY_N(offset[0] + j),
2757 -                                       tbl_tx_filter_coef_rev4[3][j]);
2758 -       } else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
2759 -               for (j = 0; j < 15; j++)
2760 -                       b43_phy_write(dev, B43_PHY_N(offset[0] + j),
2761 -                                       tbl_tx_filter_coef_rev4[5][j]);
2762 -       }
2763 -
2764 -       if (dev->phy.channel == 14)
2765 -               for (j = 0; j < 15; j++)
2766 -                       b43_phy_write(dev, B43_PHY_N(offset[0] + j),
2767 -                                       tbl_tx_filter_coef_rev4[6][j]);
2768 +               b43_nphy_pa_set_tx_dig_filter(dev, offset[i],
2769 +                                             tbl_tx_filter_coef_rev4[i]);
2770 +
2771 +       /* Verified with BCM43227 and BCM43228 */
2772 +       if (dev->phy.rev == 16)
2773 +               b43_nphy_pa_set_tx_dig_filter(dev, 0x186, dig_filter_phy_rev16);
2774 +
2775 +       if (dev->dev->chip_id == BCMA_CHIP_ID_BCM43217) {
2776 +               b43_nphy_pa_set_tx_dig_filter(dev, 0x186, dig_filter_phy_rev16);
2777 +               b43_nphy_pa_set_tx_dig_filter(dev, 0x195,
2778 +                                             tbl_tx_filter_coef_rev4[1]);
2779 +       }
2780 +
2781 +       if (b43_is_40mhz(dev)) {
2782 +               b43_nphy_pa_set_tx_dig_filter(dev, 0x186,
2783 +                                             tbl_tx_filter_coef_rev4[3]);
2784 +       } else {
2785 +               if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
2786 +                       b43_nphy_pa_set_tx_dig_filter(dev, 0x186,
2787 +                                                     tbl_tx_filter_coef_rev4[5]);
2788 +               if (dev->phy.channel == 14)
2789 +                       b43_nphy_pa_set_tx_dig_filter(dev, 0x186,
2790 +                                                     tbl_tx_filter_coef_rev4[6]);
2791 +       }
2792  }
2793  
2794  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetTxGain */
2795 @@ -4325,7 +5018,13 @@ static struct nphy_txgains b43_nphy_get_
2796                         b43_nphy_stay_in_carrier_search(dev, false);
2797  
2798                 for (i = 0; i < 2; ++i) {
2799 -                       if (dev->phy.rev >= 3) {
2800 +                       if (dev->phy.rev >= 7) {
2801 +                               target.ipa[i] = curr_gain[i] & 0x0007;
2802 +                               target.pad[i] = (curr_gain[i] & 0x00F8) >> 3;
2803 +                               target.pga[i] = (curr_gain[i] & 0x0F00) >> 8;
2804 +                               target.txgm[i] = (curr_gain[i] & 0x7000) >> 12;
2805 +                               target.tx_lpf[i] = (curr_gain[i] & 0x8000) >> 15;
2806 +                       } else if (dev->phy.rev >= 3) {
2807                                 target.ipa[i] = curr_gain[i] & 0x000F;
2808                                 target.pad[i] = (curr_gain[i] & 0x00F0) >> 4;
2809                                 target.pga[i] = (curr_gain[i] & 0x0F00) >> 8;
2810 @@ -4349,7 +5048,16 @@ static struct nphy_txgains b43_nphy_get_
2811  
2812                 for (i = 0; i < 2; ++i) {
2813                         table = b43_nphy_get_tx_gain_table(dev);
2814 -                       if (dev->phy.rev >= 3) {
2815 +                       if (!table)
2816 +                               break;
2817 +
2818 +                       if (dev->phy.rev >= 7) {
2819 +                               target.ipa[i] = (table[index[i]] >> 16) & 0x7;
2820 +                               target.pad[i] = (table[index[i]] >> 19) & 0x1F;
2821 +                               target.pga[i] = (table[index[i]] >> 24) & 0xF;
2822 +                               target.txgm[i] = (table[index[i]] >> 28) & 0x7;
2823 +                               target.tx_lpf[i] = (table[index[i]] >> 31) & 0x1;
2824 +                       } else if (dev->phy.rev >= 3) {
2825                                 target.ipa[i] = (table[index[i]] >> 16) & 0xF;
2826                                 target.pad[i] = (table[index[i]] >> 20) & 0xF;
2827                                 target.pga[i] = (table[index[i]] >> 24) & 0xF;
2828 @@ -4398,6 +5106,8 @@ static void b43_nphy_tx_cal_phy_cleanup(
2829  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalPhySetup */
2830  static void b43_nphy_tx_cal_phy_setup(struct b43_wldev *dev)
2831  {
2832 +       struct b43_phy *phy = &dev->phy;
2833 +       struct b43_phy_n *nphy = dev->phy.n;
2834         u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs;
2835         u16 tmp;
2836  
2837 @@ -4429,7 +5139,12 @@ static void b43_nphy_tx_cal_phy_setup(st
2838                 regs[7] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
2839                 regs[8] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
2840  
2841 -               b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_PA, 1, 3);
2842 +               if (!nphy->use_int_tx_iq_lo_cal)
2843 +                       b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_PA,
2844 +                                                     1, 3);
2845 +               else
2846 +                       b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_PA,
2847 +                                                     0, 3);
2848                 b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_TRSW, 2, 1);
2849                 b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_TRSW, 8, 2);
2850  
2851 @@ -4437,6 +5152,33 @@ static void b43_nphy_tx_cal_phy_setup(st
2852                 regs[10] = b43_phy_read(dev, B43_NPHY_PAPD_EN1);
2853                 b43_phy_mask(dev, B43_NPHY_PAPD_EN0, ~0x0001);
2854                 b43_phy_mask(dev, B43_NPHY_PAPD_EN1, ~0x0001);
2855 +
2856 +               tmp = b43_nphy_read_lpf_ctl(dev, 0);
2857 +               if (phy->rev >= 19)
2858 +                       b43_nphy_rf_ctl_override_rev19(dev, 0x80, tmp, 0, false,
2859 +                                                      1);
2860 +               else if (phy->rev >= 7)
2861 +                       b43_nphy_rf_ctl_override_rev7(dev, 0x80, tmp, 0, false,
2862 +                                                     1);
2863 +
2864 +               if (nphy->use_int_tx_iq_lo_cal && true /* FIXME */) {
2865 +                       if (phy->rev >= 19) {
2866 +                               b43_nphy_rf_ctl_override_rev19(dev, 0x8, 0, 0x3,
2867 +                                                              false, 0);
2868 +                       } else if (phy->rev >= 8) {
2869 +                               b43_nphy_rf_ctl_override_rev7(dev, 0x8, 0, 0x3,
2870 +                                                             false, 0);
2871 +                       } else if (phy->rev == 7) {
2872 +                               b43_radio_maskset(dev, R2057_OVR_REG0, 1 << 4, 1 << 4);
2873 +                               if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
2874 +                                       b43_radio_maskset(dev, R2057_PAD2G_TUNE_PUS_CORE0, ~1, 0);
2875 +                                       b43_radio_maskset(dev, R2057_PAD2G_TUNE_PUS_CORE1, ~1, 0);
2876 +                               } else {
2877 +                                       b43_radio_maskset(dev, R2057_IPA5G_CASCOFFV_PU_CORE0, ~1, 0);
2878 +                                       b43_radio_maskset(dev, R2057_IPA5G_CASCOFFV_PU_CORE1, ~1, 0);
2879 +                               }
2880 +                       }
2881 +               }
2882         } else {
2883                 b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, 0xA000);
2884                 b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, 0xA000);
2885 @@ -4465,6 +5207,7 @@ static void b43_nphy_tx_cal_phy_setup(st
2886  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SaveCal */
2887  static void b43_nphy_save_cal(struct b43_wldev *dev)
2888  {
2889 +       struct b43_phy *phy = &dev->phy;
2890         struct b43_phy_n *nphy = dev->phy.n;
2891  
2892         struct b43_phy_n_iq_comp *rxcal_coeffs = NULL;
2893 @@ -4489,7 +5232,26 @@ static void b43_nphy_save_cal(struct b43
2894  
2895         b43_nphy_rx_iq_coeffs(dev, false, rxcal_coeffs);
2896         /* TODO use some definitions */
2897 -       if (dev->phy.rev >= 3) {
2898 +       if (phy->rev >= 19) {
2899 +               /* TODO */
2900 +       } else if (phy->rev >= 7) {
2901 +               txcal_radio_regs[0] = b43_radio_read(dev,
2902 +                                                    R2057_TX0_LOFT_FINE_I);
2903 +               txcal_radio_regs[1] = b43_radio_read(dev,
2904 +                                                    R2057_TX0_LOFT_FINE_Q);
2905 +               txcal_radio_regs[4] = b43_radio_read(dev,
2906 +                                                    R2057_TX0_LOFT_COARSE_I);
2907 +               txcal_radio_regs[5] = b43_radio_read(dev,
2908 +                                                    R2057_TX0_LOFT_COARSE_Q);
2909 +               txcal_radio_regs[2] = b43_radio_read(dev,
2910 +                                                    R2057_TX1_LOFT_FINE_I);
2911 +               txcal_radio_regs[3] = b43_radio_read(dev,
2912 +                                                    R2057_TX1_LOFT_FINE_Q);
2913 +               txcal_radio_regs[6] = b43_radio_read(dev,
2914 +                                                    R2057_TX1_LOFT_COARSE_I);
2915 +               txcal_radio_regs[7] = b43_radio_read(dev,
2916 +                                                    R2057_TX1_LOFT_COARSE_Q);
2917 +       } else if (phy->rev >= 3) {
2918                 txcal_radio_regs[0] = b43_radio_read(dev, 0x2021);
2919                 txcal_radio_regs[1] = b43_radio_read(dev, 0x2022);
2920                 txcal_radio_regs[2] = b43_radio_read(dev, 0x3021);
2921 @@ -4504,8 +5266,9 @@ static void b43_nphy_save_cal(struct b43
2922                 txcal_radio_regs[2] = b43_radio_read(dev, 0x8D);
2923                 txcal_radio_regs[3] = b43_radio_read(dev, 0xBC);
2924         }
2925 -       iqcal_chanspec->center_freq = dev->phy.channel_freq;
2926 -       iqcal_chanspec->channel_type = dev->phy.channel_type;
2927 +       iqcal_chanspec->center_freq = dev->phy.chandef->chan->center_freq;
2928 +       iqcal_chanspec->channel_type =
2929 +                               cfg80211_get_chandef_type(dev->phy.chandef);
2930         b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 8, table);
2931  
2932         if (nphy->hang_avoid)
2933 @@ -4515,6 +5278,7 @@ static void b43_nphy_save_cal(struct b43
2934  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RestoreCal */
2935  static void b43_nphy_restore_cal(struct b43_wldev *dev)
2936  {
2937 +       struct b43_phy *phy = &dev->phy;
2938         struct b43_phy_n *nphy = dev->phy.n;
2939  
2940         u16 coef[4];
2941 @@ -4562,7 +5326,26 @@ static void b43_nphy_restore_cal(struct
2942         }
2943  
2944         /* TODO use some definitions */
2945 -       if (dev->phy.rev >= 3) {
2946 +       if (phy->rev >= 19) {
2947 +               /* TODO */
2948 +       } else if (phy->rev >= 7) {
2949 +               b43_radio_write(dev, R2057_TX0_LOFT_FINE_I,
2950 +                               txcal_radio_regs[0]);
2951 +               b43_radio_write(dev, R2057_TX0_LOFT_FINE_Q,
2952 +                               txcal_radio_regs[1]);
2953 +               b43_radio_write(dev, R2057_TX0_LOFT_COARSE_I,
2954 +                               txcal_radio_regs[4]);
2955 +               b43_radio_write(dev, R2057_TX0_LOFT_COARSE_Q,
2956 +                               txcal_radio_regs[5]);
2957 +               b43_radio_write(dev, R2057_TX1_LOFT_FINE_I,
2958 +                               txcal_radio_regs[2]);
2959 +               b43_radio_write(dev, R2057_TX1_LOFT_FINE_Q,
2960 +                               txcal_radio_regs[3]);
2961 +               b43_radio_write(dev, R2057_TX1_LOFT_COARSE_I,
2962 +                               txcal_radio_regs[6]);
2963 +               b43_radio_write(dev, R2057_TX1_LOFT_COARSE_Q,
2964 +                               txcal_radio_regs[7]);
2965 +       } else if (phy->rev >= 3) {
2966                 b43_radio_write(dev, 0x2021, txcal_radio_regs[0]);
2967                 b43_radio_write(dev, 0x2022, txcal_radio_regs[1]);
2968                 b43_radio_write(dev, 0x3021, txcal_radio_regs[2]);
2969 @@ -4585,6 +5368,7 @@ static int b43_nphy_cal_tx_iq_lo(struct
2970                                 struct nphy_txgains target,
2971                                 bool full, bool mphase)
2972  {
2973 +       struct b43_phy *phy = &dev->phy;
2974         struct b43_phy_n *nphy = dev->phy.n;
2975         int i;
2976         int error = 0;
2977 @@ -4625,7 +5409,7 @@ static int b43_nphy_cal_tx_iq_lo(struct
2978                 (dev->phy.rev == 5 && nphy->ipa2g_on &&
2979                 b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ);
2980         if (phy6or5x) {
2981 -               if (dev->phy.is_40mhz) {
2982 +               if (b43_is_40mhz(dev)) {
2983                         b43_ntab_write_bulk(dev, B43_NTAB16(15, 0), 18,
2984                                         tbl_tx_iqlo_cal_loft_ladder_40);
2985                         b43_ntab_write_bulk(dev, B43_NTAB16(15, 32), 18,
2986 @@ -4638,18 +5422,24 @@ static int b43_nphy_cal_tx_iq_lo(struct
2987                 }
2988         }
2989  
2990 -       b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8AA9);
2991 +       if (phy->rev >= 19) {
2992 +               /* TODO */
2993 +       } else if (phy->rev >= 7) {
2994 +               b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8AD9);
2995 +       } else {
2996 +               b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8AA9);
2997 +       }
2998  
2999 -       if (!dev->phy.is_40mhz)
3000 +       if (!b43_is_40mhz(dev))
3001                 freq = 2500;
3002         else
3003                 freq = 5000;
3004  
3005         if (nphy->mphase_cal_phase_id > 2)
3006 -               b43_nphy_run_samples(dev, (dev->phy.is_40mhz ? 40 : 20) * 8,
3007 -                                       0xFFFF, 0, true, false);
3008 +               b43_nphy_run_samples(dev, (b43_is_40mhz(dev) ? 40 : 20) * 8,
3009 +                                    0xFFFF, 0, true, false, false);
3010         else
3011 -               error = b43_nphy_tx_tone(dev, freq, 250, true, false);
3012 +               error = b43_nphy_tx_tone(dev, freq, 250, true, false, false);
3013  
3014         if (error == 0) {
3015                 if (nphy->mphase_cal_phase_id > 2) {
3016 @@ -4777,9 +5567,9 @@ static int b43_nphy_cal_tx_iq_lo(struct
3017                                                 nphy->txiqlocal_bestc);
3018                         nphy->txiqlocal_coeffsvalid = true;
3019                         nphy->txiqlocal_chanspec.center_freq =
3020 -                                                       dev->phy.channel_freq;
3021 +                                               phy->chandef->chan->center_freq;
3022                         nphy->txiqlocal_chanspec.channel_type =
3023 -                                                       dev->phy.channel_type;
3024 +                                       cfg80211_get_chandef_type(phy->chandef);
3025                 } else {
3026                         length = 11;
3027                         if (dev->phy.rev < 3)
3028 @@ -4815,8 +5605,8 @@ static void b43_nphy_reapply_tx_cal_coef
3029         bool equal = true;
3030  
3031         if (!nphy->txiqlocal_coeffsvalid ||
3032 -           nphy->txiqlocal_chanspec.center_freq != dev->phy.channel_freq ||
3033 -           nphy->txiqlocal_chanspec.channel_type != dev->phy.channel_type)
3034 +           nphy->txiqlocal_chanspec.center_freq != dev->phy.chandef->chan->center_freq ||
3035 +           nphy->txiqlocal_chanspec.channel_type != cfg80211_get_chandef_type(dev->phy.chandef))
3036                 return;
3037  
3038         b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer);
3039 @@ -4972,11 +5762,11 @@ static int b43_nphy_rev2_cal_rx_iq(struc
3040                         if (playtone) {
3041                                 ret = b43_nphy_tx_tone(dev, 4000,
3042                                                 (nphy->rxcalparams & 0xFFFF),
3043 -                                               false, false);
3044 +                                               false, false, true);
3045                                 playtone = false;
3046                         } else {
3047 -                               b43_nphy_run_samples(dev, 160, 0xFFFF, 0,
3048 -                                                       false, false);
3049 +                               b43_nphy_run_samples(dev, 160, 0xFFFF, 0, false,
3050 +                                                    false, true);
3051                         }
3052  
3053                         if (ret == 0) {
3054 @@ -5032,6 +5822,9 @@ static int b43_nphy_rev3_cal_rx_iq(struc
3055  static int b43_nphy_cal_rx_iq(struct b43_wldev *dev,
3056                         struct nphy_txgains target, u8 type, bool debug)
3057  {
3058 +       if (dev->phy.rev >= 7)
3059 +               type = 0;
3060 +
3061         if (dev->phy.rev >= 3)
3062                 return b43_nphy_rev3_cal_rx_iq(dev, target, type, debug);
3063         else
3064 @@ -5118,6 +5911,9 @@ static void b43_nphy_bphy_init(struct b4
3065  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SuperSwitchInit */
3066  static void b43_nphy_superswitch_init(struct b43_wldev *dev, bool init)
3067  {
3068 +       if (dev->phy.rev >= 7)
3069 +               return;
3070 +
3071         if (dev->phy.rev >= 3) {
3072                 if (!init)
3073                         return;
3074 @@ -5193,6 +5989,10 @@ static int b43_phy_initn(struct b43_wlde
3075  #endif
3076                 }
3077         }
3078 +       nphy->use_int_tx_iq_lo_cal = b43_nphy_ipa(dev) ||
3079 +               phy->rev >= 7 ||
3080 +               (phy->rev >= 5 &&
3081 +                sprom->boardflags2_hi & B43_BFH2_INTERNDET_TXIQCAL);
3082         nphy->deaf_count = 0;
3083         b43_nphy_tables_init(dev);
3084         nphy->crsminpwr_adjusted = false;
3085 @@ -5202,6 +6002,16 @@ static int b43_phy_initn(struct b43_wlde
3086         if (dev->phy.rev >= 3) {
3087                 b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S1, 0);
3088                 b43_phy_write(dev, B43_NPHY_RFCTL_OVER, 0);
3089 +               if (phy->rev >= 7) {
3090 +                       b43_phy_write(dev, B43_NPHY_REV7_RF_CTL_OVER3, 0);
3091 +                       b43_phy_write(dev, B43_NPHY_REV7_RF_CTL_OVER4, 0);
3092 +                       b43_phy_write(dev, B43_NPHY_REV7_RF_CTL_OVER5, 0);
3093 +                       b43_phy_write(dev, B43_NPHY_REV7_RF_CTL_OVER6, 0);
3094 +               }
3095 +               if (phy->rev >= 19) {
3096 +                       /* TODO */
3097 +               }
3098 +
3099                 b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S0, 0);
3100                 b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S1, 0);
3101         } else {
3102 @@ -5239,7 +6049,9 @@ static int b43_phy_initn(struct b43_wlde
3103         b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x50);
3104         b43_phy_write(dev, B43_NPHY_TXRIFS_FRDEL, 0x30);
3105  
3106 -       b43_nphy_update_mimo_config(dev, nphy->preamble_override);
3107 +       if (phy->rev < 8)
3108 +               b43_nphy_update_mimo_config(dev, nphy->preamble_override);
3109 +
3110         b43_nphy_update_txrx_chain(dev);
3111  
3112         if (phy->rev < 2) {
3113 @@ -5271,10 +6083,12 @@ static int b43_phy_initn(struct b43_wlde
3114  
3115         b43_mac_phy_clock_set(dev, true);
3116  
3117 -       b43_nphy_pa_override(dev, false);
3118 -       b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX);
3119 -       b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
3120 -       b43_nphy_pa_override(dev, true);
3121 +       if (phy->rev < 7) {
3122 +               b43_nphy_pa_override(dev, false);
3123 +               b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX);
3124 +               b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
3125 +               b43_nphy_pa_override(dev, true);
3126 +       }
3127  
3128         b43_nphy_classifier(dev, 0, 0);
3129         b43_nphy_read_clip_detection(dev, clip);
3130 @@ -5348,7 +6162,7 @@ static int b43_phy_initn(struct b43_wlde
3131         b43_phy_write(dev, B43_NPHY_TXMACDELAY, 0x0320);
3132         if (phy->rev >= 3 && phy->rev <= 6)
3133                 b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x0032);
3134 -       b43_nphy_tx_lp_fbw(dev);
3135 +       b43_nphy_tx_lpf_bw(dev);
3136         if (phy->rev >= 3)
3137                 b43_nphy_spur_workaround(dev);
3138  
3139 @@ -5397,23 +6211,23 @@ static void b43_nphy_channel_setup(struc
3140         struct b43_phy *phy = &dev->phy;
3141         struct b43_phy_n *nphy = dev->phy.n;
3142         int ch = new_channel->hw_value;
3143 -
3144 -       u16 old_band_5ghz;
3145         u16 tmp16;
3146  
3147 -       old_band_5ghz =
3148 -               b43_phy_read(dev, B43_NPHY_BANDCTL) & B43_NPHY_BANDCTL_5GHZ;
3149 -       if (new_channel->band == IEEE80211_BAND_5GHZ && !old_band_5ghz) {
3150 +       if (new_channel->band == IEEE80211_BAND_5GHZ) {
3151                 tmp16 = b43_read16(dev, B43_MMIO_PSM_PHY_HDR);
3152                 b43_write16(dev, B43_MMIO_PSM_PHY_HDR, tmp16 | 4);
3153 -               b43_phy_set(dev, B43_PHY_B_BBCFG, 0xC000);
3154 +               /* Put BPHY in the reset */
3155 +               b43_phy_set(dev, B43_PHY_B_BBCFG,
3156 +                           B43_PHY_B_BBCFG_RSTCCA | B43_PHY_B_BBCFG_RSTRX);
3157                 b43_write16(dev, B43_MMIO_PSM_PHY_HDR, tmp16);
3158                 b43_phy_set(dev, B43_NPHY_BANDCTL, B43_NPHY_BANDCTL_5GHZ);
3159 -       } else if (new_channel->band == IEEE80211_BAND_2GHZ && old_band_5ghz) {
3160 +       } else if (new_channel->band == IEEE80211_BAND_2GHZ) {
3161                 b43_phy_mask(dev, B43_NPHY_BANDCTL, ~B43_NPHY_BANDCTL_5GHZ);
3162                 tmp16 = b43_read16(dev, B43_MMIO_PSM_PHY_HDR);
3163                 b43_write16(dev, B43_MMIO_PSM_PHY_HDR, tmp16 | 4);
3164 -               b43_phy_mask(dev, B43_PHY_B_BBCFG, 0x3FFF);
3165 +               /* Take BPHY out of the reset */
3166 +               b43_phy_mask(dev, B43_PHY_B_BBCFG,
3167 +                            (u16)~(B43_PHY_B_BBCFG_RSTCCA | B43_PHY_B_BBCFG_RSTRX));
3168                 b43_write16(dev, B43_MMIO_PSM_PHY_HDR, tmp16);
3169         }
3170  
3171 @@ -5434,35 +6248,49 @@ static void b43_nphy_channel_setup(struc
3172         if (dev->phy.rev < 3)
3173                 b43_nphy_adjust_lna_gain_table(dev);
3174  
3175 -       b43_nphy_tx_lp_fbw(dev);
3176 +       b43_nphy_tx_lpf_bw(dev);
3177  
3178         if (dev->phy.rev >= 3 &&
3179             dev->phy.n->spur_avoid != B43_SPUR_AVOID_DISABLE) {
3180 -               bool avoid = false;
3181 +               u8 spuravoid = 0;
3182 +
3183                 if (dev->phy.n->spur_avoid == B43_SPUR_AVOID_FORCE) {
3184 -                       avoid = true;
3185 -               } else if (!b43_channel_type_is_40mhz(phy->channel_type)) {
3186 -                       if ((ch >= 5 && ch <= 8) || ch == 13 || ch == 14)
3187 -                               avoid = true;
3188 -               } else { /* 40MHz */
3189 -                       if (nphy->aband_spurwar_en &&
3190 -                           (ch == 38 || ch == 102 || ch == 118))
3191 -                               avoid = dev->dev->chip_id == 0x4716;
3192 -               }
3193 -
3194 -               b43_nphy_pmu_spur_avoid(dev, avoid);
3195 -
3196 -               if (dev->dev->chip_id == 43222 || dev->dev->chip_id == 43224 ||
3197 -                   dev->dev->chip_id == 43225) {
3198 -                       b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW,
3199 -                                   avoid ? 0x5341 : 0x8889);
3200 -                       b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
3201 +                       spuravoid = 1;
3202 +               } else if (phy->rev >= 19) {
3203 +                       /* TODO */
3204 +               } else if (phy->rev >= 18) {
3205 +                       /* TODO */
3206 +               } else if (phy->rev >= 17) {
3207 +                       /* TODO: Off for channels 1-11, but check 12-14! */
3208 +               } else if (phy->rev >= 16) {
3209 +                       /* TODO: Off for 2 GHz, but check 5 GHz! */
3210 +               } else if (phy->rev >= 7) {
3211 +                       if (!b43_is_40mhz(dev)) { /* 20MHz */
3212 +                               if (ch == 13 || ch == 14 || ch == 153)
3213 +                                       spuravoid = 1;
3214 +                       } else { /* 40 MHz */
3215 +                               if (ch == 54)
3216 +                                       spuravoid = 1;
3217 +                       }
3218 +               } else {
3219 +                       if (!b43_is_40mhz(dev)) { /* 20MHz */
3220 +                               if ((ch >= 5 && ch <= 8) || ch == 13 || ch == 14)
3221 +                                       spuravoid = 1;
3222 +                       } else { /* 40MHz */
3223 +                               if (nphy->aband_spurwar_en &&
3224 +                                   (ch == 38 || ch == 102 || ch == 118))
3225 +                                       spuravoid = dev->dev->chip_id == 0x4716;
3226 +                       }
3227                 }
3228  
3229 +               b43_nphy_pmu_spur_avoid(dev, spuravoid);
3230 +
3231 +               b43_mac_switch_freq(dev, spuravoid);
3232 +
3233                 if (dev->phy.rev == 3 || dev->phy.rev == 4)
3234                         ; /* TODO: reset PLL */
3235  
3236 -               if (avoid)
3237 +               if (spuravoid)
3238                         b43_phy_set(dev, B43_NPHY_BBCFG, B43_NPHY_BBCFG_RSTRX);
3239                 else
3240                         b43_phy_mask(dev, B43_NPHY_BBCFG,
3241 @@ -5488,10 +6316,20 @@ static int b43_nphy_set_channel(struct b
3242  
3243         const struct b43_nphy_channeltab_entry_rev2 *tabent_r2 = NULL;
3244         const struct b43_nphy_channeltab_entry_rev3 *tabent_r3 = NULL;
3245 +       const struct b43_nphy_chantabent_rev7 *tabent_r7 = NULL;
3246 +       const struct b43_nphy_chantabent_rev7_2g *tabent_r7_2g = NULL;
3247  
3248         u8 tmp;
3249  
3250 -       if (dev->phy.rev >= 3) {
3251 +       if (phy->rev >= 19) {
3252 +               return -ESRCH;
3253 +               /* TODO */
3254 +       } else if (phy->rev >= 7) {
3255 +               r2057_get_chantabent_rev7(dev, channel->center_freq,
3256 +                                         &tabent_r7, &tabent_r7_2g);
3257 +               if (!tabent_r7 && !tabent_r7_2g)
3258 +                       return -ESRCH;
3259 +       } else if (phy->rev >= 3) {
3260                 tabent_r3 = b43_nphy_get_chantabent_rev3(dev,
3261                                                         channel->center_freq);
3262                 if (!tabent_r3)
3263 @@ -5506,20 +6344,38 @@ static int b43_nphy_set_channel(struct b
3264         /* Channel is set later in common code, but we need to set it on our
3265            own to let this function's subcalls work properly. */
3266         phy->channel = channel->hw_value;
3267 -       phy->channel_freq = channel->center_freq;
3268  
3269 +#if 0
3270         if (b43_channel_type_is_40mhz(phy->channel_type) !=
3271                 b43_channel_type_is_40mhz(channel_type))
3272                 ; /* TODO: BMAC BW Set (channel_type) */
3273 +#endif
3274  
3275 -       if (channel_type == NL80211_CHAN_HT40PLUS)
3276 -               b43_phy_set(dev, B43_NPHY_RXCTL,
3277 -                               B43_NPHY_RXCTL_BSELU20);
3278 -       else if (channel_type == NL80211_CHAN_HT40MINUS)
3279 -               b43_phy_mask(dev, B43_NPHY_RXCTL,
3280 -                               ~B43_NPHY_RXCTL_BSELU20);
3281 +       if (channel_type == NL80211_CHAN_HT40PLUS) {
3282 +               b43_phy_set(dev, B43_NPHY_RXCTL, B43_NPHY_RXCTL_BSELU20);
3283 +               if (phy->rev >= 7)
3284 +                       b43_phy_set(dev, 0x310, 0x8000);
3285 +       } else if (channel_type == NL80211_CHAN_HT40MINUS) {
3286 +               b43_phy_mask(dev, B43_NPHY_RXCTL, ~B43_NPHY_RXCTL_BSELU20);
3287 +               if (phy->rev >= 7)
3288 +                       b43_phy_mask(dev, 0x310, (u16)~0x8000);
3289 +       }
3290  
3291 -       if (dev->phy.rev >= 3) {
3292 +       if (phy->rev >= 19) {
3293 +               /* TODO */
3294 +       } else if (phy->rev >= 7) {
3295 +               const struct b43_phy_n_sfo_cfg *phy_regs = tabent_r7 ?
3296 +                       &(tabent_r7->phy_regs) : &(tabent_r7_2g->phy_regs);
3297 +
3298 +               if (phy->radio_rev <= 4 || phy->radio_rev == 6) {
3299 +                       tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 2 : 0;
3300 +                       b43_radio_maskset(dev, R2057_TIA_CONFIG_CORE0, ~2, tmp);
3301 +                       b43_radio_maskset(dev, R2057_TIA_CONFIG_CORE1, ~2, tmp);
3302 +               }
3303 +
3304 +               b43_radio_2057_setup(dev, tabent_r7, tabent_r7_2g);
3305 +               b43_nphy_channel_setup(dev, phy_regs, channel);
3306 +       } else if (phy->rev >= 3) {
3307                 tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 4 : 0;
3308                 b43_radio_maskset(dev, 0x08, 0xFFFB, tmp);
3309                 b43_radio_2056_setup(dev, tabent_r3);
3310 @@ -5561,7 +6417,6 @@ static void b43_nphy_op_prepare_structs(
3311         nphy->hang_avoid = (phy->rev == 3 || phy->rev == 4);
3312         nphy->spur_avoid = (phy->rev >= 3) ?
3313                                 B43_SPUR_AVOID_AUTO : B43_SPUR_AVOID_DISABLE;
3314 -       nphy->init_por = true;
3315         nphy->gain_boost = true; /* this way we follow wl, assume it is true */
3316         nphy->txrx_chain = 2; /* sth different than 0 and 1 for now */
3317         nphy->phyrxchain = 3; /* to avoid b43_nphy_set_rx_core_state like wl */
3318 @@ -5602,8 +6457,6 @@ static void b43_nphy_op_prepare_structs(
3319                 nphy->ipa2g_on = sprom->fem.ghz2.extpa_gain == 2;
3320                 nphy->ipa5g_on = sprom->fem.ghz5.extpa_gain == 2;
3321         }
3322 -
3323 -       nphy->init_por = true;
3324  }
3325  
3326  static void b43_nphy_op_free(struct b43_wldev *dev)
3327 @@ -5663,7 +6516,7 @@ static void b43_nphy_op_maskset(struct b
3328  static u16 b43_nphy_op_radio_read(struct b43_wldev *dev, u16 reg)
3329  {
3330         /* Register 1 is a 32-bit register. */
3331 -       B43_WARN_ON(reg == 1);
3332 +       B43_WARN_ON(dev->phy.rev < 7 && reg == 1);
3333  
3334         if (dev->phy.rev >= 7)
3335                 reg |= 0x200; /* Radio 0x2057 */
3336 @@ -5677,7 +6530,7 @@ static u16 b43_nphy_op_radio_read(struct
3337  static void b43_nphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
3338  {
3339         /* Register 1 is a 32-bit register. */
3340 -       B43_WARN_ON(reg == 1);
3341 +       B43_WARN_ON(dev->phy.rev < 7 && reg == 1);
3342  
3343         b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
3344         b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
3345 @@ -5687,15 +6540,23 @@ static void b43_nphy_op_radio_write(stru
3346  static void b43_nphy_op_software_rfkill(struct b43_wldev *dev,
3347                                         bool blocked)
3348  {
3349 +       struct b43_phy *phy = &dev->phy;
3350 +
3351         if (b43_read32(dev, B43_MMIO_MACCTL) & B43_MACCTL_ENABLED)
3352                 b43err(dev->wl, "MAC not suspended\n");
3353  
3354         if (blocked) {
3355 -               b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
3356 -                               ~B43_NPHY_RFCTL_CMD_CHIP0PU);
3357 -               if (dev->phy.rev >= 7) {
3358 +               if (phy->rev >= 19) {
3359                         /* TODO */
3360 -               } else if (dev->phy.rev >= 3) {
3361 +               } else if (phy->rev >= 8) {
3362 +                       b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
3363 +                                    ~B43_NPHY_RFCTL_CMD_CHIP0PU);
3364 +               } else if (phy->rev >= 7) {
3365 +                       /* Nothing needed */
3366 +               } else if (phy->rev >= 3) {
3367 +                       b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
3368 +                                    ~B43_NPHY_RFCTL_CMD_CHIP0PU);
3369 +
3370                         b43_radio_mask(dev, 0x09, ~0x2);
3371  
3372                         b43_radio_write(dev, 0x204D, 0);
3373 @@ -5713,11 +6574,15 @@ static void b43_nphy_op_software_rfkill(
3374                         b43_radio_write(dev, 0x3064, 0);
3375                 }
3376         } else {
3377 -               if (dev->phy.rev >= 7) {
3378 -                       b43_radio_2057_init(dev);
3379 +               if (phy->rev >= 19) {
3380 +                       /* TODO */
3381 +               } else if (phy->rev >= 7) {
3382 +                       if (!dev->phy.radio_on)
3383 +                               b43_radio_2057_init(dev);
3384                         b43_switch_channel(dev, dev->phy.channel);
3385 -               } else if (dev->phy.rev >= 3) {
3386 -                       b43_radio_init2056(dev);
3387 +               } else if (phy->rev >= 3) {
3388 +                       if (!dev->phy.radio_on)
3389 +                               b43_radio_init2056(dev);
3390                         b43_switch_channel(dev, dev->phy.channel);
3391                 } else {
3392                         b43_radio_init2055(dev);
3393 @@ -5728,10 +6593,13 @@ static void b43_nphy_op_software_rfkill(
3394  /* http://bcm-v4.sipsolutions.net/802.11/PHY/Anacore */
3395  static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on)
3396  {
3397 +       struct b43_phy *phy = &dev->phy;
3398         u16 override = on ? 0x0 : 0x7FFF;
3399         u16 core = on ? 0xD : 0x00FD;
3400  
3401 -       if (dev->phy.rev >= 3) {
3402 +       if (phy->rev >= 19) {
3403 +               /* TODO */
3404 +       } else if (phy->rev >= 3) {
3405                 if (on) {
3406                         b43_phy_write(dev, B43_NPHY_AFECTL_C1, core);
3407                         b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, override);
3408 --- a/drivers/net/wireless/b43/phy_n.h
3409 +++ b/drivers/net/wireless/b43/phy_n.h
3410 @@ -366,11 +366,13 @@
3411  #define B43_NPHY_TXF_40CO_B1S0                 B43_PHY_N(0x0E5) /* TX filter 40 coeff B1 stage 0 */
3412  #define B43_NPHY_TXF_40CO_B32S1                        B43_PHY_N(0x0E6) /* TX filter 40 coeff B32 stage 1 */
3413  #define B43_NPHY_TXF_40CO_B1S1                 B43_PHY_N(0x0E7) /* TX filter 40 coeff B1 stage 1 */
3414 +#define B43_NPHY_REV3_RFCTL_OVER0              B43_PHY_N(0x0E7)
3415  #define B43_NPHY_TXF_40CO_B32S2                        B43_PHY_N(0x0E8) /* TX filter 40 coeff B32 stage 2 */
3416  #define B43_NPHY_TXF_40CO_B1S2                 B43_PHY_N(0x0E9) /* TX filter 40 coeff B1 stage 2 */
3417  #define B43_NPHY_BIST_STAT2                    B43_PHY_N(0x0EA) /* BIST status 2 */
3418  #define B43_NPHY_BIST_STAT3                    B43_PHY_N(0x0EB) /* BIST status 3 */
3419  #define B43_NPHY_RFCTL_OVER                    B43_PHY_N(0x0EC) /* RF control override */
3420 +#define B43_NPHY_REV3_RFCTL_OVER1              B43_PHY_N(0x0EC)
3421  #define B43_NPHY_MIMOCFG                       B43_PHY_N(0x0ED) /* MIMO config */
3422  #define  B43_NPHY_MIMOCFG_GFMIX                        0x0004 /* Greenfield or mixed mode */
3423  #define  B43_NPHY_MIMOCFG_AUTO                 0x0100 /* Greenfield/mixed mode auto */
3424 @@ -857,7 +859,18 @@
3425  #define B43_NPHY_REV3_C2_CLIP2_GAIN_A          B43_PHY_N(0x2AF)
3426  #define B43_NPHY_REV3_C2_CLIP2_GAIN_B          B43_PHY_N(0x2B0)
3427  
3428 +#define B43_NPHY_REV7_RF_CTL_MISC_REG3         B43_PHY_N(0x340)
3429 +#define B43_NPHY_REV7_RF_CTL_MISC_REG4         B43_PHY_N(0x341)
3430 +#define B43_NPHY_REV7_RF_CTL_OVER3             B43_PHY_N(0x342)
3431 +#define B43_NPHY_REV7_RF_CTL_OVER4             B43_PHY_N(0x343)
3432 +#define B43_NPHY_REV7_RF_CTL_MISC_REG5         B43_PHY_N(0x344)
3433 +#define B43_NPHY_REV7_RF_CTL_MISC_REG6         B43_PHY_N(0x345)
3434 +#define B43_NPHY_REV7_RF_CTL_OVER5             B43_PHY_N(0x346)
3435 +#define B43_NPHY_REV7_RF_CTL_OVER6             B43_PHY_N(0x347)
3436 +
3437  #define B43_PHY_B_BBCFG                                B43_PHY_N_BMODE(0x001) /* BB config */
3438 +#define  B43_PHY_B_BBCFG_RSTCCA                        0x4000 /* Reset CCA */
3439 +#define  B43_PHY_B_BBCFG_RSTRX                 0x8000 /* Reset RX */
3440  #define B43_PHY_B_TEST                         B43_PHY_N_BMODE(0x00A)
3441  
3442  struct b43_wldev;
3443 @@ -931,11 +944,12 @@ struct b43_phy_n {
3444         u16 papd_epsilon_offset[2];
3445         s32 preamble_override;
3446         u32 bb_mult_save;
3447 -       bool init_por;
3448  
3449         bool gain_boost;
3450         bool elna_gain_config;
3451         bool band5g_pwrgain;
3452 +       bool use_int_tx_iq_lo_cal;
3453 +       bool lpf_bw_overrode_for_sample_play;
3454  
3455         u8 mphase_cal_phase_id;
3456         u16 mphase_txcal_cmdidx;
3457 --- a/drivers/net/wireless/b43/tables_nphy.c
3458 +++ b/drivers/net/wireless/b43/tables_nphy.c
3459 @@ -2146,7 +2146,196 @@ static const u16 b43_ntab_antswctl_r3[4]
3460         }
3461  };
3462  
3463 -/* TX gain tables */
3464 +/* static tables, PHY revision >= 7 */
3465 +
3466 +/* Copied from brcmsmac (5.75.11) */
3467 +static const u32 b43_ntab_tmap_r7[] = {
3468 +       0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
3469 +       0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
3470 +       0xf1111110, 0x11111111, 0x11f11111, 0x00000111,
3471 +       0x11000000, 0x1111f111, 0x11111111, 0x111111f1,
3472 +       0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x000aa888,
3473 +       0x88880000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
3474 +       0xa1111110, 0x11111111, 0x11c11111, 0x00000111,
3475 +       0x11000000, 0x1111a111, 0x11111111, 0x111111a1,
3476 +       0xa2222220, 0x22222222, 0x22c22222, 0x00000222,
3477 +       0x22000000, 0x2222a222, 0x22222222, 0x222222a2,
3478 +       0xf1111110, 0x11111111, 0x11f11111, 0x00011111,
3479 +       0x11110000, 0x1111f111, 0x11111111, 0x111111f1,
3480 +       0xa8aa88a0, 0xa88888a8, 0xa8a8a88a, 0x00088aaa,
3481 +       0xaaaa0000, 0xa8a8aa88, 0xa88aaaaa, 0xaaaa8a8a,
3482 +       0xaaa8aaa0, 0x8aaa8aaa, 0xaa8a8a8a, 0x000aaa88,
3483 +       0x8aaa0000, 0xaaa8a888, 0x8aa88a8a, 0x8a88a888,
3484 +       0x08080a00, 0x0a08080a, 0x080a0a08, 0x00080808,
3485 +       0x080a0000, 0x080a0808, 0x080a0808, 0x0a0a0a08,
3486 +       0xa0a0a0a0, 0x80a0a080, 0x8080a0a0, 0x00008080,
3487 +       0x80a00000, 0x80a080a0, 0xa080a0a0, 0x8080a0a0,
3488 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
3489 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
3490 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
3491 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
3492 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
3493 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
3494 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
3495 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
3496 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
3497 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
3498 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
3499 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
3500 +       0x99999000, 0x9b9b99bb, 0x9bb99999, 0x9999b9b9,
3501 +       0x9b99bb90, 0x9bbbbb9b, 0x9b9b9bb9, 0x00000999,
3502 +       0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
3503 +       0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00aaa888,
3504 +       0x22000000, 0x2222b222, 0x22222222, 0x222222b2,
3505 +       0xb2222220, 0x22222222, 0x22d22222, 0x00000222,
3506 +       0x11000000, 0x1111a111, 0x11111111, 0x111111a1,
3507 +       0xa1111110, 0x11111111, 0x11c11111, 0x00000111,
3508 +       0x33000000, 0x3333b333, 0x33333333, 0x333333b3,
3509 +       0xb3333330, 0x33333333, 0x33d33333, 0x00000333,
3510 +       0x22000000, 0x2222a222, 0x22222222, 0x222222a2,
3511 +       0xa2222220, 0x22222222, 0x22c22222, 0x00000222,
3512 +       0x99b99b00, 0x9b9b99bb, 0x9bb99999, 0x9999b9b9,
3513 +       0x9b99bb99, 0x9bbbbb9b, 0x9b9b9bb9, 0x00000999,
3514 +       0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
3515 +       0x8a88aa88, 0x8aaaaa8a, 0x8a8a8aa8, 0x08aaa888,
3516 +       0x22222200, 0x2222f222, 0x22222222, 0x222222f2,
3517 +       0x22222222, 0x22222222, 0x22f22222, 0x00000222,
3518 +       0x11000000, 0x1111f111, 0x11111111, 0x11111111,
3519 +       0xf1111111, 0x11111111, 0x11f11111, 0x01111111,
3520 +       0xbb9bb900, 0xb9b9bb99, 0xb99bbbbb, 0xbbbb9b9b,
3521 +       0xb9bb99bb, 0xb99999b9, 0xb9b9b99b, 0x00000bbb,
3522 +       0xaa000000, 0xa8a8aa88, 0xa88aaaaa, 0xaaaa8a8a,
3523 +       0xa8aa88aa, 0xa88888a8, 0xa8a8a88a, 0x0a888aaa,
3524 +       0xaa000000, 0xa8a8aa88, 0xa88aaaaa, 0xaaaa8a8a,
3525 +       0xa8aa88a0, 0xa88888a8, 0xa8a8a88a, 0x00000aaa,
3526 +       0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
3527 +       0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
3528 +       0xbbbbbb00, 0x999bbbbb, 0x9bb99b9b, 0xb9b9b9bb,
3529 +       0xb9b99bbb, 0xb9b9b9bb, 0xb9bb9b99, 0x00000999,
3530 +       0x8a000000, 0xaa88a888, 0xa88888aa, 0xa88a8a88,
3531 +       0xa88aa88a, 0x88a8aaaa, 0xa8aa8aaa, 0x0888a88a,
3532 +       0x0b0b0b00, 0x090b0b0b, 0x0b090b0b, 0x0909090b,
3533 +       0x09090b0b, 0x09090b0b, 0x09090b09, 0x00000909,
3534 +       0x0a000000, 0x0a080808, 0x080a080a, 0x080a0a08,
3535 +       0x080a080a, 0x0808080a, 0x0a0a0a08, 0x0808080a,
3536 +       0xb0b0b000, 0x9090b0b0, 0x90b09090, 0xb0b0b090,
3537 +       0xb0b090b0, 0x90b0b0b0, 0xb0b09090, 0x00000090,
3538 +       0x80000000, 0xa080a080, 0xa08080a0, 0xa0808080,
3539 +       0xa080a080, 0x80a0a0a0, 0xa0a080a0, 0x00a0a0a0,
3540 +       0x22000000, 0x2222f222, 0x22222222, 0x222222f2,
3541 +       0xf2222220, 0x22222222, 0x22f22222, 0x00000222,
3542 +       0x11000000, 0x1111f111, 0x11111111, 0x111111f1,
3543 +       0xf1111110, 0x11111111, 0x11f11111, 0x00000111,
3544 +       0x33000000, 0x3333f333, 0x33333333, 0x333333f3,
3545 +       0xf3333330, 0x33333333, 0x33f33333, 0x00000333,
3546 +       0x22000000, 0x2222f222, 0x22222222, 0x222222f2,
3547 +       0xf2222220, 0x22222222, 0x22f22222, 0x00000222,
3548 +       0x99000000, 0x9b9b99bb, 0x9bb99999, 0x9999b9b9,
3549 +       0x9b99bb90, 0x9bbbbb9b, 0x9b9b9bb9, 0x00000999,
3550 +       0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
3551 +       0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
3552 +       0x88888000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
3553 +       0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
3554 +       0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
3555 +       0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00aaa888,
3556 +       0x88a88a00, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
3557 +       0x8a88aa88, 0x8aaaaa8a, 0x8a8a8aa8, 0x000aa888,
3558 +       0x88880000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
3559 +       0x8a88aa88, 0x8aaaaa8a, 0x8a8a8aa8, 0x08aaa888,
3560 +       0x11000000, 0x1111a111, 0x11111111, 0x111111a1,
3561 +       0xa1111110, 0x11111111, 0x11c11111, 0x00000111,
3562 +       0x11000000, 0x1111a111, 0x11111111, 0x111111a1,
3563 +       0xa1111110, 0x11111111, 0x11c11111, 0x00000111,
3564 +       0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
3565 +       0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
3566 +       0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
3567 +       0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
3568 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
3569 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
3570 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
3571 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
3572 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
3573 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
3574 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
3575 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
3576 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
3577 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
3578 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
3579 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
3580 +};
3581 +
3582 +/* Extracted from MMIO dump of 6.30.223.141 */
3583 +static const u32 b43_ntab_noisevar_r7[] = {
3584 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3585 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3586 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3587 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3588 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3589 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3590 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3591 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3592 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3593 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3594 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3595 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3596 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3597 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3598 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3599 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3600 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3601 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3602 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3603 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3604 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3605 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3606 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3607 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3608 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3609 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3610 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3611 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3612 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3613 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3614 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3615 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3616 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3617 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3618 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3619 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3620 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3621 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3622 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3623 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3624 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3625 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3626 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3627 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3628 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3629 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3630 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3631 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3632 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3633 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3634 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3635 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3636 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3637 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3638 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3639 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
3640 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
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 +};
3649 +
3650 +/**************************************************
3651 + * TX gain tables
3652 + **************************************************/
3653 +
3654  static const u32 b43_ntab_tx_gain_rev0_1_2[] = {
3655         0x03cc2b44, 0x03cc2b42, 0x03cc2a44, 0x03cc2a42,
3656         0x03cc2944, 0x03c82b44, 0x03c82b42, 0x03c82a44,
3657 @@ -2182,7 +2371,9 @@ static const u32 b43_ntab_tx_gain_rev0_1
3658         0x03801442, 0x03801344, 0x03801342, 0x00002b00,
3659  };
3660  
3661 -static const u32 b43_ntab_tx_gain_rev3plus_2ghz[] = {
3662 +/* EPA 2 GHz */
3663 +
3664 +static const u32 b43_ntab_tx_gain_epa_rev3_2g[] = {
3665         0x1f410044, 0x1f410042, 0x1f410040, 0x1f41003e,
3666         0x1f41003c, 0x1f41003b, 0x1f410039, 0x1f410037,
3667         0x1e410044, 0x1e410042, 0x1e410040, 0x1e41003e,
3668 @@ -2217,7 +2408,44 @@ static const u32 b43_ntab_tx_gain_rev3pl
3669         0x1041003c, 0x1041003b, 0x10410039, 0x10410037,
3670  };
3671  
3672 -static const u32 b43_ntab_tx_gain_rev3_5ghz[] = {
3673 +static const u32 b43_ntab_tx_gain_epa_rev3_hi_pwr_2g[] = {
3674 +       0x0f410044, 0x0f410042, 0x0f410040, 0x0f41003e,
3675 +       0x0f41003c, 0x0f41003b, 0x0f410039, 0x0f410037,
3676 +       0x0e410044, 0x0e410042, 0x0e410040, 0x0e41003e,
3677 +       0x0e41003c, 0x0e41003b, 0x0e410039, 0x0e410037,
3678 +       0x0d410044, 0x0d410042, 0x0d410040, 0x0d41003e,
3679 +       0x0d41003c, 0x0d41003b, 0x0d410039, 0x0d410037,
3680 +       0x0c410044, 0x0c410042, 0x0c410040, 0x0c41003e,
3681 +       0x0c41003c, 0x0c41003b, 0x0c410039, 0x0c410037,
3682 +       0x0b410044, 0x0b410042, 0x0b410040, 0x0b41003e,
3683 +       0x0b41003c, 0x0b41003b, 0x0b410039, 0x0b410037,
3684 +       0x0a410044, 0x0a410042, 0x0a410040, 0x0a41003e,
3685 +       0x0a41003c, 0x0a41003b, 0x0a410039, 0x0a410037,
3686 +       0x09410044, 0x09410042, 0x09410040, 0x0941003e,
3687 +       0x0941003c, 0x0941003b, 0x09410039, 0x09410037,
3688 +       0x08410044, 0x08410042, 0x08410040, 0x0841003e,
3689 +       0x0841003c, 0x0841003b, 0x08410039, 0x08410037,
3690 +       0x07410044, 0x07410042, 0x07410040, 0x0741003e,
3691 +       0x0741003c, 0x0741003b, 0x07410039, 0x07410037,
3692 +       0x06410044, 0x06410042, 0x06410040, 0x0641003e,
3693 +       0x0641003c, 0x0641003b, 0x06410039, 0x06410037,
3694 +       0x05410044, 0x05410042, 0x05410040, 0x0541003e,
3695 +       0x0541003c, 0x0541003b, 0x05410039, 0x05410037,
3696 +       0x04410044, 0x04410042, 0x04410040, 0x0441003e,
3697 +       0x0441003c, 0x0441003b, 0x04410039, 0x04410037,
3698 +       0x03410044, 0x03410042, 0x03410040, 0x0341003e,
3699 +       0x0341003c, 0x0341003b, 0x03410039, 0x03410037,
3700 +       0x02410044, 0x02410042, 0x02410040, 0x0241003e,
3701 +       0x0241003c, 0x0241003b, 0x02410039, 0x02410037,
3702 +       0x01410044, 0x01410042, 0x01410040, 0x0141003e,
3703 +       0x0141003c, 0x0141003b, 0x01410039, 0x01410037,
3704 +       0x00410044, 0x00410042, 0x00410040, 0x0041003e,
3705 +       0x0041003c, 0x0041003b, 0x00410039, 0x00410037
3706 +};
3707 +
3708 +/* EPA 5 GHz */
3709 +
3710 +static const u32 b43_ntab_tx_gain_epa_rev3_5g[] = {
3711         0xcff70044, 0xcff70042, 0xcff70040, 0xcff7003e,
3712         0xcff7003c, 0xcff7003b, 0xcff70039, 0xcff70037,
3713         0xcef70044, 0xcef70042, 0xcef70040, 0xcef7003e,
3714 @@ -2252,7 +2480,7 @@ static const u32 b43_ntab_tx_gain_rev3_5
3715         0xc0f7003c, 0xc0f7003b, 0xc0f70039, 0xc0f70037,
3716  };
3717  
3718 -static const u32 b43_ntab_tx_gain_rev4_5ghz[] = {
3719 +static const u32 b43_ntab_tx_gain_epa_rev4_5g[] = {
3720         0x2ff20044, 0x2ff20042, 0x2ff20040, 0x2ff2003e,
3721         0x2ff2003c, 0x2ff2003b, 0x2ff20039, 0x2ff20037,
3722         0x2ef20044, 0x2ef20042, 0x2ef20040, 0x2ef2003e,
3723 @@ -2287,7 +2515,42 @@ static const u32 b43_ntab_tx_gain_rev4_5
3724         0x20d2003a, 0x20d20038, 0x20d20036, 0x20d20034,
3725  };
3726  
3727 -static const u32 b43_ntab_tx_gain_rev5plus_5ghz[] = {
3728 +static const u32 b43_ntab_tx_gain_epa_rev4_hi_pwr_5g[] = {
3729 +       0x2ff10044, 0x2ff10042, 0x2ff10040, 0x2ff1003e,
3730 +       0x2ff1003c, 0x2ff1003b, 0x2ff10039, 0x2ff10037,
3731 +       0x2ef10044, 0x2ef10042, 0x2ef10040, 0x2ef1003e,
3732 +       0x2ef1003c, 0x2ef1003b, 0x2ef10039, 0x2ef10037,
3733 +       0x2df10044, 0x2df10042, 0x2df10040, 0x2df1003e,
3734 +       0x2df1003c, 0x2df1003b, 0x2df10039, 0x2df10037,
3735 +       0x2cf10044, 0x2cf10042, 0x2cf10040, 0x2cf1003e,
3736 +       0x2cf1003c, 0x2cf1003b, 0x2cf10039, 0x2cf10037,
3737 +       0x2bf10044, 0x2bf10042, 0x2bf10040, 0x2bf1003e,
3738 +       0x2bf1003c, 0x2bf1003b, 0x2bf10039, 0x2bf10037,
3739 +       0x2af10044, 0x2af10042, 0x2af10040, 0x2af1003e,
3740 +       0x2af1003c, 0x2af1003b, 0x2af10039, 0x2af10037,
3741 +       0x29f10044, 0x29f10042, 0x29f10040, 0x29f1003e,
3742 +       0x29f1003c, 0x29f1003b, 0x29f10039, 0x29f10037,
3743 +       0x28f10044, 0x28f10042, 0x28f10040, 0x28f1003e,
3744 +       0x28f1003c, 0x28f1003b, 0x28f10039, 0x28f10037,
3745 +       0x27f10044, 0x27f10042, 0x27f10040, 0x27f1003e,
3746 +       0x27f1003c, 0x27f1003b, 0x27f10039, 0x27f10037,
3747 +       0x26f10044, 0x26f10042, 0x26f10040, 0x26f1003e,
3748 +       0x26f1003c, 0x26f1003b, 0x26f10039, 0x26f10037,
3749 +       0x25f10044, 0x25f10042, 0x25f10040, 0x25f1003e,
3750 +       0x25f1003c, 0x25f1003b, 0x25f10039, 0x25f10037,
3751 +       0x24f10044, 0x24f10042, 0x24f10040, 0x24f1003e,
3752 +       0x24f1003c, 0x24f1003b, 0x24f10039, 0x24f10038,
3753 +       0x23f10041, 0x23f10040, 0x23f1003f, 0x23f1003e,
3754 +       0x23f1003c, 0x23f1003b, 0x23f10039, 0x23f10037,
3755 +       0x22f10044, 0x22f10042, 0x22f10040, 0x22f1003e,
3756 +       0x22f1003c, 0x22f1003b, 0x22f10039, 0x22f10037,
3757 +       0x21f10044, 0x21f10042, 0x21f10040, 0x21f1003e,
3758 +       0x21f1003c, 0x21f1003b, 0x21f10039, 0x21f10037,
3759 +       0x20d10043, 0x20d10041, 0x20d1003e, 0x20d1003c,
3760 +       0x20d1003a, 0x20d10038, 0x20d10036, 0x20d10034
3761 +};
3762 +
3763 +static const u32 b43_ntab_tx_gain_epa_rev5_5g[] = {
3764         0x0f62004a, 0x0f620048, 0x0f620046, 0x0f620044,
3765         0x0f620042, 0x0f620040, 0x0f62003e, 0x0f62003c,
3766         0x0e620044, 0x0e620042, 0x0e620040, 0x0e62003e,
3767 @@ -2322,7 +2585,9 @@ static const u32 b43_ntab_tx_gain_rev5pl
3768         0x0062003b, 0x00620039, 0x00620037, 0x00620035,
3769  };
3770  
3771 -static const u32 txpwrctrl_tx_gain_ipa[] = {
3772 +/* IPA 2 GHz */
3773 +
3774 +static const u32 b43_ntab_tx_gain_ipa_rev3_2g[] = {
3775         0x5ff7002d, 0x5ff7002b, 0x5ff7002a, 0x5ff70029,
3776         0x5ff70028, 0x5ff70027, 0x5ff70026, 0x5ff70025,
3777         0x5ef7002d, 0x5ef7002b, 0x5ef7002a, 0x5ef70029,
3778 @@ -2357,7 +2622,7 @@ static const u32 txpwrctrl_tx_gain_ipa[]
3779         0x50f70028, 0x50f70027, 0x50f70026, 0x50f70025,
3780  };
3781  
3782 -static const u32 txpwrctrl_tx_gain_ipa_rev5[] = {
3783 +static const u32 b43_ntab_tx_gain_ipa_rev5_2g[] = {
3784         0x1ff7002d, 0x1ff7002b, 0x1ff7002a, 0x1ff70029,
3785         0x1ff70028, 0x1ff70027, 0x1ff70026, 0x1ff70025,
3786         0x1ef7002d, 0x1ef7002b, 0x1ef7002a, 0x1ef70029,
3787 @@ -2392,7 +2657,7 @@ static const u32 txpwrctrl_tx_gain_ipa_r
3788         0x10f70028, 0x10f70027, 0x10f70026, 0x10f70025,
3789  };
3790  
3791 -static const u32 txpwrctrl_tx_gain_ipa_rev6[] = {
3792 +static const u32 b43_ntab_tx_gain_ipa_rev6_2g[] = {
3793         0x0ff7002d, 0x0ff7002b, 0x0ff7002a, 0x0ff70029,
3794         0x0ff70028, 0x0ff70027, 0x0ff70026, 0x0ff70025,
3795         0x0ef7002d, 0x0ef7002b, 0x0ef7002a, 0x0ef70029,
3796 @@ -2427,7 +2692,117 @@ static const u32 txpwrctrl_tx_gain_ipa_r
3797         0x00f70028, 0x00f70027, 0x00f70026, 0x00f70025,
3798  };
3799  
3800 -static const u32 txpwrctrl_tx_gain_ipa_5g[] = {
3801 +/* Copied from brcmsmac (5.75.11): nphy_tpc_txgain_ipa_2g_2057rev5 */
3802 +static const u32 b43_ntab_tx_gain_ipa_2057_rev5_2g[] = {
3803 +       0x30ff0031, 0x30e70031, 0x30e7002e, 0x30cf002e,
3804 +       0x30bf002e, 0x30af002e, 0x309f002f, 0x307f0033,
3805 +       0x307f0031, 0x307f002e, 0x3077002e, 0x306f002e,
3806 +       0x3067002e, 0x305f002f, 0x30570030, 0x3057002d,
3807 +       0x304f002e, 0x30470031, 0x3047002e, 0x3047002c,
3808 +       0x30470029, 0x303f002c, 0x303f0029, 0x3037002d,
3809 +       0x3037002a, 0x30370028, 0x302f002c, 0x302f002a,
3810 +       0x302f0028, 0x302f0026, 0x3027002c, 0x30270029,
3811 +       0x30270027, 0x30270025, 0x30270023, 0x301f002c,
3812 +       0x301f002a, 0x301f0028, 0x301f0025, 0x301f0024,
3813 +       0x301f0022, 0x301f001f, 0x3017002d, 0x3017002b,
3814 +       0x30170028, 0x30170026, 0x30170024, 0x30170022,
3815 +       0x30170020, 0x3017001e, 0x3017001d, 0x3017001b,
3816 +       0x3017001a, 0x30170018, 0x30170017, 0x30170015,
3817 +       0x300f002c, 0x300f0029, 0x300f0027, 0x300f0024,
3818 +       0x300f0022, 0x300f0021, 0x300f001f, 0x300f001d,
3819 +       0x300f001b, 0x300f001a, 0x300f0018, 0x300f0017,
3820 +       0x300f0016, 0x300f0015, 0x300f0115, 0x300f0215,
3821 +       0x300f0315, 0x300f0415, 0x300f0515, 0x300f0615,
3822 +       0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3823 +       0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3824 +       0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3825 +       0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3826 +       0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3827 +       0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3828 +       0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3829 +       0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3830 +       0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3831 +       0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3832 +       0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3833 +       0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3834 +       0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3835 +};
3836 +
3837 +/* Extracted from MMIO dump of 6.30.223.141 */
3838 +static const u32 b43_ntab_tx_gain_ipa_2057_rev9_2g[] = {
3839 +       0x60ff0031, 0x60e7002c, 0x60cf002a, 0x60c70029,
3840 +       0x60b70029, 0x60a70029, 0x609f002a, 0x6097002b,
3841 +       0x6087002e, 0x60770031, 0x606f0032, 0x60670034,
3842 +       0x60670031, 0x605f0033, 0x605f0031, 0x60570033,
3843 +       0x60570030, 0x6057002d, 0x6057002b, 0x604f002d,
3844 +       0x604f002b, 0x604f0029, 0x604f0026, 0x60470029,
3845 +       0x60470027, 0x603f0029, 0x603f0027, 0x603f0025,
3846 +       0x60370029, 0x60370027, 0x60370024, 0x602f002a,
3847 +       0x602f0028, 0x602f0026, 0x602f0024, 0x6027002a,
3848 +       0x60270028, 0x60270026, 0x60270024, 0x60270022,
3849 +       0x601f002b, 0x601f0029, 0x601f0027, 0x601f0024,
3850 +       0x601f0022, 0x601f0020, 0x601f001f, 0x601f001d,
3851 +       0x60170029, 0x60170027, 0x60170025, 0x60170023,
3852 +       0x60170021, 0x6017001f, 0x6017001d, 0x6017001c,
3853 +       0x6017001a, 0x60170018, 0x60170018, 0x60170016,
3854 +       0x60170015, 0x600f0029, 0x600f0027, 0x600f0025,
3855 +       0x600f0023, 0x600f0021, 0x600f001f, 0x600f001d,
3856 +       0x600f001c, 0x600f001a, 0x600f0019, 0x600f0018,
3857 +       0x600f0016, 0x600f0015, 0x600f0115, 0x600f0215,
3858 +       0x600f0315, 0x600f0415, 0x600f0515, 0x600f0615,
3859 +       0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
3860 +       0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
3861 +       0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
3862 +       0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
3863 +       0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
3864 +       0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
3865 +       0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
3866 +       0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
3867 +       0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
3868 +       0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
3869 +       0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
3870 +       0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
3871 +};
3872 +
3873 +/* Extracted from MMIO dump of 6.30.223.248 */
3874 +static const u32 b43_ntab_tx_gain_ipa_2057_rev14_2g[] = {
3875 +       0x50df002e, 0x50cf002d, 0x50bf002c, 0x50b7002b,
3876 +       0x50af002a, 0x50a70029, 0x509f0029, 0x50970028,
3877 +       0x508f0027, 0x50870027, 0x507f0027, 0x50770027,
3878 +       0x506f0027, 0x50670027, 0x505f0028, 0x50570029,
3879 +       0x504f002b, 0x5047002e, 0x5047002b, 0x50470029,
3880 +       0x503f002c, 0x503f0029, 0x5037002c, 0x5037002a,
3881 +       0x50370028, 0x502f002d, 0x502f002b, 0x502f0028,
3882 +       0x502f0026, 0x5027002d, 0x5027002a, 0x50270028,
3883 +       0x50270026, 0x50270024, 0x501f002e, 0x501f002b,
3884 +       0x501f0029, 0x501f0027, 0x501f0024, 0x501f0022,
3885 +       0x501f0020, 0x501f001f, 0x5017002c, 0x50170029,
3886 +       0x50170027, 0x50170024, 0x50170022, 0x50170021,
3887 +       0x5017001f, 0x5017001d, 0x5017001b, 0x5017001a,
3888 +       0x50170018, 0x50170017, 0x50170015, 0x500f002c,
3889 +       0x500f002a, 0x500f0027, 0x500f0025, 0x500f0023,
3890 +       0x500f0022, 0x500f001f, 0x500f001e, 0x500f001c,
3891 +       0x500f001a, 0x500f0019, 0x500f0018, 0x500f0016,
3892 +       0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
3893 +       0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
3894 +       0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
3895 +       0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
3896 +       0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
3897 +       0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
3898 +       0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
3899 +       0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
3900 +       0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
3901 +       0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
3902 +       0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
3903 +       0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
3904 +       0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
3905 +       0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
3906 +       0x500f0015, 0x500f0015, 0x500f0015, 0x500f0015,
3907 +};
3908 +
3909 +/* IPA 2 5Hz */
3910 +
3911 +static const u32 b43_ntab_tx_gain_ipa_rev3_5g[] = {
3912         0x7ff70035, 0x7ff70033, 0x7ff70032, 0x7ff70031,
3913         0x7ff7002f, 0x7ff7002e, 0x7ff7002d, 0x7ff7002b,
3914         0x7ff7002a, 0x7ff70029, 0x7ff70028, 0x7ff70027,
3915 @@ -2462,6 +2837,42 @@ static const u32 txpwrctrl_tx_gain_ipa_5
3916         0x70f70021, 0x70f70020, 0x70f70020, 0x70f7001f,
3917  };
3918  
3919 +/* Extracted from MMIO dump of 6.30.223.141 */
3920 +static const u32 b43_ntab_tx_gain_ipa_2057_rev9_5g[] = {
3921 +       0x7f7f0053, 0x7f7f004b, 0x7f7f0044, 0x7f7f003f,
3922 +       0x7f7f0039, 0x7f7f0035, 0x7f7f0032, 0x7f7f0030,
3923 +       0x7f7f002d, 0x7e7f0030, 0x7e7f002d, 0x7d7f0032,
3924 +       0x7d7f002f, 0x7d7f002c, 0x7c7f0032, 0x7c7f0030,
3925 +       0x7c7f002d, 0x7b7f0030, 0x7b7f002e, 0x7b7f002b,
3926 +       0x7a7f0032, 0x7a7f0030, 0x7a7f002d, 0x7a7f002b,
3927 +       0x797f0030, 0x797f002e, 0x797f002b, 0x797f0029,
3928 +       0x787f0030, 0x787f002d, 0x787f002b, 0x777f0032,
3929 +       0x777f0030, 0x777f002d, 0x777f002b, 0x767f0031,
3930 +       0x767f002f, 0x767f002c, 0x767f002a, 0x757f0031,
3931 +       0x757f002f, 0x757f002c, 0x757f002a, 0x747f0030,
3932 +       0x747f002d, 0x747f002b, 0x737f0032, 0x737f002f,
3933 +       0x737f002c, 0x737f002a, 0x727f0030, 0x727f002d,
3934 +       0x727f002b, 0x727f0029, 0x717f0030, 0x717f002d,
3935 +       0x717f002b, 0x707f0031, 0x707f002f, 0x707f002c,
3936 +       0x707f002a, 0x707f0027, 0x707f0025, 0x707f0023,
3937 +       0x707f0021, 0x707f001f, 0x707f001d, 0x707f001c,
3938 +       0x707f001a, 0x707f0019, 0x707f0017, 0x707f0016,
3939 +       0x707f0015, 0x707f0014, 0x707f0012, 0x707f0012,
3940 +       0x707f0011, 0x707f0010, 0x707f000f, 0x707f000e,
3941 +       0x707f000d, 0x707f000d, 0x707f000c, 0x707f000b,
3942 +       0x707f000a, 0x707f000a, 0x707f0009, 0x707f0008,
3943 +       0x707f0008, 0x707f0008, 0x707f0008, 0x707f0007,
3944 +       0x707f0007, 0x707f0006, 0x707f0006, 0x707f0006,
3945 +       0x707f0005, 0x707f0005, 0x707f0005, 0x707f0004,
3946 +       0x707f0004, 0x707f0004, 0x707f0003, 0x707f0003,
3947 +       0x707f0003, 0x707f0003, 0x707f0003, 0x707f0003,
3948 +       0x707f0003, 0x707f0003, 0x707f0003, 0x707f0003,
3949 +       0x707f0002, 0x707f0002, 0x707f0002, 0x707f0002,
3950 +       0x707f0002, 0x707f0002, 0x707f0002, 0x707f0002,
3951 +       0x707f0002, 0x707f0001, 0x707f0001, 0x707f0001,
3952 +       0x707f0001, 0x707f0001, 0x707f0001, 0x707f0001,
3953 +};
3954 +
3955  const s8 b43_ntab_papd_pga_gain_delta_ipa_2g[] = {
3956         -114, -108, -98, -91, -84, -78, -70, -62,
3957         -54, -46, -39, -31, -23, -15, -8, 0
3958 @@ -3031,31 +3442,8 @@ void b43_ntab_write_bulk(struct b43_wlde
3959                 b43_ntab_write_bulk(dev, offset, ARRAY_SIZE(data), data); \
3960         } while (0)
3961  
3962 -static void b43_nphy_tables_init_rev3(struct b43_wldev *dev)
3963 +static void b43_nphy_tables_init_shared_lut(struct b43_wldev *dev)
3964  {
3965 -       struct ssb_sprom *sprom = dev->dev->bus_sprom;
3966 -       u8 antswlut;
3967 -
3968 -       if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
3969 -               antswlut = sprom->fem.ghz5.antswlut;
3970 -       else
3971 -               antswlut = sprom->fem.ghz2.antswlut;
3972 -
3973 -       /* Static tables */
3974 -       ntab_upload(dev, B43_NTAB_FRAMESTRUCT_R3, b43_ntab_framestruct_r3);
3975 -       ntab_upload(dev, B43_NTAB_PILOT_R3, b43_ntab_pilot_r3);
3976 -       ntab_upload(dev, B43_NTAB_TMAP_R3, b43_ntab_tmap_r3);
3977 -       ntab_upload(dev, B43_NTAB_INTLEVEL_R3, b43_ntab_intlevel_r3);
3978 -       ntab_upload(dev, B43_NTAB_TDTRN_R3, b43_ntab_tdtrn_r3);
3979 -       ntab_upload(dev, B43_NTAB_NOISEVAR_R3, b43_ntab_noisevar_r3);
3980 -       ntab_upload(dev, B43_NTAB_MCS_R3, b43_ntab_mcs_r3);
3981 -       ntab_upload(dev, B43_NTAB_TDI20A0_R3, b43_ntab_tdi20a0_r3);
3982 -       ntab_upload(dev, B43_NTAB_TDI20A1_R3, b43_ntab_tdi20a1_r3);
3983 -       ntab_upload(dev, B43_NTAB_TDI40A0_R3, b43_ntab_tdi40a0_r3);
3984 -       ntab_upload(dev, B43_NTAB_TDI40A1_R3, b43_ntab_tdi40a1_r3);
3985 -       ntab_upload(dev, B43_NTAB_PILOTLT_R3, b43_ntab_pilotlt_r3);
3986 -       ntab_upload(dev, B43_NTAB_CHANEST_R3, b43_ntab_channelest_r3);
3987 -       ntab_upload(dev, B43_NTAB_FRAMELT_R3, b43_ntab_framelookup_r3);
3988         ntab_upload(dev, B43_NTAB_C0_ESTPLT_R3, b43_ntab_estimatepowerlt0_r3);
3989         ntab_upload(dev, B43_NTAB_C1_ESTPLT_R3, b43_ntab_estimatepowerlt1_r3);
3990         ntab_upload(dev, B43_NTAB_C0_ADJPLT_R3, b43_ntab_adjustpower0_r3);
3991 @@ -3066,6 +3454,107 @@ static void b43_nphy_tables_init_rev3(st
3992         ntab_upload(dev, B43_NTAB_C1_IQLT_R3, b43_ntab_iqlt1_r3);
3993         ntab_upload(dev, B43_NTAB_C0_LOFEEDTH_R3, b43_ntab_loftlt0_r3);
3994         ntab_upload(dev, B43_NTAB_C1_LOFEEDTH_R3, b43_ntab_loftlt1_r3);
3995 +}
3996 +
3997 +static void b43_nphy_tables_init_rev7_volatile(struct b43_wldev *dev)
3998 +{
3999 +       struct ssb_sprom *sprom = dev->dev->bus_sprom;
4000 +       u8 antswlut;
4001 +       int core, offset, i;
4002 +
4003 +       const int antswlut0_offsets[] = { 0, 4, 8, }; /* Offsets for values */
4004 +       const u8 antswlut0_values[][3] = {
4005 +               { 0x2, 0x12, 0x8 }, /* Core 0 */
4006 +               { 0x2, 0x18, 0x2 }, /* Core 1 */
4007 +       };
4008 +
4009 +       if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
4010 +               antswlut = sprom->fem.ghz5.antswlut;
4011 +       else
4012 +               antswlut = sprom->fem.ghz2.antswlut;
4013 +
4014 +       switch (antswlut) {
4015 +       case 0:
4016 +               for (core = 0; core < 2; core++) {
4017 +                       for (i = 0; i < ARRAY_SIZE(antswlut0_values[0]); i++) {
4018 +                               offset = core ? 0x20 : 0x00;
4019 +                               offset += antswlut0_offsets[i];
4020 +                               b43_ntab_write(dev, B43_NTAB8(9, offset),
4021 +                                              antswlut0_values[core][i]);
4022 +                       }
4023 +               }
4024 +               break;
4025 +       default:
4026 +               b43err(dev->wl, "Unsupported antswlut: %d\n", antswlut);
4027 +               break;
4028 +       }
4029 +}
4030 +
4031 +static void b43_nphy_tables_init_rev16(struct b43_wldev *dev)
4032 +{
4033 +       /* Static tables */
4034 +       if (dev->phy.do_full_init) {
4035 +               ntab_upload(dev, B43_NTAB_NOISEVAR_R7, b43_ntab_noisevar_r7);
4036 +               b43_nphy_tables_init_shared_lut(dev);
4037 +       }
4038 +
4039 +       /* Volatile tables */
4040 +       b43_nphy_tables_init_rev7_volatile(dev);
4041 +}
4042 +
4043 +static void b43_nphy_tables_init_rev7(struct b43_wldev *dev)
4044 +{
4045 +       /* Static tables */
4046 +       if (dev->phy.do_full_init) {
4047 +               ntab_upload(dev, B43_NTAB_FRAMESTRUCT_R3, b43_ntab_framestruct_r3);
4048 +               ntab_upload(dev, B43_NTAB_PILOT_R3, b43_ntab_pilot_r3);
4049 +               ntab_upload(dev, B43_NTAB_TMAP_R7, b43_ntab_tmap_r7);
4050 +               ntab_upload(dev, B43_NTAB_INTLEVEL_R3, b43_ntab_intlevel_r3);
4051 +               ntab_upload(dev, B43_NTAB_TDTRN_R3, b43_ntab_tdtrn_r3);
4052 +               ntab_upload(dev, B43_NTAB_NOISEVAR_R7, b43_ntab_noisevar_r7);
4053 +               ntab_upload(dev, B43_NTAB_MCS_R3, b43_ntab_mcs_r3);
4054 +               ntab_upload(dev, B43_NTAB_TDI20A0_R3, b43_ntab_tdi20a0_r3);
4055 +               ntab_upload(dev, B43_NTAB_TDI20A1_R3, b43_ntab_tdi20a1_r3);
4056 +               ntab_upload(dev, B43_NTAB_TDI40A0_R3, b43_ntab_tdi40a0_r3);
4057 +               ntab_upload(dev, B43_NTAB_TDI40A1_R3, b43_ntab_tdi40a1_r3);
4058 +               ntab_upload(dev, B43_NTAB_PILOTLT_R3, b43_ntab_pilotlt_r3);
4059 +               ntab_upload(dev, B43_NTAB_CHANEST_R3, b43_ntab_channelest_r3);
4060 +               ntab_upload(dev, B43_NTAB_FRAMELT_R3, b43_ntab_framelookup_r3);
4061 +               b43_nphy_tables_init_shared_lut(dev);
4062 +       }
4063 +
4064 +       /* Volatile tables */
4065 +       b43_nphy_tables_init_rev7_volatile(dev);
4066 +}
4067 +
4068 +static void b43_nphy_tables_init_rev3(struct b43_wldev *dev)
4069 +{
4070 +       struct ssb_sprom *sprom = dev->dev->bus_sprom;
4071 +       u8 antswlut;
4072 +
4073 +       if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
4074 +               antswlut = sprom->fem.ghz5.antswlut;
4075 +       else
4076 +               antswlut = sprom->fem.ghz2.antswlut;
4077 +
4078 +       /* Static tables */
4079 +       if (dev->phy.do_full_init) {
4080 +               ntab_upload(dev, B43_NTAB_FRAMESTRUCT_R3, b43_ntab_framestruct_r3);
4081 +               ntab_upload(dev, B43_NTAB_PILOT_R3, b43_ntab_pilot_r3);
4082 +               ntab_upload(dev, B43_NTAB_TMAP_R3, b43_ntab_tmap_r3);
4083 +               ntab_upload(dev, B43_NTAB_INTLEVEL_R3, b43_ntab_intlevel_r3);
4084 +               ntab_upload(dev, B43_NTAB_TDTRN_R3, b43_ntab_tdtrn_r3);
4085 +               ntab_upload(dev, B43_NTAB_NOISEVAR_R3, b43_ntab_noisevar_r3);
4086 +               ntab_upload(dev, B43_NTAB_MCS_R3, b43_ntab_mcs_r3);
4087 +               ntab_upload(dev, B43_NTAB_TDI20A0_R3, b43_ntab_tdi20a0_r3);
4088 +               ntab_upload(dev, B43_NTAB_TDI20A1_R3, b43_ntab_tdi20a1_r3);
4089 +               ntab_upload(dev, B43_NTAB_TDI40A0_R3, b43_ntab_tdi40a0_r3);
4090 +               ntab_upload(dev, B43_NTAB_TDI40A1_R3, b43_ntab_tdi40a1_r3);
4091 +               ntab_upload(dev, B43_NTAB_PILOTLT_R3, b43_ntab_pilotlt_r3);
4092 +               ntab_upload(dev, B43_NTAB_CHANEST_R3, b43_ntab_channelest_r3);
4093 +               ntab_upload(dev, B43_NTAB_FRAMELT_R3, b43_ntab_framelookup_r3);
4094 +               b43_nphy_tables_init_shared_lut(dev);
4095 +       }
4096  
4097         /* Volatile tables */
4098         if (antswlut < ARRAY_SIZE(b43_ntab_antswctl_r3))
4099 @@ -3078,20 +3567,22 @@ static void b43_nphy_tables_init_rev3(st
4100  static void b43_nphy_tables_init_rev0(struct b43_wldev *dev)
4101  {
4102         /* Static tables */
4103 -       ntab_upload(dev, B43_NTAB_FRAMESTRUCT, b43_ntab_framestruct);
4104 -       ntab_upload(dev, B43_NTAB_FRAMELT, b43_ntab_framelookup);
4105 -       ntab_upload(dev, B43_NTAB_TMAP, b43_ntab_tmap);
4106 -       ntab_upload(dev, B43_NTAB_TDTRN, b43_ntab_tdtrn);
4107 -       ntab_upload(dev, B43_NTAB_INTLEVEL, b43_ntab_intlevel);
4108 -       ntab_upload(dev, B43_NTAB_PILOT, b43_ntab_pilot);
4109 -       ntab_upload(dev, B43_NTAB_TDI20A0, b43_ntab_tdi20a0);
4110 -       ntab_upload(dev, B43_NTAB_TDI20A1, b43_ntab_tdi20a1);
4111 -       ntab_upload(dev, B43_NTAB_TDI40A0, b43_ntab_tdi40a0);
4112 -       ntab_upload(dev, B43_NTAB_TDI40A1, b43_ntab_tdi40a1);
4113 -       ntab_upload(dev, B43_NTAB_CHANEST, b43_ntab_channelest);
4114 -       ntab_upload(dev, B43_NTAB_MCS, b43_ntab_mcs);
4115 -       ntab_upload(dev, B43_NTAB_NOISEVAR10, b43_ntab_noisevar10);
4116 -       ntab_upload(dev, B43_NTAB_NOISEVAR11, b43_ntab_noisevar11);
4117 +       if (dev->phy.do_full_init) {
4118 +               ntab_upload(dev, B43_NTAB_FRAMESTRUCT, b43_ntab_framestruct);
4119 +               ntab_upload(dev, B43_NTAB_FRAMELT, b43_ntab_framelookup);
4120 +               ntab_upload(dev, B43_NTAB_TMAP, b43_ntab_tmap);
4121 +               ntab_upload(dev, B43_NTAB_TDTRN, b43_ntab_tdtrn);
4122 +               ntab_upload(dev, B43_NTAB_INTLEVEL, b43_ntab_intlevel);
4123 +               ntab_upload(dev, B43_NTAB_PILOT, b43_ntab_pilot);
4124 +               ntab_upload(dev, B43_NTAB_TDI20A0, b43_ntab_tdi20a0);
4125 +               ntab_upload(dev, B43_NTAB_TDI20A1, b43_ntab_tdi20a1);
4126 +               ntab_upload(dev, B43_NTAB_TDI40A0, b43_ntab_tdi40a0);
4127 +               ntab_upload(dev, B43_NTAB_TDI40A1, b43_ntab_tdi40a1);
4128 +               ntab_upload(dev, B43_NTAB_CHANEST, b43_ntab_channelest);
4129 +               ntab_upload(dev, B43_NTAB_MCS, b43_ntab_mcs);
4130 +               ntab_upload(dev, B43_NTAB_NOISEVAR10, b43_ntab_noisevar10);
4131 +               ntab_upload(dev, B43_NTAB_NOISEVAR11, b43_ntab_noisevar11);
4132 +       }
4133  
4134         /* Volatile tables */
4135         ntab_upload(dev, B43_NTAB_BDI, b43_ntab_bdi);
4136 @@ -3111,7 +3602,11 @@ static void b43_nphy_tables_init_rev0(st
4137  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/InitTables */
4138  void b43_nphy_tables_init(struct b43_wldev *dev)
4139  {
4140 -       if (dev->phy.rev >= 3)
4141 +       if (dev->phy.rev >= 16)
4142 +               b43_nphy_tables_init_rev16(dev);
4143 +       else if (dev->phy.rev >= 7)
4144 +               b43_nphy_tables_init_rev7(dev);
4145 +       else if (dev->phy.rev >= 3)
4146                 b43_nphy_tables_init_rev3(dev);
4147         else
4148                 b43_nphy_tables_init_rev0(dev);
4149 @@ -3120,23 +3615,55 @@ void b43_nphy_tables_init(struct b43_wld
4150  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetIpaGainTbl */
4151  static const u32 *b43_nphy_get_ipa_gain_table(struct b43_wldev *dev)
4152  {
4153 +       struct b43_phy *phy = &dev->phy;
4154 +
4155         if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
4156 -               if (dev->phy.rev >= 6) {
4157 -                       if (dev->dev->chip_id == 47162)
4158 -                               return txpwrctrl_tx_gain_ipa_rev5;
4159 -                       return txpwrctrl_tx_gain_ipa_rev6;
4160 -               } else if (dev->phy.rev >= 5) {
4161 -                       return txpwrctrl_tx_gain_ipa_rev5;
4162 -               } else {
4163 -                       return txpwrctrl_tx_gain_ipa;
4164 +               switch (phy->rev) {
4165 +               case 17:
4166 +                       if (phy->radio_rev == 14)
4167 +                               return b43_ntab_tx_gain_ipa_2057_rev14_2g;
4168 +                       break;
4169 +               case 16:
4170 +                       if (phy->radio_rev == 9)
4171 +                               return b43_ntab_tx_gain_ipa_2057_rev9_2g;
4172 +                       break;
4173 +               case 8:
4174 +                       if (phy->radio_rev == 5)
4175 +                               return b43_ntab_tx_gain_ipa_2057_rev5_2g;
4176 +                       break;
4177 +               case 6:
4178 +                       if (dev->dev->chip_id == BCMA_CHIP_ID_BCM47162)
4179 +                               return b43_ntab_tx_gain_ipa_rev5_2g;
4180 +                       return b43_ntab_tx_gain_ipa_rev6_2g;
4181 +               case 5:
4182 +                       return b43_ntab_tx_gain_ipa_rev5_2g;
4183 +               case 4:
4184 +               case 3:
4185 +                       return b43_ntab_tx_gain_ipa_rev3_2g;
4186                 }
4187 +
4188 +               b43err(dev->wl,
4189 +                      "No 2GHz IPA gain table available for this device\n");
4190 +               return NULL;
4191         } else {
4192 -               return txpwrctrl_tx_gain_ipa_5g;
4193 +               switch (phy->rev) {
4194 +               case 16:
4195 +                       if (phy->radio_rev == 9)
4196 +                               return b43_ntab_tx_gain_ipa_2057_rev9_5g;
4197 +                       break;
4198 +               case 3 ... 6:
4199 +                       return b43_ntab_tx_gain_ipa_rev3_5g;
4200 +               }
4201 +
4202 +               b43err(dev->wl,
4203 +                      "No 5GHz IPA gain table available for this device\n");
4204 +               return NULL;
4205         }
4206  }
4207  
4208  const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev)
4209  {
4210 +       struct b43_phy *phy = &dev->phy;
4211         enum ieee80211_band band = b43_current_band(dev->wl);
4212         struct ssb_sprom *sprom = dev->dev->bus_sprom;
4213  
4214 @@ -3148,19 +3675,36 @@ const u32 *b43_nphy_get_tx_gain_table(st
4215             (dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ)) {
4216                 return b43_nphy_get_ipa_gain_table(dev);
4217         } else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
4218 -               if (dev->phy.rev == 3)
4219 -                       return b43_ntab_tx_gain_rev3_5ghz;
4220 -               if (dev->phy.rev == 4)
4221 +               switch (phy->rev) {
4222 +               case 6:
4223 +               case 5:
4224 +                       return b43_ntab_tx_gain_epa_rev5_5g;
4225 +               case 4:
4226                         return sprom->fem.ghz5.extpa_gain == 3 ?
4227 -                               b43_ntab_tx_gain_rev4_5ghz :
4228 -                               b43_ntab_tx_gain_rev4_5ghz; /* FIXME */
4229 -               else
4230 -                       return b43_ntab_tx_gain_rev5plus_5ghz;
4231 +                               b43_ntab_tx_gain_epa_rev4_5g :
4232 +                               b43_ntab_tx_gain_epa_rev4_hi_pwr_5g;
4233 +               case 3:
4234 +                       return b43_ntab_tx_gain_epa_rev3_5g;
4235 +               default:
4236 +                       b43err(dev->wl,
4237 +                              "No 5GHz EPA gain table available for this device\n");
4238 +                       return NULL;
4239 +               }
4240         } else {
4241 -               if (dev->phy.rev >= 5 && sprom->fem.ghz5.extpa_gain == 3)
4242 -                       return b43_ntab_tx_gain_rev3plus_2ghz; /* FIXME */
4243 -               else
4244 -                       return b43_ntab_tx_gain_rev3plus_2ghz;
4245 +               switch (phy->rev) {
4246 +               case 6:
4247 +               case 5:
4248 +                       if (sprom->fem.ghz5.extpa_gain == 3)
4249 +                               return b43_ntab_tx_gain_epa_rev3_hi_pwr_2g;
4250 +                       /* fall through */
4251 +               case 4:
4252 +               case 3:
4253 +                       return b43_ntab_tx_gain_epa_rev3_2g;
4254 +               default:
4255 +                       b43err(dev->wl,
4256 +                              "No 2GHz EPA gain table available for this device\n");
4257 +                       return NULL;
4258 +               }
4259         }
4260  }
4261  
4262 @@ -3187,7 +3731,7 @@ struct nphy_gain_ctl_workaround_entry *b
4263         /* Some workarounds to the workarounds... */
4264         if (ghz5 && dev->phy.rev >= 6) {
4265                 if (dev->phy.radio_rev == 11 &&
4266 -                   !b43_channel_type_is_40mhz(dev->phy.channel_type))
4267 +                   !b43_is_40mhz(dev))
4268                         e->cliplo_gain = 0x2d;
4269         } else if (!ghz5 && dev->phy.rev >= 5) {
4270                 static const int gain_data[] = {0x0062, 0x0064, 0x006a, 0x106a,
4271 --- a/drivers/net/wireless/b43/Kconfig
4272 +++ b/drivers/net/wireless/b43/Kconfig
4273 @@ -37,7 +37,7 @@ config B43_SSB
4274  choice
4275         prompt "Supported bus types"
4276         depends on B43
4277 -       default B43_BCMA_AND_SSB
4278 +       default B43_BUSES_BCMA_AND_SSB
4279  
4280  config B43_BUSES_BCMA_AND_SSB
4281         bool "BCMA and SSB"
4282 @@ -123,6 +123,15 @@ config B43_PIO
4283         select SSB_BLOCKIO
4284         default y
4285  
4286 +config B43_PHY_G
4287 +       bool "Support for G-PHY (802.11g) devices"
4288 +       depends on B43 && B43_SSB
4289 +       default y
4290 +       ---help---
4291 +         This PHY type can be found in the following chipsets:
4292 +         PCI: BCM4306, BCM4311, BCM4318
4293 +         SoC: BCM4712, BCM5352E
4294 +
4295  config B43_PHY_N
4296         bool "Support for 802.11n (N-PHY) devices"
4297         depends on B43
4298 --- a/drivers/net/wireless/b43/phy_ht.c
4299 +++ b/drivers/net/wireless/b43/phy_ht.c
4300 @@ -596,7 +596,7 @@ static void b43_phy_ht_tx_power_ctl_setu
4301         u8 target[3];
4302         s16 a1[3], b0[3], b1[3];
4303  
4304 -       u16 freq = dev->phy.channel_freq;
4305 +       u16 freq = dev->phy.chandef->chan->center_freq;
4306         int i, c;
4307  
4308         if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
4309 --- a/drivers/net/wireless/b43/phy_a.h
4310 +++ b/drivers/net/wireless/b43/phy_a.h
4311 @@ -123,8 +123,4 @@ struct b43_phy_a {
4312   */
4313  void b43_phy_inita(struct b43_wldev *dev);
4314  
4315 -
4316 -struct b43_phy_operations;
4317 -extern const struct b43_phy_operations b43_phyops_a;
4318 -
4319  #endif /* LINUX_B43_PHY_A_H_ */
4320 --- a/drivers/net/wireless/b43/Makefile
4321 +++ b/drivers/net/wireless/b43/Makefile
4322 @@ -1,13 +1,11 @@
4323  b43-y                          += main.o
4324  b43-y                          += bus.o
4325 -b43-y                          += tables.o
4326 +b43-$(CPTCFG_B43_PHY_G)                += phy_a.o phy_g.o tables.o lo.o wa.o
4327  b43-$(CPTCFG_B43_PHY_N)                += tables_nphy.o
4328  b43-$(CPTCFG_B43_PHY_N)                += radio_2055.o
4329  b43-$(CPTCFG_B43_PHY_N)                += radio_2056.o
4330  b43-$(CPTCFG_B43_PHY_N)                += radio_2057.o
4331  b43-y                          += phy_common.o
4332 -b43-y                          += phy_g.o
4333 -b43-y                          += phy_a.o
4334  b43-$(CPTCFG_B43_PHY_N)                += phy_n.o
4335  b43-$(CPTCFG_B43_PHY_LP)       += phy_lp.o
4336  b43-$(CPTCFG_B43_PHY_LP)       += tables_lpphy.o
4337 @@ -17,8 +15,6 @@ b43-$(CPTCFG_B43_PHY_HT)      += radio_2059.o
4338  b43-$(CPTCFG_B43_PHY_LCN)      += phy_lcn.o tables_phy_lcn.o
4339  b43-y                          += sysfs.o
4340  b43-y                          += xmit.o
4341 -b43-y                          += lo.o
4342 -b43-y                          += wa.o
4343  b43-y                          += dma.o
4344  b43-y                          += pio.o
4345  b43-y                          += rfkill.o
4346 --- a/drivers/net/wireless/b43/phy_a.c
4347 +++ b/drivers/net/wireless/b43/phy_a.c
4348 @@ -573,7 +573,7 @@ static void b43_aphy_op_pwork_60sec(stru
4349  {//TODO
4350  }
4351  
4352 -const struct b43_phy_operations b43_phyops_a = {
4353 +static const struct b43_phy_operations b43_phyops_a = {
4354         .allocate               = b43_aphy_op_allocate,
4355         .free                   = b43_aphy_op_free,
4356         .prepare_structs        = b43_aphy_op_prepare_structs,
4357 --- a/drivers/net/wireless/b43/radio_2057.c
4358 +++ b/drivers/net/wireless/b43/radio_2057.c
4359 @@ -26,7 +26,7 @@
4360  #include "radio_2057.h"
4361  #include "phy_common.h"
4362  
4363 -static u16 r2057_rev4_init[42][2] = {
4364 +static u16 r2057_rev4_init[][2] = {
4365         { 0x0E, 0x20 }, { 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 },
4366         { 0x35, 0x26 }, { 0x3C, 0xff }, { 0x3D, 0xff }, { 0x3E, 0xff },
4367         { 0x3F, 0xff }, { 0x62, 0x33 }, { 0x8A, 0xf0 }, { 0x8B, 0x10 },
4368 @@ -40,7 +40,7 @@ static u16 r2057_rev4_init[42][2] = {
4369         { 0x1AB, 0x00 }, { 0x1AC, 0x00 },
4370  };
4371  
4372 -static u16 r2057_rev5_init[44][2] = {
4373 +static u16 r2057_rev5_init[][2] = {
4374         { 0x00, 0x00 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x23, 0x6 },
4375         { 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 },
4376         { 0x59, 0x88 }, { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f },
4377 @@ -54,7 +54,7 @@ static u16 r2057_rev5_init[44][2] = {
4378         { 0x1AC, 0x00 }, { 0x1B7, 0x0c }, { 0x1C1, 0x01 }, { 0x1C2, 0x80 },
4379  };
4380  
4381 -static u16 r2057_rev5a_init[45][2] = {
4382 +static u16 r2057_rev5a_init[][2] = {
4383         { 0x00, 0x15 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x23, 0x6 },
4384         { 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 },
4385         { 0x59, 0x88 }, { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f },
4386 @@ -69,7 +69,7 @@ static u16 r2057_rev5a_init[45][2] = {
4387         { 0x1C2, 0x80 },
4388  };
4389  
4390 -static u16 r2057_rev7_init[54][2] = {
4391 +static u16 r2057_rev7_init[][2] = {
4392         { 0x00, 0x00 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x31, 0x00 },
4393         { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 }, { 0x59, 0x88 },
4394         { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f }, { 0x64, 0x13 },
4395 @@ -86,7 +86,8 @@ static u16 r2057_rev7_init[54][2] = {
4396         { 0x1B7, 0x05 }, { 0x1C2, 0xa0 },
4397  };
4398  
4399 -static u16 r2057_rev8_init[54][2] = {
4400 +/* TODO: Which devices should use it?
4401 +static u16 r2057_rev8_init[][2] = {
4402         { 0x00, 0x08 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x31, 0x00 },
4403         { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 }, { 0x59, 0x88 },
4404         { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f }, { 0x64, 0x0f },
4405 @@ -102,6 +103,436 @@ static u16 r2057_rev8_init[54][2] = {
4406         { 0x1A6, 0x00 }, { 0x1AA, 0x00 }, { 0x1AB, 0x00 }, { 0x1AC, 0x00 },
4407         { 0x1B7, 0x05 }, { 0x1C2, 0xa0 },
4408  };
4409 +*/
4410 +
4411 +/* Extracted from MMIO dump of 6.30.223.141 */
4412 +static u16 r2057_rev9_init[][2] = {
4413 +       { 0x27, 0x1f }, { 0x28, 0x0a }, { 0x29, 0x2f }, { 0x42, 0x1f },
4414 +       { 0x48, 0x3f }, { 0x5c, 0x41 }, { 0x63, 0x14 }, { 0x64, 0x12 },
4415 +       { 0x66, 0xff }, { 0x74, 0xa3 }, { 0x7b, 0x14 }, { 0x7c, 0x14 },
4416 +       { 0x7d, 0xee }, { 0x86, 0xc0 }, { 0xc4, 0x10 }, { 0xc9, 0x01 },
4417 +       { 0xe1, 0x41 }, { 0xe8, 0x14 }, { 0xe9, 0x12 }, { 0xeb, 0xff },
4418 +       { 0xf5, 0x0a }, { 0xf8, 0x09 }, { 0xf9, 0xa3 }, { 0x100, 0x14 },
4419 +       { 0x101, 0x10 }, { 0x102, 0xee }, { 0x10b, 0xc0 }, { 0x149, 0x10 },
4420 +       { 0x14e, 0x01 }, { 0x1b7, 0x05 }, { 0x1c2, 0xa0 },
4421 +};
4422 +
4423 +/* Extracted from MMIO dump of 6.30.223.248 */
4424 +static u16 r2057_rev14_init[][2] = {
4425 +       { 0x011, 0xfc }, { 0x030, 0x24 }, { 0x040, 0x1c }, { 0x082, 0x08 },
4426 +       { 0x0b4, 0x44 }, { 0x0c8, 0x01 }, { 0x0c9, 0x01 }, { 0x107, 0x08 },
4427 +       { 0x14d, 0x01 }, { 0x14e, 0x01 }, { 0x1af, 0x40 }, { 0x1b0, 0x40 },
4428 +       { 0x1cc, 0x01 }, { 0x1cf, 0x10 }, { 0x1d0, 0x0f }, { 0x1d3, 0x10 },
4429 +       { 0x1d4, 0x0f },
4430 +};
4431 +
4432 +#define RADIOREGS7(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \
4433 +                  r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, \
4434 +                  r20, r21, r22, r23, r24, r25, r26, r27) \
4435 +       .radio_vcocal_countval0                 = r00,  \
4436 +       .radio_vcocal_countval1                 = r01,  \
4437 +       .radio_rfpll_refmaster_sparextalsize    = r02,  \
4438 +       .radio_rfpll_loopfilter_r1              = r03,  \
4439 +       .radio_rfpll_loopfilter_c2              = r04,  \
4440 +       .radio_rfpll_loopfilter_c1              = r05,  \
4441 +       .radio_cp_kpd_idac                      = r06,  \
4442 +       .radio_rfpll_mmd0                       = r07,  \
4443 +       .radio_rfpll_mmd1                       = r08,  \
4444 +       .radio_vcobuf_tune                      = r09,  \
4445 +       .radio_logen_mx2g_tune                  = r10,  \
4446 +       .radio_logen_mx5g_tune                  = r11,  \
4447 +       .radio_logen_indbuf2g_tune              = r12,  \
4448 +       .radio_logen_indbuf5g_tune              = r13,  \
4449 +       .radio_txmix2g_tune_boost_pu_core0      = r14,  \
4450 +       .radio_pad2g_tune_pus_core0             = r15,  \
4451 +       .radio_pga_boost_tune_core0             = r16,  \
4452 +       .radio_txmix5g_boost_tune_core0         = r17,  \
4453 +       .radio_pad5g_tune_misc_pus_core0        = r18,  \
4454 +       .radio_lna2g_tune_core0                 = r19,  \
4455 +       .radio_lna5g_tune_core0                 = r20,  \
4456 +       .radio_txmix2g_tune_boost_pu_core1      = r21,  \
4457 +       .radio_pad2g_tune_pus_core1             = r22,  \
4458 +       .radio_pga_boost_tune_core1             = r23,  \
4459 +       .radio_txmix5g_boost_tune_core1         = r24,  \
4460 +       .radio_pad5g_tune_misc_pus_core1        = r25,  \
4461 +       .radio_lna2g_tune_core1                 = r26,  \
4462 +       .radio_lna5g_tune_core1                 = r27
4463 +
4464 +#define RADIOREGS7_2G(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \
4465 +                     r10, r11, r12, r13, r14, r15, r16, r17) \
4466 +       .radio_vcocal_countval0                 = r00,  \
4467 +       .radio_vcocal_countval1                 = r01,  \
4468 +       .radio_rfpll_refmaster_sparextalsize    = r02,  \
4469 +       .radio_rfpll_loopfilter_r1              = r03,  \
4470 +       .radio_rfpll_loopfilter_c2              = r04,  \
4471 +       .radio_rfpll_loopfilter_c1              = r05,  \
4472 +       .radio_cp_kpd_idac                      = r06,  \
4473 +       .radio_rfpll_mmd0                       = r07,  \
4474 +       .radio_rfpll_mmd1                       = r08,  \
4475 +       .radio_vcobuf_tune                      = r09,  \
4476 +       .radio_logen_mx2g_tune                  = r10,  \
4477 +       .radio_logen_indbuf2g_tune              = r11,  \
4478 +       .radio_txmix2g_tune_boost_pu_core0      = r12,  \
4479 +       .radio_pad2g_tune_pus_core0             = r13,  \
4480 +       .radio_lna2g_tune_core0                 = r14,  \
4481 +       .radio_txmix2g_tune_boost_pu_core1      = r15,  \
4482 +       .radio_pad2g_tune_pus_core1             = r16,  \
4483 +       .radio_lna2g_tune_core1                 = r17
4484 +
4485 +#define PHYREGS(r0, r1, r2, r3, r4, r5)        \
4486 +       .phy_regs.phy_bw1a      = r0,   \
4487 +       .phy_regs.phy_bw2       = r1,   \
4488 +       .phy_regs.phy_bw3       = r2,   \
4489 +       .phy_regs.phy_bw4       = r3,   \
4490 +       .phy_regs.phy_bw5       = r4,   \
4491 +       .phy_regs.phy_bw6       = r5
4492 +
4493 +/* Copied from brcmsmac (5.75.11): chan_info_nphyrev8_2057_rev5 */
4494 +static const struct b43_nphy_chantabent_rev7_2g b43_nphy_chantab_phy_rev8_radio_rev5[] = {
4495 +       {
4496 +               .freq                   = 2412,
4497 +               RADIOREGS7_2G(0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c,
4498 +                             0x09, 0x0d, 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61,
4499 +                             0x03, 0xff),
4500 +               PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
4501 +       },
4502 +       {
4503 +               .freq                   = 2417,
4504 +               RADIOREGS7_2G(0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71,
4505 +                             0x09, 0x0d, 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61,
4506 +                             0x03, 0xff),
4507 +               PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
4508 +       },
4509 +       {
4510 +               .freq                   = 2422,
4511 +               RADIOREGS7_2G(0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76,
4512 +                             0x09, 0x0d, 0x08, 0x0e, 0x61, 0x03, 0xef, 0x61,
4513 +                             0x03, 0xef),
4514 +               PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
4515 +       },
4516 +       {
4517 +               .freq                   = 2427,
4518 +               RADIOREGS7_2G(0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b,
4519 +                             0x09, 0x0c, 0x08, 0x0e, 0x61, 0x03, 0xdf, 0x61,
4520 +                             0x03, 0xdf),
4521 +               PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
4522 +       },
4523 +       {
4524 +               .freq                   = 2432,
4525 +               RADIOREGS7_2G(0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80,
4526 +                             0x09, 0x0c, 0x07, 0x0d, 0x61, 0x03, 0xcf, 0x61,
4527 +                             0x03, 0xcf),
4528 +               PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
4529 +       },
4530 +       {
4531 +               .freq                   = 2437,
4532 +               RADIOREGS7_2G(0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85,
4533 +                             0x09, 0x0c, 0x07, 0x0d, 0x61, 0x03, 0xbf, 0x61,
4534 +                             0x03, 0xbf),
4535 +               PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
4536 +       },
4537 +       {
4538 +               .freq                   = 2442,
4539 +               RADIOREGS7_2G(0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a,
4540 +                             0x09, 0x0b, 0x07, 0x0d, 0x61, 0x03, 0xaf, 0x61,
4541 +                             0x03, 0xaf),
4542 +               PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
4543 +       },
4544 +       {
4545 +               .freq                   = 2447,
4546 +               RADIOREGS7_2G(0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f,
4547 +                             0x09, 0x0b, 0x07, 0x0d, 0x61, 0x03, 0x9f, 0x61,
4548 +                             0x03, 0x9f),
4549 +               PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
4550 +       },
4551 +       {
4552 +               .freq                   = 2452,
4553 +               RADIOREGS7_2G(0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94,
4554 +                             0x09, 0x0b, 0x07, 0x0d, 0x61, 0x03, 0x8f, 0x61,
4555 +                             0x03, 0x8f),
4556 +               PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
4557 +       },
4558 +       {
4559 +               .freq                   = 2457,
4560 +               RADIOREGS7_2G(0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99,
4561 +                             0x09, 0x0b, 0x07, 0x0c, 0x61, 0x03, 0x7f, 0x61,
4562 +                             0x03, 0x7f),
4563 +               PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
4564 +       },
4565 +       {
4566 +               .freq                   = 2462,
4567 +               RADIOREGS7_2G(0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e,
4568 +                             0x09, 0x0b, 0x07, 0x0c, 0x61, 0x03, 0x6f, 0x61,
4569 +                             0x03, 0x6f),
4570 +               PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
4571 +       },
4572 +       {
4573 +               .freq                   = 2467,
4574 +               RADIOREGS7_2G(0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3,
4575 +                             0x09, 0x0b, 0x06, 0x0c, 0x61, 0x03, 0x5f, 0x61,
4576 +                             0x03, 0x5f),
4577 +               PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b),
4578 +       },
4579 +       {
4580 +               .freq                   = 2472,
4581 +               RADIOREGS7_2G(0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8,
4582 +                             0x09, 0x0a, 0x06, 0x0b, 0x61, 0x03, 0x4f, 0x61,
4583 +                             0x03, 0x4f),
4584 +               PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429),
4585 +       },
4586 +       {
4587 +               .freq                   = 2484,
4588 +               RADIOREGS7_2G(0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4,
4589 +                             0x09, 0x0a, 0x06, 0x0b, 0x61, 0x03, 0x3f, 0x61,
4590 +                             0x03, 0x3f),
4591 +               PHYREGS(0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424),
4592 +       }
4593 +};
4594 +
4595 +/* Extracted from MMIO dump of 6.30.223.248 */
4596 +static const struct b43_nphy_chantabent_rev7_2g b43_nphy_chantab_phy_rev17_radio_rev14[] = {
4597 +       {
4598 +               .freq                   = 2412,
4599 +               RADIOREGS7_2G(0x48, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x6c,
4600 +                             0x09, 0x0d, 0x09, 0x03, 0x21, 0x53, 0xff, 0x21,
4601 +                             0x53, 0xff),
4602 +               PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
4603 +       },
4604 +       {
4605 +               .freq                   = 2417,
4606 +               RADIOREGS7_2G(0x4b, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x71,
4607 +                             0x09, 0x0d, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
4608 +                             0x53, 0xff),
4609 +               PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
4610 +       },
4611 +       {
4612 +               .freq                   = 2422,
4613 +               RADIOREGS7_2G(0x4e, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x76,
4614 +                             0x09, 0x0d, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
4615 +                             0x53, 0xff),
4616 +               PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
4617 +       },
4618 +       {
4619 +               .freq                   = 2427,
4620 +               RADIOREGS7_2G(0x52, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x7b,
4621 +                             0x09, 0x0c, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
4622 +                             0x53, 0xff),
4623 +               PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
4624 +       },
4625 +       {
4626 +               .freq                   = 2432,
4627 +               RADIOREGS7_2G(0x55, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x80,
4628 +                             0x09, 0x0c, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
4629 +                             0x53, 0xff),
4630 +               PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
4631 +       },
4632 +       {
4633 +               .freq                   = 2437,
4634 +               RADIOREGS7_2G(0x58, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x85,
4635 +                             0x09, 0x0c, 0x08, 0x03, 0x21, 0x53, 0xff, 0x21,
4636 +                             0x53, 0xff),
4637 +               PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
4638 +       },
4639 +       {
4640 +               .freq                   = 2442,
4641 +               RADIOREGS7_2G(0x5c, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x8a,
4642 +                             0x09, 0x0c, 0x08, 0x03, 0x21, 0x43, 0xff, 0x21,
4643 +                             0x43, 0xff),
4644 +               PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
4645 +       },
4646 +       {
4647 +               .freq                   = 2447,
4648 +               RADIOREGS7_2G(0x5f, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x8f,
4649 +                             0x09, 0x0c, 0x08, 0x03, 0x21, 0x43, 0xff, 0x21,
4650 +                             0x43, 0xff),
4651 +               PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
4652 +       },
4653 +       {
4654 +               .freq                   = 2452,
4655 +               RADIOREGS7_2G(0x62, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x94,
4656 +                             0x09, 0x0c, 0x08, 0x03, 0x21, 0x43, 0xff, 0x21,
4657 +                             0x43, 0xff),
4658 +               PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
4659 +       },
4660 +       {
4661 +               .freq                   = 2457,
4662 +               RADIOREGS7_2G(0x66, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x99,
4663 +                             0x09, 0x0b, 0x07, 0x03, 0x21, 0x43, 0xff, 0x21,
4664 +                             0x43, 0xff),
4665 +               PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
4666 +       },
4667 +       {
4668 +               .freq                   = 2462,
4669 +               RADIOREGS7_2G(0x69, 0x16, 0x30, 0x2b, 0x1f, 0x1f, 0x30, 0x9e,
4670 +                             0x09, 0x0b, 0x07, 0x03, 0x01, 0x43, 0xff, 0x01,
4671 +                             0x43, 0xff),
4672 +               PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
4673 +       },
4674 +};
4675 +
4676 +/* Extracted from MMIO dump of 6.30.223.141 */
4677 +static const struct b43_nphy_chantabent_rev7 b43_nphy_chantab_phy_rev16_radio_rev9[] = {
4678 +       {
4679 +               .freq                   = 2412,
4680 +               RADIOREGS7(0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c,
4681 +                          0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x41, 0x63,
4682 +                          0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
4683 +                          0x00, 0x00, 0xf0, 0x00),
4684 +               PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
4685 +       },
4686 +       {
4687 +               .freq                   = 2417,
4688 +               RADIOREGS7(0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71,
4689 +                          0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x41, 0x63,
4690 +                          0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
4691 +                          0x00, 0x00, 0xf0, 0x00),
4692 +               PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
4693 +       },
4694 +       {
4695 +               .freq                   = 2422,
4696 +               RADIOREGS7(0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76,
4697 +                          0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x41, 0x63,
4698 +                          0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
4699 +                          0x00, 0x00, 0xf0, 0x00),
4700 +               PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
4701 +       },
4702 +       {
4703 +               .freq                   = 2427,
4704 +               RADIOREGS7(0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b,
4705 +                          0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x41, 0x63,
4706 +                          0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
4707 +                          0x00, 0x00, 0xf0, 0x00),
4708 +               PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
4709 +       },
4710 +       {
4711 +               .freq                   = 2432,
4712 +               RADIOREGS7(0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80,
4713 +                          0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x41, 0x63,
4714 +                          0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
4715 +                          0x00, 0x00, 0xf0, 0x00),
4716 +               PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
4717 +       },
4718 +       {
4719 +               .freq                   = 2437,
4720 +               RADIOREGS7(0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85,
4721 +                          0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x41, 0x63,
4722 +                          0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
4723 +                          0x00, 0x00, 0xf0, 0x00),
4724 +               PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
4725 +       },
4726 +       {
4727 +               .freq                   = 2442,
4728 +               RADIOREGS7(0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a,
4729 +                          0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x41, 0x63,
4730 +                          0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
4731 +                          0x00, 0x00, 0xf0, 0x00),
4732 +               PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
4733 +       },
4734 +       {
4735 +               .freq                   = 2447,
4736 +               RADIOREGS7(0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f,
4737 +                          0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x41, 0x63,
4738 +                          0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
4739 +                          0x00, 0x00, 0xf0, 0x00),
4740 +               PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
4741 +       },
4742 +       {
4743 +               .freq                   = 2452,
4744 +               RADIOREGS7(0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94,
4745 +                          0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x41, 0x63,
4746 +                          0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
4747 +                          0x00, 0x00, 0xf0, 0x00),
4748 +               PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
4749 +       },
4750 +       {
4751 +               .freq                   = 2457,
4752 +               RADIOREGS7(0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99,
4753 +                          0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x41, 0x63,
4754 +                          0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
4755 +                          0x00, 0x00, 0xf0, 0x00),
4756 +               PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
4757 +       },
4758 +       {
4759 +               .freq                   = 2462,
4760 +               RADIOREGS7(0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e,
4761 +                          0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x41, 0x63,
4762 +                          0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
4763 +                          0x00, 0x00, 0xf0, 0x00),
4764 +               PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
4765 +       },
4766 +       {
4767 +               .freq                   = 5180,
4768 +               RADIOREGS7(0xbe, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x06,
4769 +                          0x02, 0x0e, 0x00, 0x0e, 0x00, 0x9e, 0x00, 0x00,
4770 +                          0x9f, 0x2f, 0xa3, 0x00, 0xfc, 0x00, 0x00, 0x4f,
4771 +                          0x3a, 0x83, 0x00, 0xfc),
4772 +               PHYREGS(0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb),
4773 +       },
4774 +       {
4775 +               .freq                   = 5200,
4776 +               RADIOREGS7(0xc5, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x08,
4777 +                          0x02, 0x0e, 0x00, 0x0e, 0x00, 0x9e, 0x00, 0x00,
4778 +                          0x7f, 0x2f, 0x83, 0x00, 0xf8, 0x00, 0x00, 0x4c,
4779 +                          0x4a, 0x83, 0x00, 0xf8),
4780 +               PHYREGS(0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9),
4781 +       },
4782 +       {
4783 +               .freq                   = 5220,
4784 +               RADIOREGS7(0xcc, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x0a,
4785 +                          0x02, 0x0e, 0x00, 0x0e, 0x00, 0x9e, 0x00, 0x00,
4786 +                          0x6d, 0x3d, 0x83, 0x00, 0xf8, 0x00, 0x00, 0x2d,
4787 +                          0x2a, 0x73, 0x00, 0xf8),
4788 +               PHYREGS(0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7),
4789 +       },
4790 +       {
4791 +               .freq                   = 5240,
4792 +               RADIOREGS7(0xd2, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x0c,
4793 +                          0x02, 0x0d, 0x00, 0x0d, 0x00, 0x8d, 0x00, 0x00,
4794 +                          0x4d, 0x1c, 0x73, 0x00, 0xf8, 0x00, 0x00, 0x4d,
4795 +                          0x2b, 0x73, 0x00, 0xf8),
4796 +               PHYREGS(0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5),
4797 +       },
4798 +       {
4799 +               .freq                   = 5745,
4800 +               RADIOREGS7(0x7b, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x7d,
4801 +                          0x04, 0x08, 0x00, 0x06, 0x00, 0x15, 0x00, 0x00,
4802 +                          0x08, 0x03, 0x03, 0x00, 0x30, 0x00, 0x00, 0x06,
4803 +                          0x02, 0x03, 0x00, 0x30),
4804 +               PHYREGS(0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9),
4805 +       },
4806 +       {
4807 +               .freq                   = 5765,
4808 +               RADIOREGS7(0x81, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x81,
4809 +                          0x04, 0x08, 0x00, 0x06, 0x00, 0x15, 0x00, 0x00,
4810 +                          0x06, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x05,
4811 +                          0x02, 0x03, 0x00, 0x00),
4812 +               PHYREGS(0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8),
4813 +       },
4814 +       {
4815 +               .freq                   = 5785,
4816 +               RADIOREGS7(0x88, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x85,
4817 +                          0x04, 0x08, 0x00, 0x06, 0x00, 0x15, 0x00, 0x00,
4818 +                          0x08, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x05,
4819 +                          0x21, 0x03, 0x00, 0x00),
4820 +               PHYREGS(0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6),
4821 +       },
4822 +       {
4823 +               .freq                   = 5805,
4824 +               RADIOREGS7(0x8f, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x89,
4825 +                          0x04, 0x07, 0x00, 0x06, 0x00, 0x04, 0x00, 0x00,
4826 +                          0x06, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03,
4827 +                          0x00, 0x03, 0x00, 0x00),
4828 +               PHYREGS(0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4),
4829 +       },
4830 +       {
4831 +               .freq                   = 5825,
4832 +               RADIOREGS7(0x95, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x8d,
4833 +                          0x04, 0x07, 0x00, 0x05, 0x00, 0x03, 0x00, 0x00,
4834 +                          0x05, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03,
4835 +                          0x00, 0x03, 0x00, 0x00),
4836 +               PHYREGS(0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3),
4837 +       },
4838 +};
4839  
4840  void r2057_upload_inittabs(struct b43_wldev *dev)
4841  {
4842 @@ -109,33 +540,98 @@ void r2057_upload_inittabs(struct b43_wl
4843         u16 *table = NULL;
4844         u16 size, i;
4845  
4846 -       if (phy->rev == 7) {
4847 +       switch (phy->rev) {
4848 +       case 7:
4849                 table = r2057_rev4_init[0];
4850                 size = ARRAY_SIZE(r2057_rev4_init);
4851 -       } else if (phy->rev == 8 || phy->rev == 9) {
4852 +               break;
4853 +       case 8:
4854                 if (phy->radio_rev == 5) {
4855 -                       if (phy->radio_rev == 8) {
4856 -                               table = r2057_rev5_init[0];
4857 -                               size = ARRAY_SIZE(r2057_rev5_init);
4858 -                       } else {
4859 -                               table = r2057_rev5a_init[0];
4860 -                               size = ARRAY_SIZE(r2057_rev5a_init);
4861 -                       }
4862 +                       table = r2057_rev5_init[0];
4863 +                       size = ARRAY_SIZE(r2057_rev5_init);
4864                 } else if (phy->radio_rev == 7) {
4865                         table = r2057_rev7_init[0];
4866                         size = ARRAY_SIZE(r2057_rev7_init);
4867 -               } else if (phy->radio_rev == 9) {
4868 -                       table = r2057_rev8_init[0];
4869 -                       size = ARRAY_SIZE(r2057_rev8_init);
4870                 }
4871 +               break;
4872 +       case 9:
4873 +               if (phy->radio_rev == 5) {
4874 +                       table = r2057_rev5a_init[0];
4875 +                       size = ARRAY_SIZE(r2057_rev5a_init);
4876 +               }
4877 +               break;
4878 +       case 16:
4879 +               if (phy->radio_rev == 9) {
4880 +                       table = r2057_rev9_init[0];
4881 +                       size = ARRAY_SIZE(r2057_rev9_init);
4882 +               }
4883 +               break;
4884 +       case 17:
4885 +               if (phy->radio_rev == 14) {
4886 +                       table = r2057_rev14_init[0];
4887 +                       size = ARRAY_SIZE(r2057_rev14_init);
4888 +               }
4889 +               break;
4890         }
4891  
4892 +       B43_WARN_ON(!table);
4893 +
4894         if (table) {
4895 -               for (i = 0; i < 10; i++) {
4896 -                       pr_info("radio_write 0x%X ", *table);
4897 -                       table++;
4898 -                       pr_info("0x%X\n", *table);
4899 -                       table++;
4900 +               for (i = 0; i < size; i++, table += 2)
4901 +                       b43_radio_write(dev, table[0], table[1]);
4902 +       }
4903 +}
4904 +
4905 +void r2057_get_chantabent_rev7(struct b43_wldev *dev, u16 freq,
4906 +                              const struct b43_nphy_chantabent_rev7 **tabent_r7,
4907 +                              const struct b43_nphy_chantabent_rev7_2g **tabent_r7_2g)
4908 +{
4909 +       struct b43_phy *phy = &dev->phy;
4910 +       const struct b43_nphy_chantabent_rev7 *e_r7 = NULL;
4911 +       const struct b43_nphy_chantabent_rev7_2g *e_r7_2g = NULL;
4912 +       unsigned int len, i;
4913 +
4914 +       *tabent_r7 = NULL;
4915 +       *tabent_r7_2g = NULL;
4916 +
4917 +       switch (phy->rev) {
4918 +       case 8:
4919 +               if (phy->radio_rev == 5) {
4920 +                       e_r7_2g = b43_nphy_chantab_phy_rev8_radio_rev5;
4921 +                       len = ARRAY_SIZE(b43_nphy_chantab_phy_rev8_radio_rev5);
4922 +               }
4923 +               break;
4924 +       case 16:
4925 +               if (phy->radio_rev == 9) {
4926 +                       e_r7 = b43_nphy_chantab_phy_rev16_radio_rev9;
4927 +                       len = ARRAY_SIZE(b43_nphy_chantab_phy_rev16_radio_rev9);
4928 +               }
4929 +               break;
4930 +       case 17:
4931 +               if (phy->radio_rev == 14) {
4932 +                       e_r7_2g = b43_nphy_chantab_phy_rev17_radio_rev14;
4933 +                       len = ARRAY_SIZE(b43_nphy_chantab_phy_rev17_radio_rev14);
4934 +               }
4935 +               break;
4936 +       default:
4937 +               break;
4938 +       }
4939 +
4940 +       if (e_r7) {
4941 +               for (i = 0; i < len; i++, e_r7++) {
4942 +                       if (e_r7->freq == freq) {
4943 +                               *tabent_r7 = e_r7;
4944 +                               return;
4945 +                       }
4946 +               }
4947 +       } else if (e_r7_2g) {
4948 +               for (i = 0; i < len; i++, e_r7_2g++) {
4949 +                       if (e_r7_2g->freq == freq) {
4950 +                               *tabent_r7_2g = e_r7_2g;
4951 +                               return;
4952 +                       }
4953                 }
4954 +       } else {
4955 +               B43_WARN_ON(1);
4956         }
4957  }
4958 --- a/drivers/net/wireless/b43/radio_2057.h
4959 +++ b/drivers/net/wireless/b43/radio_2057.h
4960 @@ -84,6 +84,8 @@
4961  #define R2057_CMOSBUF_RX_RCCR                  0x04c
4962  #define R2057_LOGEN_SEL_PKDET                  0x04d
4963  #define R2057_CMOSBUF_SHAREIQ_PTAT             0x04e
4964 +
4965 +/* MISC core 0 */
4966  #define R2057_RXTXBIAS_CONFIG_CORE0            0x04f
4967  #define R2057_TXGM_TXRF_PUS_CORE0              0x050
4968  #define R2057_TXGM_IDAC_BLEED_CORE0            0x051
4969 @@ -204,6 +206,8 @@
4970  #define R2057_RXBB_GPAIOSEL_RXLPF_RCCAL_CORE0  0x0d1
4971  #define R2057_LPF_GAIN_CORE0                   0x0d2
4972  #define R2057_DACBUF_IDACS_BW_CORE0            0x0d3
4973 +
4974 +/* MISC core 1 */
4975  #define R2057_RXTXBIAS_CONFIG_CORE1            0x0d4
4976  #define R2057_TXGM_TXRF_PUS_CORE1              0x0d5
4977  #define R2057_TXGM_IDAC_BLEED_CORE1            0x0d6
4978 @@ -324,6 +328,7 @@
4979  #define R2057_RXBB_GPAIOSEL_RXLPF_RCCAL_CORE1  0x156
4980  #define R2057_LPF_GAIN_CORE1                   0x157
4981  #define R2057_DACBUF_IDACS_BW_CORE1            0x158
4982 +
4983  #define R2057_DACBUF_VINCM_CORE1               0x159
4984  #define R2057_RCCAL_START_R1_Q1_P1             0x15a
4985  #define R2057_RCCAL_X1                         0x15b
4986 @@ -345,6 +350,8 @@
4987  #define R2057_RCCAL_BCAP_VAL                   0x16b
4988  #define R2057_RCCAL_HPC_VAL                    0x16c
4989  #define R2057_RCCAL_OVERRIDES                  0x16d
4990 +
4991 +/* TX core 0 */
4992  #define R2057_TX0_IQCAL_GAIN_BW                        0x170
4993  #define R2057_TX0_LOFT_FINE_I                  0x171
4994  #define R2057_TX0_LOFT_FINE_Q                  0x172
4995 @@ -362,6 +369,8 @@
4996  #define R2057_TX0_TXRXCOUPLE_2G_PWRUP          0x17e
4997  #define R2057_TX0_TXRXCOUPLE_5G_ATTEN          0x17f
4998  #define R2057_TX0_TXRXCOUPLE_5G_PWRUP          0x180
4999 +
5000 +/* TX core 1 */
5001  #define R2057_TX1_IQCAL_GAIN_BW                        0x190
5002  #define R2057_TX1_LOFT_FINE_I                  0x191
5003  #define R2057_TX1_LOFT_FINE_Q                  0x192
5004 @@ -379,6 +388,7 @@
5005  #define R2057_TX1_TXRXCOUPLE_2G_PWRUP          0x19e
5006  #define R2057_TX1_TXRXCOUPLE_5G_ATTEN          0x19f
5007  #define R2057_TX1_TXRXCOUPLE_5G_PWRUP          0x1a0
5008 +
5009  #define R2057_AFE_VCM_CAL_MASTER_CORE0         0x1a1
5010  #define R2057_AFE_SET_VCM_I_CORE0              0x1a2
5011  #define R2057_AFE_SET_VCM_Q_CORE0              0x1a3
5012 @@ -425,6 +435,72 @@
5013  
5014  #define R2057_VCM_MASK                         0x7
5015  
5016 +struct b43_nphy_chantabent_rev7 {
5017 +       /* The channel frequency in MHz */
5018 +       u16 freq;
5019 +       /* Radio regs values on channelswitch */
5020 +       u8 radio_vcocal_countval0;
5021 +       u8 radio_vcocal_countval1;
5022 +       u8 radio_rfpll_refmaster_sparextalsize;
5023 +       u8 radio_rfpll_loopfilter_r1;
5024 +       u8 radio_rfpll_loopfilter_c2;
5025 +       u8 radio_rfpll_loopfilter_c1;
5026 +       u8 radio_cp_kpd_idac;
5027 +       u8 radio_rfpll_mmd0;
5028 +       u8 radio_rfpll_mmd1;
5029 +       u8 radio_vcobuf_tune;
5030 +       u8 radio_logen_mx2g_tune;
5031 +       u8 radio_logen_mx5g_tune;
5032 +       u8 radio_logen_indbuf2g_tune;
5033 +       u8 radio_logen_indbuf5g_tune;
5034 +       u8 radio_txmix2g_tune_boost_pu_core0;
5035 +       u8 radio_pad2g_tune_pus_core0;
5036 +       u8 radio_pga_boost_tune_core0;
5037 +       u8 radio_txmix5g_boost_tune_core0;
5038 +       u8 radio_pad5g_tune_misc_pus_core0;
5039 +       u8 radio_lna2g_tune_core0;
5040 +       u8 radio_lna5g_tune_core0;
5041 +       u8 radio_txmix2g_tune_boost_pu_core1;
5042 +       u8 radio_pad2g_tune_pus_core1;
5043 +       u8 radio_pga_boost_tune_core1;
5044 +       u8 radio_txmix5g_boost_tune_core1;
5045 +       u8 radio_pad5g_tune_misc_pus_core1;
5046 +       u8 radio_lna2g_tune_core1;
5047 +       u8 radio_lna5g_tune_core1;
5048 +       /* PHY res values on channelswitch */
5049 +       struct b43_phy_n_sfo_cfg phy_regs;
5050 +};
5051 +
5052 +struct b43_nphy_chantabent_rev7_2g {
5053 +       /* The channel frequency in MHz */
5054 +       u16 freq;
5055 +       /* Radio regs values on channelswitch */
5056 +       u8 radio_vcocal_countval0;
5057 +       u8 radio_vcocal_countval1;
5058 +       u8 radio_rfpll_refmaster_sparextalsize;
5059 +       u8 radio_rfpll_loopfilter_r1;
5060 +       u8 radio_rfpll_loopfilter_c2;
5061 +       u8 radio_rfpll_loopfilter_c1;
5062 +       u8 radio_cp_kpd_idac;
5063 +       u8 radio_rfpll_mmd0;
5064 +       u8 radio_rfpll_mmd1;
5065 +       u8 radio_vcobuf_tune;
5066 +       u8 radio_logen_mx2g_tune;
5067 +       u8 radio_logen_indbuf2g_tune;
5068 +       u8 radio_txmix2g_tune_boost_pu_core0;
5069 +       u8 radio_pad2g_tune_pus_core0;
5070 +       u8 radio_lna2g_tune_core0;
5071 +       u8 radio_txmix2g_tune_boost_pu_core1;
5072 +       u8 radio_pad2g_tune_pus_core1;
5073 +       u8 radio_lna2g_tune_core1;
5074 +       /* PHY regs values on channelswitch */
5075 +       struct b43_phy_n_sfo_cfg phy_regs;
5076 +};
5077 +
5078  void r2057_upload_inittabs(struct b43_wldev *dev);
5079  
5080 +void r2057_get_chantabent_rev7(struct b43_wldev *dev, u16 freq,
5081 +                              const struct b43_nphy_chantabent_rev7 **tabent_r7,
5082 +                              const struct b43_nphy_chantabent_rev7_2g **tabent_r7_2g);
5083 +
5084  #endif /* B43_RADIO_2057_H_ */
5085 --- a/drivers/net/wireless/b43/tables_nphy.h
5086 +++ b/drivers/net/wireless/b43/tables_nphy.h
5087 @@ -165,6 +165,10 @@ struct nphy_gain_ctl_workaround_entry *b
5088  #define B43_NTAB_C1_LOFEEDTH_R3                B43_NTAB16(27, 448) /* Local Oscillator Feed Through lookup 1 */
5089  #define B43_NTAB_C1_PAPD_COMP_R3       B43_NTAB16(27, 576)
5090  
5091 +/* Static N-PHY tables, PHY revision >= 7 */
5092 +#define B43_NTAB_TMAP_R7               B43_NTAB32(12,   0) /* TM AP */
5093 +#define B43_NTAB_NOISEVAR_R7           B43_NTAB32(16,   0) /* noise variance */
5094 +
5095  #define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_40_SIZE       18
5096  #define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_20_SIZE       18
5097  #define B43_NTAB_TX_IQLO_CAL_IQIMB_LADDER_40_SIZE      18
5098 --- a/.local-symbols
5099 +++ b/.local-symbols
5100 @@ -176,6 +176,7 @@ B43_PCMCIA=
5101  B43_SDIO=
5102  B43_BCMA_PIO=
5103  B43_PIO=
5104 +B43_PHY_G=
5105  B43_PHY_N=
5106  B43_PHY_LP=
5107  B43_PHY_HT=