mac80211: b43: backport b43 patches from wireless testing
[oweals/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 @@ -3742,7 +3791,9 @@ static int b43_switch_band(struct b43_wl
349         b43dbg(dev->wl, "Switching to %s GHz band\n",
350                band_to_string(chan->band));
351  
352 -       b43_software_rfkill(dev, true);
353 +       /* Some new devices don't need disabling radio for band switching */
354 +       if (!(phy->type == B43_PHYTYPE_N && phy->rev >= 3))
355 +               b43_software_rfkill(dev, true);
356  
357         phy->gmode = gmode;
358         b43_phy_put_into_reset(dev);
359 @@ -3796,38 +3847,29 @@ static void b43_set_retry_limits(struct
360  static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
361  {
362         struct b43_wl *wl = hw_to_b43_wl(hw);
363 -       struct b43_wldev *dev;
364 -       struct b43_phy *phy;
365 +       struct b43_wldev *dev = wl->current_dev;
366 +       struct b43_phy *phy = &dev->phy;
367         struct ieee80211_conf *conf = &hw->conf;
368         int antenna;
369         int err = 0;
370 -       bool reload_bss = false;
371  
372         mutex_lock(&wl->mutex);
373 -
374 -       dev = wl->current_dev;
375 -
376         b43_mac_suspend(dev);
377  
378 -       /* Switch the band (if necessary). This might change the active core. */
379 -       err = b43_switch_band(dev, conf->chandef.chan);
380 -       if (err)
381 -               goto out_unlock_mutex;
382 +       if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
383 +               phy->chandef = &conf->chandef;
384 +               phy->channel = conf->chandef.chan->hw_value;
385  
386 -       /* Need to reload all settings if the core changed */
387 -       if (dev != wl->current_dev) {
388 -               dev = wl->current_dev;
389 -               changed = ~0;
390 -               reload_bss = true;
391 -       }
392 +               /* Switch the band (if necessary). */
393 +               err = b43_switch_band(dev, conf->chandef.chan);
394 +               if (err)
395 +                       goto out_mac_enable;
396  
397 -       phy = &dev->phy;
398 -
399 -       if (conf_is_ht(conf))
400 -               phy->is_40mhz =
401 -                       (conf_is_ht40_minus(conf) || conf_is_ht40_plus(conf));
402 -       else
403 -               phy->is_40mhz = false;
404 +               /* Switch to the requested channel.
405 +                * The firmware takes care of races with the TX handler.
406 +                */
407 +               b43_switch_channel(dev, phy->channel);
408 +       }
409  
410         if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
411                 b43_set_retry_limits(dev, conf->short_frame_max_tx_count,
412 @@ -3836,11 +3878,6 @@ static int b43_op_config(struct ieee8021
413         if (!changed)
414                 goto out_mac_enable;
415  
416 -       /* Switch to the requested channel.
417 -        * The firmware takes care of races with the TX handler. */
418 -       if (conf->chandef.chan->hw_value != phy->channel)
419 -               b43_switch_channel(dev, conf->chandef.chan->hw_value);
420 -
421         dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_MONITOR);
422  
423         /* Adjust the desired TX power level. */
424 @@ -3876,12 +3913,8 @@ static int b43_op_config(struct ieee8021
425  
426  out_mac_enable:
427         b43_mac_enable(dev);
428 -out_unlock_mutex:
429         mutex_unlock(&wl->mutex);
430  
431 -       if (wl->vif && reload_bss)
432 -               b43_op_bss_info_changed(hw, wl->vif, &wl->vif->bss_conf, ~0);
433 -
434         return err;
435  }
436  
437 @@ -4307,6 +4340,7 @@ static char *b43_phy_name(struct b43_wld
438  static int b43_phy_versioning(struct b43_wldev *dev)
439  {
440         struct b43_phy *phy = &dev->phy;
441 +       const u8 core_rev = dev->dev->core_rev;
442         u32 tmp;
443         u8 analog_type;
444         u8 phy_type;
445 @@ -4321,23 +4355,23 @@ static int b43_phy_versioning(struct b43
446         analog_type = (tmp & B43_PHYVER_ANALOG) >> B43_PHYVER_ANALOG_SHIFT;
447         phy_type = (tmp & B43_PHYVER_TYPE) >> B43_PHYVER_TYPE_SHIFT;
448         phy_rev = (tmp & B43_PHYVER_VERSION);
449 +
450 +       /* LCNXN is continuation of N which run out of revisions */
451 +       if (phy_type == B43_PHYTYPE_LCNXN) {
452 +               phy_type = B43_PHYTYPE_N;
453 +               phy_rev += 16;
454 +       }
455 +
456         switch (phy_type) {
457 -       case B43_PHYTYPE_A:
458 -               if (phy_rev >= 4)
459 -                       unsupported = 1;
460 -               break;
461 -       case B43_PHYTYPE_B:
462 -               if (phy_rev != 2 && phy_rev != 4 && phy_rev != 6
463 -                   && phy_rev != 7)
464 -                       unsupported = 1;
465 -               break;
466 +#ifdef CPTCFG_B43_PHY_G
467         case B43_PHYTYPE_G:
468                 if (phy_rev > 9)
469                         unsupported = 1;
470                 break;
471 +#endif
472  #ifdef CPTCFG_B43_PHY_N
473         case B43_PHYTYPE_N:
474 -               if (phy_rev > 9)
475 +               if (phy_rev >= 19)
476                         unsupported = 1;
477                 break;
478  #endif
479 @@ -4372,7 +4406,15 @@ static int b43_phy_versioning(struct b43
480                 analog_type, phy_type, b43_phy_name(dev, phy_type), phy_rev);
481  
482         /* Get RADIO versioning */
483 -       if (dev->dev->core_rev >= 24) {
484 +       if (core_rev == 40 || core_rev == 42) {
485 +               radio_manuf = 0x17F;
486 +
487 +               b43_write16(dev, B43_MMIO_RADIO24_CONTROL, 0);
488 +               radio_rev = b43_read16(dev, B43_MMIO_RADIO24_DATA);
489 +
490 +               b43_write16(dev, B43_MMIO_RADIO24_CONTROL, 1);
491 +               radio_ver = b43_read16(dev, B43_MMIO_RADIO24_DATA);
492 +       } else if (core_rev >= 24) {
493                 u16 radio24[3];
494  
495                 for (tmp = 0; tmp < 3; tmp++) {
496 @@ -4428,7 +4470,10 @@ static int b43_phy_versioning(struct b43
497                         unsupported = 1;
498                 break;
499         case B43_PHYTYPE_N:
500 -               if (radio_ver != 0x2055 && radio_ver != 0x2056)
501 +               if (radio_ver != 0x2055 && radio_ver != 0x2056 &&
502 +                   radio_ver != 0x2057)
503 +                       unsupported = 1;
504 +               if (radio_ver == 0x2057 && !(radio_rev == 9))
505                         unsupported = 1;
506                 break;
507         case B43_PHYTYPE_LP:
508 @@ -4447,13 +4492,13 @@ static int b43_phy_versioning(struct b43
509                 B43_WARN_ON(1);
510         }
511         if (unsupported) {
512 -               b43err(dev->wl, "FOUND UNSUPPORTED RADIO "
513 -                      "(Manuf 0x%X, Version 0x%X, Revision %u)\n",
514 +               b43err(dev->wl,
515 +                      "FOUND UNSUPPORTED RADIO (Manuf 0x%X, ID 0x%X, Revision %u)\n",
516                        radio_manuf, radio_ver, radio_rev);
517                 return -EOPNOTSUPP;
518         }
519 -       b43dbg(dev->wl, "Found Radio: Manuf 0x%X, Version 0x%X, Revision %u\n",
520 -              radio_manuf, radio_ver, radio_rev);
521 +       b43info(dev->wl, "Found Radio: Manuf 0x%X, ID 0x%X, Revision %u\n",
522 +               radio_manuf, radio_ver, radio_rev);
523  
524         phy->radio_manuf = radio_manuf;
525         phy->radio_ver = radio_ver;
526 @@ -5064,9 +5109,15 @@ static int b43_setup_bands(struct b43_wl
527                            bool have_2ghz_phy, bool have_5ghz_phy)
528  {
529         struct ieee80211_hw *hw = dev->wl->hw;
530 +       struct b43_phy *phy = &dev->phy;
531 +       bool limited_2g;
532 +
533 +       /* We don't support all 2 GHz channels on some devices */
534 +       limited_2g = phy->radio_ver == 0x2057 && phy->radio_rev == 9;
535  
536         if (have_2ghz_phy)
537 -               hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &b43_band_2GHz;
538 +               hw->wiphy->bands[IEEE80211_BAND_2GHZ] = limited_2g ?
539 +                       &b43_band_2ghz_limited : &b43_band_2GHz;
540         if (dev->phy.type == B43_PHYTYPE_N) {
541                 if (have_5ghz_phy)
542                         hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &b43_band_5GHz_nphy;
543 @@ -5164,6 +5215,7 @@ static void b43_supported_bands(struct b
544  static int b43_wireless_core_attach(struct b43_wldev *dev)
545  {
546         struct b43_wl *wl = dev->wl;
547 +       struct b43_phy *phy = &dev->phy;
548         int err;
549         u32 tmp;
550         bool have_2ghz_phy = false, have_5ghz_phy = false;
551 @@ -5181,6 +5233,8 @@ static int b43_wireless_core_attach(stru
552                 goto out;
553         }
554  
555 +       phy->do_full_init = true;
556 +
557         /* Try to guess supported bands for the first init needs */
558         switch (dev->dev->bus_type) {
559  #ifdef CPTCFG_B43_BCMA
560 @@ -5214,14 +5268,16 @@ static int b43_wireless_core_attach(stru
561         b43_supported_bands(dev, &have_2ghz_phy, &have_5ghz_phy);
562  
563         /* We don't support 5 GHz on some PHYs yet */
564 -       switch (dev->phy.type) {
565 -       case B43_PHYTYPE_A:
566 -       case B43_PHYTYPE_G:
567 -       case B43_PHYTYPE_N:
568 -       case B43_PHYTYPE_LP:
569 -       case B43_PHYTYPE_HT:
570 -               b43warn(wl, "5 GHz band is unsupported on this PHY\n");
571 -               have_5ghz_phy = false;
572 +       if (have_5ghz_phy) {
573 +               switch (dev->phy.type) {
574 +               case B43_PHYTYPE_A:
575 +               case B43_PHYTYPE_G:
576 +               case B43_PHYTYPE_N:
577 +               case B43_PHYTYPE_LP:
578 +               case B43_PHYTYPE_HT:
579 +                       b43warn(wl, "5 GHz band is unsupported on this PHY\n");
580 +                       have_5ghz_phy = false;
581 +               }
582         }
583  
584         if (!have_2ghz_phy && !have_5ghz_phy) {
585 --- a/drivers/net/wireless/b43/phy_common.c
586 +++ b/drivers/net/wireless/b43/phy_common.c
587 @@ -45,11 +45,10 @@ int b43_phy_allocate(struct b43_wldev *d
588         phy->ops = NULL;
589  
590         switch (phy->type) {
591 -       case B43_PHYTYPE_A:
592 -               phy->ops = &b43_phyops_a;
593 -               break;
594         case B43_PHYTYPE_G:
595 +#ifdef CPTCFG_B43_PHY_G
596                 phy->ops = &b43_phyops_g;
597 +#endif
598                 break;
599         case B43_PHYTYPE_N:
600  #ifdef CPTCFG_B43_PHY_N
601 @@ -94,18 +93,25 @@ int b43_phy_init(struct b43_wldev *dev)
602         const struct b43_phy_operations *ops = phy->ops;
603         int err;
604  
605 -       phy->channel = ops->get_default_chan(dev);
606 +       /* During PHY init we need to use some channel. On the first init this
607 +        * function is called *before* b43_op_config, so our pointer is NULL.
608 +        */
609 +       if (!phy->chandef) {
610 +               phy->chandef = &dev->wl->hw->conf.chandef;
611 +               phy->channel = phy->chandef->chan->hw_value;
612 +       }
613  
614         phy->ops->switch_analog(dev, true);
615         b43_software_rfkill(dev, false);
616 +
617         err = ops->init(dev);
618         if (err) {
619                 b43err(dev->wl, "PHY init failed\n");
620                 goto err_block_rf;
621         }
622 -       /* Make sure to switch hardware and firmware (SHM) to
623 -        * the default channel. */
624 -       err = b43_switch_channel(dev, ops->get_default_chan(dev));
625 +       phy->do_full_init = false;
626 +
627 +       err = b43_switch_channel(dev, phy->channel);
628         if (err) {
629                 b43err(dev->wl, "PHY init: Channel switch to default failed\n");
630                 goto err_phy_exit;
631 @@ -114,6 +120,7 @@ int b43_phy_init(struct b43_wldev *dev)
632         return 0;
633  
634  err_phy_exit:
635 +       phy->do_full_init = true;
636         if (ops->exit)
637                 ops->exit(dev);
638  err_block_rf:
639 @@ -127,6 +134,7 @@ void b43_phy_exit(struct b43_wldev *dev)
640         const struct b43_phy_operations *ops = dev->phy.ops;
641  
642         b43_software_rfkill(dev, true);
643 +       dev->phy.do_full_init = true;
644         if (ops->exit)
645                 ops->exit(dev);
646  }
647 @@ -403,9 +411,6 @@ int b43_switch_channel(struct b43_wldev
648         u16 channelcookie, savedcookie;
649         int err;
650  
651 -       if (new_channel == B43_DEFAULT_CHANNEL)
652 -               new_channel = phy->ops->get_default_chan(dev);
653 -
654         /* First we set the channel radio code to prevent the
655          * firmware from sending ghost packets.
656          */
657 @@ -423,7 +428,6 @@ int b43_switch_channel(struct b43_wldev
658         if (err)
659                 goto err_restore_cookie;
660  
661 -       dev->phy.channel = new_channel;
662         /* Wait for the radio to tune to the channel and stabilize. */
663         msleep(8);
664  
665 @@ -542,10 +546,9 @@ void b43_phyop_switch_analog_generic(str
666  }
667  
668  
669 -bool b43_channel_type_is_40mhz(enum nl80211_channel_type channel_type)
670 +bool b43_is_40mhz(struct b43_wldev *dev)
671  {
672 -       return (channel_type == NL80211_CHAN_HT40MINUS ||
673 -               channel_type == NL80211_CHAN_HT40PLUS);
674 +       return dev->phy.chandef->width == NL80211_CHAN_WIDTH_40;
675  }
676  
677  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/BmacPhyClkFgc */
678 --- a/drivers/net/wireless/b43/phy_common.h
679 +++ b/drivers/net/wireless/b43/phy_common.h
680 @@ -228,12 +228,12 @@ struct b43_phy {
681         bool supports_2ghz;
682         bool supports_5ghz;
683  
684 -       /* HT info */
685 -       bool is_40mhz;
686 -
687         /* Is GMODE (2 GHz mode) bit enabled? */
688         bool gmode;
689  
690 +       /* After power reset full init has to be performed */
691 +       bool do_full_init;
692 +
693         /* Analog Type */
694         u8 analog;
695         /* B43_PHYTYPE_ */
696 @@ -264,9 +264,8 @@ struct b43_phy {
697         unsigned long next_txpwr_check_time;
698  
699         /* Current channel */
700 +       struct cfg80211_chan_def *chandef;
701         unsigned int channel;
702 -       u16 channel_freq;
703 -       enum nl80211_channel_type channel_type;
704  
705         /* PHY TX errors counter. */
706         atomic_t txerr_cnt;
707 @@ -397,10 +396,6 @@ void b43_phy_take_out_of_reset(struct b4
708   * b43_switch_channel - Switch to another channel
709   */
710  int b43_switch_channel(struct b43_wldev *dev, unsigned int new_channel);
711 -/**
712 - * B43_DEFAULT_CHANNEL - Switch to the default channel.
713 - */
714 -#define B43_DEFAULT_CHANNEL    UINT_MAX
715  
716  /**
717   * b43_software_rfkill - Turn the radio ON or OFF in software.
718 @@ -451,7 +446,7 @@ int b43_phy_shm_tssi_read(struct b43_wld
719   */
720  void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on);
721  
722 -bool b43_channel_type_is_40mhz(enum nl80211_channel_type channel_type);
723 +bool b43_is_40mhz(struct b43_wldev *dev);
724  
725  void b43_phy_force_clock(struct b43_wldev *dev, bool force);
726  
727 --- a/drivers/net/wireless/b43/phy_n.c
728 +++ b/drivers/net/wireless/b43/phy_n.c
729 @@ -36,6 +36,7 @@
730  #include "main.h"
731  
732  struct nphy_txgains {
733 +       u16 tx_lpf[2];
734         u16 txgm[2];
735         u16 pga[2];
736         u16 pad[2];
737 @@ -43,6 +44,7 @@ struct nphy_txgains {
738  };
739  
740  struct nphy_iqcal_params {
741 +       u16 tx_lpf;
742         u16 txgm;
743         u16 pga;
744         u16 pad;
745 @@ -69,6 +71,14 @@ enum b43_nphy_rf_sequence {
746         B43_RFSEQ_UPDATE_GAINU,
747  };
748  
749 +enum n_rf_ctl_over_cmd {
750 +       N_RF_CTL_OVER_CMD_RXRF_PU = 0,
751 +       N_RF_CTL_OVER_CMD_RX_PU = 1,
752 +       N_RF_CTL_OVER_CMD_TX_PU = 2,
753 +       N_RF_CTL_OVER_CMD_RX_GAIN = 3,
754 +       N_RF_CTL_OVER_CMD_TX_GAIN = 4,
755 +};
756 +
757  enum n_intc_override {
758         N_INTC_OVERRIDE_OFF = 0,
759         N_INTC_OVERRIDE_TRSW = 1,
760 @@ -140,11 +150,19 @@ ok:
761         b43_phy_write(dev, B43_NPHY_RFSEQMODE, seq_mode);
762  }
763  
764 +static void b43_nphy_rf_ctl_override_rev19(struct b43_wldev *dev, u16 field,
765 +                                          u16 value, u8 core, bool off,
766 +                                          u8 override_id)
767 +{
768 +       /* TODO */
769 +}
770 +
771  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverrideRev7 */
772  static void b43_nphy_rf_ctl_override_rev7(struct b43_wldev *dev, u16 field,
773                                           u16 value, u8 core, bool off,
774                                           u8 override)
775  {
776 +       struct b43_phy *phy = &dev->phy;
777         const struct nphy_rf_control_override_rev7 *e;
778         u16 en_addrs[3][2] = {
779                 { 0x0E7, 0x0EC }, { 0x342, 0x343 }, { 0x346, 0x347 }
780 @@ -154,6 +172,11 @@ static void b43_nphy_rf_ctl_override_rev
781         u16 val_addr;
782         u8 i;
783  
784 +       if (phy->rev >= 19 || phy->rev < 3) {
785 +               B43_WARN_ON(1);
786 +               return;
787 +       }
788 +
789         /* Remember: we can get NULL! */
790         e = b43_nphy_get_rf_ctl_over_rev7(dev, field, override);
791  
792 @@ -181,6 +204,50 @@ static void b43_nphy_rf_ctl_override_rev
793         }
794  }
795  
796 +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverideOneToMany */
797 +static void b43_nphy_rf_ctl_override_one_to_many(struct b43_wldev *dev,
798 +                                                enum n_rf_ctl_over_cmd cmd,
799 +                                                u16 value, u8 core, bool off)
800 +{
801 +       struct b43_phy *phy = &dev->phy;
802 +       u16 tmp;
803 +
804 +       B43_WARN_ON(phy->rev < 7);
805 +
806 +       switch (cmd) {
807 +       case N_RF_CTL_OVER_CMD_RXRF_PU:
808 +               b43_nphy_rf_ctl_override_rev7(dev, 0x20, value, core, off, 1);
809 +               b43_nphy_rf_ctl_override_rev7(dev, 0x10, value, core, off, 1);
810 +               b43_nphy_rf_ctl_override_rev7(dev, 0x08, value, core, off, 1);
811 +               break;
812 +       case N_RF_CTL_OVER_CMD_RX_PU:
813 +               b43_nphy_rf_ctl_override_rev7(dev, 0x4, value, core, off, 1);
814 +               b43_nphy_rf_ctl_override_rev7(dev, 0x2, value, core, off, 1);
815 +               b43_nphy_rf_ctl_override_rev7(dev, 0x1, value, core, off, 1);
816 +               b43_nphy_rf_ctl_override_rev7(dev, 0x2, value, core, off, 2);
817 +               b43_nphy_rf_ctl_override_rev7(dev, 0x0800, value, core, off, 1);
818 +               break;
819 +       case N_RF_CTL_OVER_CMD_TX_PU:
820 +               b43_nphy_rf_ctl_override_rev7(dev, 0x4, value, core, off, 0);
821 +               b43_nphy_rf_ctl_override_rev7(dev, 0x2, value, core, off, 1);
822 +               b43_nphy_rf_ctl_override_rev7(dev, 0x1, value, core, off, 2);
823 +               b43_nphy_rf_ctl_override_rev7(dev, 0x0800, value, core, off, 1);
824 +               break;
825 +       case N_RF_CTL_OVER_CMD_RX_GAIN:
826 +               tmp = value & 0xFF;
827 +               b43_nphy_rf_ctl_override_rev7(dev, 0x0800, tmp, core, off, 0);
828 +               tmp = value >> 8;
829 +               b43_nphy_rf_ctl_override_rev7(dev, 0x6000, tmp, core, off, 0);
830 +               break;
831 +       case N_RF_CTL_OVER_CMD_TX_GAIN:
832 +               tmp = value & 0x7FFF;
833 +               b43_nphy_rf_ctl_override_rev7(dev, 0x1000, tmp, core, off, 0);
834 +               tmp = value >> 14;
835 +               b43_nphy_rf_ctl_override_rev7(dev, 0x4000, tmp, core, off, 0);
836 +               break;
837 +       }
838 +}
839 +
840  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverride */
841  static void b43_nphy_rf_ctl_override(struct b43_wldev *dev, u16 field,
842                                      u16 value, u8 core, bool off)
843 @@ -264,6 +331,8 @@ static void b43_nphy_rf_ctl_intc_overrid
844         u16 reg, tmp, tmp2, val;
845         int core;
846  
847 +       /* TODO: What about rev19+? Revs 3+ and 7+ are a bit similar */
848 +
849         for (core = 0; core < 2; core++) {
850                 if ((core_sel == 1 && core != 0) ||
851                     (core_sel == 2 && core != 1))
852 @@ -505,6 +574,14 @@ static void b43_nphy_stay_in_carrier_sea
853         }
854  }
855  
856 +/* http://bcm-v4.sipsolutions.net/PHY/N/Read_Lpf_Bw_Ctl */
857 +static u16 b43_nphy_read_lpf_ctl(struct b43_wldev *dev, u16 offset)
858 +{
859 +       if (!offset)
860 +               offset = b43_is_40mhz(dev) ? 0x159 : 0x154;
861 +       return b43_ntab_read(dev, B43_NTAB16(7, offset)) & 0x7;
862 +}
863 +
864  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/AdjustLnaGainTbl */
865  static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev)
866  {
867 @@ -590,7 +667,148 @@ static void b43_nphy_set_rf_sequence(str
868   * Radio 0x2057
869   **************************************************/
870  
871 -/* http://bcm-v4.sipsolutions.net/PHY/radio2057_rcal */
872 +static void b43_radio_2057_chantab_upload(struct b43_wldev *dev,
873 +                                         const struct b43_nphy_chantabent_rev7 *e_r7,
874 +                                         const struct b43_nphy_chantabent_rev7_2g *e_r7_2g)
875 +{
876 +       if (e_r7_2g) {
877 +               b43_radio_write(dev, R2057_VCOCAL_COUNTVAL0, e_r7_2g->radio_vcocal_countval0);
878 +               b43_radio_write(dev, R2057_VCOCAL_COUNTVAL1, e_r7_2g->radio_vcocal_countval1);
879 +               b43_radio_write(dev, R2057_RFPLL_REFMASTER_SPAREXTALSIZE, e_r7_2g->radio_rfpll_refmaster_sparextalsize);
880 +               b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_R1, e_r7_2g->radio_rfpll_loopfilter_r1);
881 +               b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C2, e_r7_2g->radio_rfpll_loopfilter_c2);
882 +               b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C1, e_r7_2g->radio_rfpll_loopfilter_c1);
883 +               b43_radio_write(dev, R2057_CP_KPD_IDAC, e_r7_2g->radio_cp_kpd_idac);
884 +               b43_radio_write(dev, R2057_RFPLL_MMD0, e_r7_2g->radio_rfpll_mmd0);
885 +               b43_radio_write(dev, R2057_RFPLL_MMD1, e_r7_2g->radio_rfpll_mmd1);
886 +               b43_radio_write(dev, R2057_VCOBUF_TUNE, e_r7_2g->radio_vcobuf_tune);
887 +               b43_radio_write(dev, R2057_LOGEN_MX2G_TUNE, e_r7_2g->radio_logen_mx2g_tune);
888 +               b43_radio_write(dev, R2057_LOGEN_INDBUF2G_TUNE, e_r7_2g->radio_logen_indbuf2g_tune);
889 +               b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE0, e_r7_2g->radio_txmix2g_tune_boost_pu_core0);
890 +               b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE0, e_r7_2g->radio_pad2g_tune_pus_core0);
891 +               b43_radio_write(dev, R2057_LNA2G_TUNE_CORE0, e_r7_2g->radio_lna2g_tune_core0);
892 +               b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE1, e_r7_2g->radio_txmix2g_tune_boost_pu_core1);
893 +               b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE1, e_r7_2g->radio_pad2g_tune_pus_core1);
894 +               b43_radio_write(dev, R2057_LNA2G_TUNE_CORE1, e_r7_2g->radio_lna2g_tune_core1);
895 +
896 +       } else {
897 +               b43_radio_write(dev, R2057_VCOCAL_COUNTVAL0, e_r7->radio_vcocal_countval0);
898 +               b43_radio_write(dev, R2057_VCOCAL_COUNTVAL1, e_r7->radio_vcocal_countval1);
899 +               b43_radio_write(dev, R2057_RFPLL_REFMASTER_SPAREXTALSIZE, e_r7->radio_rfpll_refmaster_sparextalsize);
900 +               b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_R1, e_r7->radio_rfpll_loopfilter_r1);
901 +               b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C2, e_r7->radio_rfpll_loopfilter_c2);
902 +               b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C1, e_r7->radio_rfpll_loopfilter_c1);
903 +               b43_radio_write(dev, R2057_CP_KPD_IDAC, e_r7->radio_cp_kpd_idac);
904 +               b43_radio_write(dev, R2057_RFPLL_MMD0, e_r7->radio_rfpll_mmd0);
905 +               b43_radio_write(dev, R2057_RFPLL_MMD1, e_r7->radio_rfpll_mmd1);
906 +               b43_radio_write(dev, R2057_VCOBUF_TUNE, e_r7->radio_vcobuf_tune);
907 +               b43_radio_write(dev, R2057_LOGEN_MX2G_TUNE, e_r7->radio_logen_mx2g_tune);
908 +               b43_radio_write(dev, R2057_LOGEN_MX5G_TUNE, e_r7->radio_logen_mx5g_tune);
909 +               b43_radio_write(dev, R2057_LOGEN_INDBUF2G_TUNE, e_r7->radio_logen_indbuf2g_tune);
910 +               b43_radio_write(dev, R2057_LOGEN_INDBUF5G_TUNE, e_r7->radio_logen_indbuf5g_tune);
911 +               b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE0, e_r7->radio_txmix2g_tune_boost_pu_core0);
912 +               b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE0, e_r7->radio_pad2g_tune_pus_core0);
913 +               b43_radio_write(dev, R2057_PGA_BOOST_TUNE_CORE0, e_r7->radio_pga_boost_tune_core0);
914 +               b43_radio_write(dev, R2057_TXMIX5G_BOOST_TUNE_CORE0, e_r7->radio_txmix5g_boost_tune_core0);
915 +               b43_radio_write(dev, R2057_PAD5G_TUNE_MISC_PUS_CORE0, e_r7->radio_pad5g_tune_misc_pus_core0);
916 +               b43_radio_write(dev, R2057_LNA2G_TUNE_CORE0, e_r7->radio_lna2g_tune_core0);
917 +               b43_radio_write(dev, R2057_LNA5G_TUNE_CORE0, e_r7->radio_lna5g_tune_core0);
918 +               b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE1, e_r7->radio_txmix2g_tune_boost_pu_core1);
919 +               b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE1, e_r7->radio_pad2g_tune_pus_core1);
920 +               b43_radio_write(dev, R2057_PGA_BOOST_TUNE_CORE1, e_r7->radio_pga_boost_tune_core1);
921 +               b43_radio_write(dev, R2057_TXMIX5G_BOOST_TUNE_CORE1, e_r7->radio_txmix5g_boost_tune_core1);
922 +               b43_radio_write(dev, R2057_PAD5G_TUNE_MISC_PUS_CORE1, e_r7->radio_pad5g_tune_misc_pus_core1);
923 +               b43_radio_write(dev, R2057_LNA2G_TUNE_CORE1, e_r7->radio_lna2g_tune_core1);
924 +               b43_radio_write(dev, R2057_LNA5G_TUNE_CORE1, e_r7->radio_lna5g_tune_core1);
925 +       }
926 +}
927 +
928 +static void b43_radio_2057_setup(struct b43_wldev *dev,
929 +                                const struct b43_nphy_chantabent_rev7 *tabent_r7,
930 +                                const struct b43_nphy_chantabent_rev7_2g *tabent_r7_2g)
931 +{
932 +       struct b43_phy *phy = &dev->phy;
933 +
934 +       b43_radio_2057_chantab_upload(dev, tabent_r7, tabent_r7_2g);
935 +
936 +       switch (phy->radio_rev) {
937 +       case 0 ... 4:
938 +       case 6:
939 +               if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
940 +                       b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_R1, 0x3f);
941 +                       b43_radio_write(dev, R2057_CP_KPD_IDAC, 0x3f);
942 +                       b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C1, 0x8);
943 +                       b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C2, 0x8);
944 +               } else {
945 +                       b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_R1, 0x1f);
946 +                       b43_radio_write(dev, R2057_CP_KPD_IDAC, 0x3f);
947 +                       b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C1, 0x8);
948 +                       b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C2, 0x8);
949 +               }
950 +               break;
951 +       case 9: /* e.g. PHY rev 16 */
952 +               b43_radio_write(dev, R2057_LOGEN_PTAT_RESETS, 0x20);
953 +               b43_radio_write(dev, R2057_VCOBUF_IDACS, 0x18);
954 +               if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
955 +                       b43_radio_write(dev, R2057_LOGEN_PTAT_RESETS, 0x38);
956 +                       b43_radio_write(dev, R2057_VCOBUF_IDACS, 0x0f);
957 +
958 +                       if (b43_is_40mhz(dev)) {
959 +                               /* TODO */
960 +                       } else {
961 +                               b43_radio_write(dev,
962 +                                               R2057_PAD_BIAS_FILTER_BWS_CORE0,
963 +                                               0x3c);
964 +                               b43_radio_write(dev,
965 +                                               R2057_PAD_BIAS_FILTER_BWS_CORE1,
966 +                                               0x3c);
967 +                       }
968 +               }
969 +               break;
970 +       /* TODO */
971 +       }
972 +
973 +       if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
974 +               u16 txmix2g_tune_boost_pu = 0;
975 +               u16 pad2g_tune_pus = 0;
976 +
977 +               if (b43_nphy_ipa(dev)) {
978 +                       switch (phy->radio_rev) {
979 +                       case 9:
980 +                               txmix2g_tune_boost_pu = 0x0041;
981 +                               /* TODO */
982 +                               break;
983 +                       }
984 +                       /* TODO */
985 +               }
986 +
987 +               if (txmix2g_tune_boost_pu)
988 +                       b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE0,
989 +                                       txmix2g_tune_boost_pu);
990 +               if (pad2g_tune_pus)
991 +                       b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE0,
992 +                                       pad2g_tune_pus);
993 +               if (txmix2g_tune_boost_pu)
994 +                       b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE1,
995 +                                       txmix2g_tune_boost_pu);
996 +               if (pad2g_tune_pus)
997 +                       b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE1,
998 +                                       pad2g_tune_pus);
999 +       }
1000 +
1001 +       usleep_range(50, 100);
1002 +
1003 +       /* VCO calibration */
1004 +       b43_radio_mask(dev, R2057_RFPLL_MISC_EN, ~0x01);
1005 +       b43_radio_mask(dev, R2057_RFPLL_MISC_CAL_RESETN, ~0x04);
1006 +       b43_radio_set(dev, R2057_RFPLL_MISC_CAL_RESETN, 0x4);
1007 +       b43_radio_set(dev, R2057_RFPLL_MISC_EN, 0x01);
1008 +       usleep_range(300, 600);
1009 +}
1010 +
1011 +/* Calibrate resistors in LPF of PLL?
1012 + * http://bcm-v4.sipsolutions.net/PHY/radio205x_rcal
1013 + */
1014  static u8 b43_radio_2057_rcal(struct b43_wldev *dev)
1015  {
1016         struct b43_phy *phy = &dev->phy;
1017 @@ -603,15 +821,25 @@ static u8 b43_radio_2057_rcal(struct b43
1018                 b43_radio_maskset(dev, 0x1ca, ~0x2, 0x1);
1019         }
1020  
1021 +       /* Enable */
1022         b43_radio_set(dev, R2057_RCAL_CONFIG, 0x1);
1023         udelay(10);
1024 -       b43_radio_set(dev, R2057_RCAL_CONFIG, 0x3);
1025 -       if (!b43_radio_wait_value(dev, R2057_RCCAL_N1_1, 1, 1, 100, 1000000)) {
1026 +
1027 +       /* Start */
1028 +       b43_radio_set(dev, R2057_RCAL_CONFIG, 0x2);
1029 +       usleep_range(100, 200);
1030 +
1031 +       /* Stop */
1032 +       b43_radio_mask(dev, R2057_RCAL_CONFIG, ~0x2);
1033 +
1034 +       /* Wait and check for result */
1035 +       if (!b43_radio_wait_value(dev, R2057_RCAL_STATUS, 1, 1, 100, 1000000)) {
1036                 b43err(dev->wl, "Radio 0x2057 rcal timeout\n");
1037                 return 0;
1038         }
1039 -       b43_radio_mask(dev, R2057_RCAL_CONFIG, ~0x2);
1040         tmp = b43_radio_read(dev, R2057_RCAL_STATUS) & 0x3E;
1041 +
1042 +       /* Disable */
1043         b43_radio_mask(dev, R2057_RCAL_CONFIG, ~0x1);
1044  
1045         if (phy->radio_rev == 5) {
1046 @@ -627,7 +855,9 @@ static u8 b43_radio_2057_rcal(struct b43
1047         return tmp & 0x3e;
1048  }
1049  
1050 -/* http://bcm-v4.sipsolutions.net/PHY/radio2057_rccal */
1051 +/* Calibrate the internal RC oscillator?
1052 + * http://bcm-v4.sipsolutions.net/PHY/radio2057_rccal
1053 + */
1054  static u16 b43_radio_2057_rccal(struct b43_wldev *dev)
1055  {
1056         struct b43_phy *phy = &dev->phy;
1057 @@ -635,49 +865,76 @@ static u16 b43_radio_2057_rccal(struct b
1058                         phy->radio_rev == 6);
1059         u16 tmp;
1060  
1061 +       /* Setup cal */
1062         if (special) {
1063                 b43_radio_write(dev, R2057_RCCAL_MASTER, 0x61);
1064                 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xC0);
1065         } else {
1066 -               b43_radio_write(dev, 0x1AE, 0x61);
1067 +               b43_radio_write(dev, R2057v7_RCCAL_MASTER, 0x61);
1068                 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xE1);
1069         }
1070         b43_radio_write(dev, R2057_RCCAL_X1, 0x6E);
1071 +
1072 +       /* Start, wait, stop */
1073         b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x55);
1074 -       if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 1, 1, 500,
1075 +       if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 2, 2, 500,
1076                                   5000000))
1077                 b43dbg(dev->wl, "Radio 0x2057 rccal timeout\n");
1078 +       usleep_range(35, 70);
1079         b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x15);
1080 +       usleep_range(70, 140);
1081 +
1082 +       /* Setup cal */
1083         if (special) {
1084                 b43_radio_write(dev, R2057_RCCAL_MASTER, 0x69);
1085                 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xB0);
1086         } else {
1087 -               b43_radio_write(dev, 0x1AE, 0x69);
1088 +               b43_radio_write(dev, R2057v7_RCCAL_MASTER, 0x69);
1089                 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xD5);
1090         }
1091         b43_radio_write(dev, R2057_RCCAL_X1, 0x6E);
1092 +
1093 +       /* Start, wait, stop */
1094 +       usleep_range(35, 70);
1095         b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x55);
1096 -       if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 1, 1, 500,
1097 +       usleep_range(70, 140);
1098 +       if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 2, 2, 500,
1099                                   5000000))
1100                 b43dbg(dev->wl, "Radio 0x2057 rccal timeout\n");
1101 +       usleep_range(35, 70);
1102         b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x15);
1103 +       usleep_range(70, 140);
1104 +
1105 +       /* Setup cal */
1106         if (special) {
1107                 b43_radio_write(dev, R2057_RCCAL_MASTER, 0x73);
1108                 b43_radio_write(dev, R2057_RCCAL_X1, 0x28);
1109                 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xB0);
1110         } else {
1111 -               b43_radio_write(dev, 0x1AE, 0x73);
1112 +               b43_radio_write(dev, R2057v7_RCCAL_MASTER, 0x73);
1113                 b43_radio_write(dev, R2057_RCCAL_X1, 0x6E);
1114                 b43_radio_write(dev, R2057_RCCAL_TRC0, 0x99);
1115         }
1116 +
1117 +       /* Start, wait, stop */
1118 +       usleep_range(35, 70);
1119         b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x55);
1120 -       if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 1, 1, 500,
1121 +       usleep_range(70, 140);
1122 +       if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 2, 2, 500,
1123                                   5000000)) {
1124                 b43err(dev->wl, "Radio 0x2057 rcal timeout\n");
1125                 return 0;
1126         }
1127         tmp = b43_radio_read(dev, R2057_RCCAL_DONE_OSCCAP);
1128 +       usleep_range(35, 70);
1129         b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x15);
1130 +       usleep_range(70, 140);
1131 +
1132 +       if (special)
1133 +               b43_radio_mask(dev, R2057_RCCAL_MASTER, ~0x1);
1134 +       else
1135 +               b43_radio_mask(dev, R2057v7_RCCAL_MASTER, ~0x1);
1136 +
1137         return tmp;
1138  }
1139  
1140 @@ -700,13 +957,11 @@ static void b43_radio_2057_init_post(str
1141         b43_radio_mask(dev, R2057_RFPLL_MISC_CAL_RESETN, ~0x78);
1142         b43_radio_mask(dev, R2057_XTAL_CONFIG2, ~0x80);
1143  
1144 -       if (dev->phy.n->init_por) {
1145 +       if (dev->phy.do_full_init) {
1146                 b43_radio_2057_rcal(dev);
1147                 b43_radio_2057_rccal(dev);
1148         }
1149         b43_radio_mask(dev, R2057_RFPLL_MASTER, ~0x8);
1150 -
1151 -       dev->phy.n->init_por = false;
1152  }
1153  
1154  /* http://bcm-v4.sipsolutions.net/802.11/Radio/2057/Init */
1155 @@ -800,6 +1055,7 @@ static void b43_chantab_radio_2056_uploa
1156  static void b43_radio_2056_setup(struct b43_wldev *dev,
1157                                 const struct b43_nphy_channeltab_entry_rev3 *e)
1158  {
1159 +       struct b43_phy *phy = &dev->phy;
1160         struct ssb_sprom *sprom = dev->dev->bus_sprom;
1161         enum ieee80211_band band = b43_current_band(dev->wl);
1162         u16 offset;
1163 @@ -897,7 +1153,7 @@ static void b43_radio_2056_setup(struct
1164                                         offset | B2056_TX_MIXG_BOOST_TUNE,
1165                                         mixg_boost);
1166                         } else {
1167 -                               bias = dev->phy.is_40mhz ? 0x40 : 0x20;
1168 +                               bias = b43_is_40mhz(dev) ? 0x40 : 0x20;
1169                                 b43_radio_write(dev,
1170                                         offset | B2056_TX_INTPAG_IMAIN_STAT,
1171                                         bias);
1172 @@ -911,7 +1167,7 @@ static void b43_radio_2056_setup(struct
1173                         b43_radio_write(dev, offset | B2056_TX_PA_SPARE1, 0xee);
1174                 }
1175         } else if (dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ) {
1176 -               u16 freq = dev->phy.channel_freq;
1177 +               u16 freq = phy->chandef->chan->center_freq;
1178                 if (freq < 5100) {
1179                         paa_boost = 0xA;
1180                         pada_boost = 0x77;
1181 @@ -1028,7 +1284,7 @@ static void b43_radio_init2056_post(stru
1182         b43_radio_mask(dev, B2056_SYN_COM_RESET, ~0x2);
1183         b43_radio_mask(dev, B2056_SYN_PLL_MAST2, ~0xFC);
1184         b43_radio_mask(dev, B2056_SYN_RCCAL_CTRL0, ~0x1);
1185 -       if (dev->phy.n->init_por)
1186 +       if (dev->phy.do_full_init)
1187                 b43_radio_2056_rcal(dev);
1188  }
1189  
1190 @@ -1041,8 +1297,6 @@ static void b43_radio_init2056(struct b4
1191         b43_radio_init2056_pre(dev);
1192         b2056_upload_inittabs(dev, 0, 0);
1193         b43_radio_init2056_post(dev);
1194 -
1195 -       dev->phy.n->init_por = false;
1196  }
1197  
1198  /**************************************************
1199 @@ -1214,8 +1468,7 @@ static u16 b43_nphy_gen_load_samples(str
1200         u16 bw, len, rot, angle;
1201         struct b43_c32 *samples;
1202  
1203 -
1204 -       bw = (dev->phy.is_40mhz) ? 40 : 20;
1205 +       bw = b43_is_40mhz(dev) ? 40 : 20;
1206         len = bw << 3;
1207  
1208         if (test) {
1209 @@ -1224,7 +1477,7 @@ static u16 b43_nphy_gen_load_samples(str
1210                 else
1211                         bw = 80;
1212  
1213 -               if (dev->phy.is_40mhz)
1214 +               if (b43_is_40mhz(dev))
1215                         bw <<= 1;
1216  
1217                 len = bw << 1;
1218 @@ -1252,8 +1505,10 @@ static u16 b43_nphy_gen_load_samples(str
1219  
1220  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RunSamples */
1221  static void b43_nphy_run_samples(struct b43_wldev *dev, u16 samps, u16 loops,
1222 -                                       u16 wait, bool iqmode, bool dac_test)
1223 +                                u16 wait, bool iqmode, bool dac_test,
1224 +                                bool modify_bbmult)
1225  {
1226 +       struct b43_phy *phy = &dev->phy;
1227         struct b43_phy_n *nphy = dev->phy.n;
1228         int i;
1229         u16 seq_mode;
1230 @@ -1261,17 +1516,35 @@ static void b43_nphy_run_samples(struct
1231  
1232         b43_nphy_stay_in_carrier_search(dev, true);
1233  
1234 +       if (phy->rev >= 7) {
1235 +               bool lpf_bw3, lpf_bw4;
1236 +
1237 +               lpf_bw3 = b43_phy_read(dev, B43_NPHY_REV7_RF_CTL_OVER3) & 0x80;
1238 +               lpf_bw4 = b43_phy_read(dev, B43_NPHY_REV7_RF_CTL_OVER3) & 0x80;
1239 +
1240 +               if (lpf_bw3 || lpf_bw4) {
1241 +                       /* TODO */
1242 +               } else {
1243 +                       u16 value = b43_nphy_read_lpf_ctl(dev, 0);
1244 +                       if (phy->rev >= 19)
1245 +                               b43_nphy_rf_ctl_override_rev19(dev, 0x80, value,
1246 +                                                              0, false, 1);
1247 +                       else
1248 +                               b43_nphy_rf_ctl_override_rev7(dev, 0x80, value,
1249 +                                                             0, false, 1);
1250 +                       nphy->lpf_bw_overrode_for_sample_play = true;
1251 +               }
1252 +       }
1253 +
1254         if ((nphy->bb_mult_save & 0x80000000) == 0) {
1255                 tmp = b43_ntab_read(dev, B43_NTAB16(15, 87));
1256                 nphy->bb_mult_save = (tmp & 0xFFFF) | 0x80000000;
1257         }
1258  
1259 -       /* TODO: add modify_bbmult argument */
1260 -       if (!dev->phy.is_40mhz)
1261 -               tmp = 0x6464;
1262 -       else
1263 -               tmp = 0x4747;
1264 -       b43_ntab_write(dev, B43_NTAB16(15, 87), tmp);
1265 +       if (modify_bbmult) {
1266 +               tmp = !b43_is_40mhz(dev) ? 0x6464 : 0x4747;
1267 +               b43_ntab_write(dev, B43_NTAB16(15, 87), tmp);
1268 +       }
1269  
1270         b43_phy_write(dev, B43_NPHY_SAMP_DEPCNT, (samps - 1));
1271  
1272 @@ -1289,10 +1562,8 @@ static void b43_nphy_run_samples(struct
1273                 b43_phy_mask(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x7FFF);
1274                 b43_phy_set(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8000);
1275         } else {
1276 -               if (dac_test)
1277 -                       b43_phy_write(dev, B43_NPHY_SAMP_CMD, 5);
1278 -               else
1279 -                       b43_phy_write(dev, B43_NPHY_SAMP_CMD, 1);
1280 +               tmp = dac_test ? 5 : 1;
1281 +               b43_phy_write(dev, B43_NPHY_SAMP_CMD, tmp);
1282         }
1283         for (i = 0; i < 100; i++) {
1284                 if (!(b43_phy_read(dev, B43_NPHY_RFSEQST) & 1)) {
1285 @@ -1392,6 +1663,12 @@ static void b43_nphy_scale_offset_rssi(s
1286         }
1287  }
1288  
1289 +static void b43_nphy_rssi_select_rev19(struct b43_wldev *dev, u8 code,
1290 +                                      enum n_rssi_type rssi_type)
1291 +{
1292 +       /* TODO */
1293 +}
1294 +
1295  static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code,
1296                                       enum n_rssi_type rssi_type)
1297  {
1298 @@ -1461,13 +1738,15 @@ static void b43_nphy_rev3_rssi_select(st
1299                                         enum ieee80211_band band =
1300                                                 b43_current_band(dev->wl);
1301  
1302 -                                       if (b43_nphy_ipa(dev))
1303 -                                               val = (band == IEEE80211_BAND_5GHZ) ? 0xC : 0xE;
1304 -                                       else
1305 -                                               val = 0x11;
1306 -                                       reg = (i == 0) ? 0x2000 : 0x3000;
1307 -                                       reg |= B2055_PADDRV;
1308 -                                       b43_radio_write(dev, reg, val);
1309 +                                       if (dev->phy.rev < 7) {
1310 +                                               if (b43_nphy_ipa(dev))
1311 +                                                       val = (band == IEEE80211_BAND_5GHZ) ? 0xC : 0xE;
1312 +                                               else
1313 +                                                       val = 0x11;
1314 +                                               reg = (i == 0) ? B2056_TX0 : B2056_TX1;
1315 +                                               reg |= B2056_TX_TX_SSI_MUX;
1316 +                                               b43_radio_write(dev, reg, val);
1317 +                                       }
1318  
1319                                         reg = (i == 0) ?
1320                                                 B43_NPHY_AFECTL_OVER1 :
1321 @@ -1554,7 +1833,9 @@ static void b43_nphy_rev2_rssi_select(st
1322  static void b43_nphy_rssi_select(struct b43_wldev *dev, u8 code,
1323                                  enum n_rssi_type type)
1324  {
1325 -       if (dev->phy.rev >= 3)
1326 +       if (dev->phy.rev >= 19)
1327 +               b43_nphy_rssi_select_rev19(dev, code, type);
1328 +       else if (dev->phy.rev >= 3)
1329                 b43_nphy_rev3_rssi_select(dev, code, type);
1330         else
1331                 b43_nphy_rev2_rssi_select(dev, code, type);
1332 @@ -1598,6 +1879,8 @@ static int b43_nphy_poll_rssi(struct b43
1333         u16 save_regs_phy[9];
1334         u16 s[2];
1335  
1336 +       /* TODO: rev7+ is treated like rev3+, what about rev19+? */
1337 +
1338         if (dev->phy.rev >= 3) {
1339                 save_regs_phy[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
1340                 save_regs_phy[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
1341 @@ -1679,6 +1962,7 @@ static int b43_nphy_poll_rssi(struct b43
1342  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */
1343  static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
1344  {
1345 +       struct b43_phy *phy = &dev->phy;
1346         struct b43_phy_n *nphy = dev->phy.n;
1347  
1348         u16 saved_regs_phy_rfctl[2];
1349 @@ -1696,12 +1980,14 @@ static void b43_nphy_rev3_rssi_cal(struc
1350                 B43_NPHY_AFECTL_OVER1, B43_NPHY_AFECTL_OVER,
1351                 B43_NPHY_AFECTL_C1, B43_NPHY_AFECTL_C2,
1352                 B43_NPHY_TXF_40CO_B1S1, B43_NPHY_RFCTL_OVER,
1353 -               0x342, 0x343, 0x346, 0x347,
1354 +               B43_NPHY_REV7_RF_CTL_OVER3, B43_NPHY_REV7_RF_CTL_OVER4,
1355 +               B43_NPHY_REV7_RF_CTL_OVER5, B43_NPHY_REV7_RF_CTL_OVER6,
1356                 0x2ff,
1357                 B43_NPHY_TXF_40CO_B1S0, B43_NPHY_TXF_40CO_B32S1,
1358                 B43_NPHY_RFCTL_CMD,
1359                 B43_NPHY_RFCTL_LUT_TRSW_UP1, B43_NPHY_RFCTL_LUT_TRSW_UP2,
1360 -               0x340, 0x341, 0x344, 0x345,
1361 +               B43_NPHY_REV7_RF_CTL_MISC_REG3, B43_NPHY_REV7_RF_CTL_MISC_REG4,
1362 +               B43_NPHY_REV7_RF_CTL_MISC_REG5, B43_NPHY_REV7_RF_CTL_MISC_REG6,
1363                 B43_NPHY_RFCTL_RSSIO1, B43_NPHY_RFCTL_RSSIO2
1364         };
1365         u16 *regs_to_store;
1366 @@ -1748,9 +2034,24 @@ static void b43_nphy_rev3_rssi_cal(struc
1367         b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_TRSW, 1, 7);
1368  
1369         if (dev->phy.rev >= 7) {
1370 -               /* TODO */
1371 +               b43_nphy_rf_ctl_override_one_to_many(dev,
1372 +                                                    N_RF_CTL_OVER_CMD_RXRF_PU,
1373 +                                                    0, 0, false);
1374 +               b43_nphy_rf_ctl_override_one_to_many(dev,
1375 +                                                    N_RF_CTL_OVER_CMD_RX_PU,
1376 +                                                    1, 0, false);
1377 +               b43_nphy_rf_ctl_override_rev7(dev, 0x80, 1, 0, false, 0);
1378 +               b43_nphy_rf_ctl_override_rev7(dev, 0x80, 1, 0, false, 0);
1379                 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
1380 +                       b43_nphy_rf_ctl_override_rev7(dev, 0x20, 0, 0, false,
1381 +                                                     0);
1382 +                       b43_nphy_rf_ctl_override_rev7(dev, 0x10, 1, 0, false,
1383 +                                                     0);
1384                 } else {
1385 +                       b43_nphy_rf_ctl_override_rev7(dev, 0x10, 0, 0, false,
1386 +                                                     0);
1387 +                       b43_nphy_rf_ctl_override_rev7(dev, 0x20, 1, 0, false,
1388 +                                                     0);
1389                 }
1390         } else {
1391                 b43_nphy_rf_ctl_override(dev, 0x1, 0, 0, false);
1392 @@ -1779,7 +2080,10 @@ static void b43_nphy_rev3_rssi_cal(struc
1393                 /* Grab RSSI results for every possible VCM */
1394                 for (vcm = 0; vcm < 8; vcm++) {
1395                         if (dev->phy.rev >= 7)
1396 -                               ;
1397 +                               b43_radio_maskset(dev,
1398 +                                                 core ? R2057_NB_MASTER_CORE1 :
1399 +                                                        R2057_NB_MASTER_CORE0,
1400 +                                                 ~R2057_VCM_MASK, vcm);
1401                         else
1402                                 b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC,
1403                                                   0xE3, vcm << 2);
1404 @@ -1810,7 +2114,10 @@ static void b43_nphy_rev3_rssi_cal(struc
1405  
1406                 /* Select the best VCM */
1407                 if (dev->phy.rev >= 7)
1408 -                       ;
1409 +                       b43_radio_maskset(dev,
1410 +                                         core ? R2057_NB_MASTER_CORE1 :
1411 +                                                R2057_NB_MASTER_CORE0,
1412 +                                         ~R2057_VCM_MASK, vcm);
1413                 else
1414                         b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC,
1415                                           0xE3, vcm_final << 2);
1416 @@ -1880,6 +2187,10 @@ static void b43_nphy_rev3_rssi_cal(struc
1417                 rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G;
1418         }
1419         if (dev->phy.rev >= 7) {
1420 +               rssical_radio_regs[0] = b43_radio_read(dev,
1421 +                                                      R2057_NB_MASTER_CORE0);
1422 +               rssical_radio_regs[1] = b43_radio_read(dev,
1423 +                                                      R2057_NB_MASTER_CORE1);
1424         } else {
1425                 rssical_radio_regs[0] = b43_radio_read(dev, B2056_RX0 |
1426                                                        B2056_RX_RSSI_MISC);
1427 @@ -1901,9 +2212,9 @@ static void b43_nphy_rev3_rssi_cal(struc
1428  
1429         /* Remember for which channel we store configuration */
1430         if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
1431 -               nphy->rssical_chanspec_2G.center_freq = dev->phy.channel_freq;
1432 +               nphy->rssical_chanspec_2G.center_freq = phy->chandef->chan->center_freq;
1433         else
1434 -               nphy->rssical_chanspec_5G.center_freq = dev->phy.channel_freq;
1435 +               nphy->rssical_chanspec_5G.center_freq = phy->chandef->chan->center_freq;
1436  
1437         /* End of calibration, restore configuration */
1438         b43_nphy_classifier(dev, 7, class);
1439 @@ -2080,7 +2391,9 @@ static void b43_nphy_rev2_rssi_cal(struc
1440   */
1441  static void b43_nphy_rssi_cal(struct b43_wldev *dev)
1442  {
1443 -       if (dev->phy.rev >= 3) {
1444 +       if (dev->phy.rev >= 19) {
1445 +               /* TODO */
1446 +       } else if (dev->phy.rev >= 3) {
1447                 b43_nphy_rev3_rssi_cal(dev);
1448         } else {
1449                 b43_nphy_rev2_rssi_cal(dev, N_RSSI_NB);
1450 @@ -2093,7 +2406,21 @@ static void b43_nphy_rssi_cal(struct b43
1451   * Workarounds
1452   **************************************************/
1453  
1454 -static void b43_nphy_gain_ctl_workarounds_rev3plus(struct b43_wldev *dev)
1455 +static void b43_nphy_gain_ctl_workarounds_rev19(struct b43_wldev *dev)
1456 +{
1457 +       /* TODO */
1458 +}
1459 +
1460 +static void b43_nphy_gain_ctl_workarounds_rev7(struct b43_wldev *dev)
1461 +{
1462 +       struct b43_phy *phy = &dev->phy;
1463 +
1464 +       switch (phy->rev) {
1465 +       /* TODO */
1466 +       }
1467 +}
1468 +
1469 +static void b43_nphy_gain_ctl_workarounds_rev3(struct b43_wldev *dev)
1470  {
1471         struct ssb_sprom *sprom = dev->dev->bus_sprom;
1472  
1473 @@ -2196,7 +2523,7 @@ static void b43_nphy_gain_ctl_workaround
1474         b43_phy_write(dev, B43_NPHY_C1_NBCLIPTHRES, 0x84);
1475         b43_phy_write(dev, B43_NPHY_C2_NBCLIPTHRES, 0x84);
1476  
1477 -       if (!dev->phy.is_40mhz) {
1478 +       if (!b43_is_40mhz(dev)) {
1479                 /* Set dwell lengths */
1480                 b43_phy_write(dev, B43_NPHY_CLIP1_NBDWELL_LEN, 0x002B);
1481                 b43_phy_write(dev, B43_NPHY_CLIP2_NBDWELL_LEN, 0x002B);
1482 @@ -2210,7 +2537,7 @@ static void b43_nphy_gain_ctl_workaround
1483         b43_phy_maskset(dev, B43_NPHY_C2_CLIPWBTHRES,
1484                         ~B43_NPHY_C2_CLIPWBTHRES_CLIP2, 21);
1485  
1486 -       if (!dev->phy.is_40mhz) {
1487 +       if (!b43_is_40mhz(dev)) {
1488                 b43_phy_maskset(dev, B43_NPHY_C1_CGAINI,
1489                         ~B43_NPHY_C1_CGAINI_GAINBKOFF, 0x1);
1490                 b43_phy_maskset(dev, B43_NPHY_C2_CGAINI,
1491 @@ -2225,12 +2552,12 @@ static void b43_nphy_gain_ctl_workaround
1492  
1493         if (nphy->gain_boost) {
1494                 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ &&
1495 -                       dev->phy.is_40mhz)
1496 +                   b43_is_40mhz(dev))
1497                         code = 4;
1498                 else
1499                         code = 5;
1500         } else {
1501 -               code = dev->phy.is_40mhz ? 6 : 7;
1502 +               code = b43_is_40mhz(dev) ? 6 : 7;
1503         }
1504  
1505         /* Set HPVGA2 index */
1506 @@ -2290,22 +2617,16 @@ static void b43_nphy_gain_ctl_workaround
1507  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */
1508  static void b43_nphy_gain_ctl_workarounds(struct b43_wldev *dev)
1509  {
1510 -       if (dev->phy.rev >= 7)
1511 -               ; /* TODO */
1512 +       if (dev->phy.rev >= 19)
1513 +               b43_nphy_gain_ctl_workarounds_rev19(dev);
1514 +       else if (dev->phy.rev >= 7)
1515 +               b43_nphy_gain_ctl_workarounds_rev7(dev);
1516         else if (dev->phy.rev >= 3)
1517 -               b43_nphy_gain_ctl_workarounds_rev3plus(dev);
1518 +               b43_nphy_gain_ctl_workarounds_rev3(dev);
1519         else
1520                 b43_nphy_gain_ctl_workarounds_rev1_2(dev);
1521  }
1522  
1523 -/* http://bcm-v4.sipsolutions.net/PHY/N/Read_Lpf_Bw_Ctl */
1524 -static u16 b43_nphy_read_lpf_ctl(struct b43_wldev *dev, u16 offset)
1525 -{
1526 -       if (!offset)
1527 -               offset = (dev->phy.is_40mhz) ? 0x159 : 0x154;
1528 -       return b43_ntab_read(dev, B43_NTAB16(7, offset)) & 0x7;
1529 -}
1530 -
1531  static void b43_nphy_workarounds_rev7plus(struct b43_wldev *dev)
1532  {
1533         struct ssb_sprom *sprom = dev->dev->bus_sprom;
1534 @@ -2375,13 +2696,13 @@ static void b43_nphy_workarounds_rev7plu
1535         lpf_40 = b43_nphy_read_lpf_ctl(dev, 0x159);
1536         lpf_11b = b43_nphy_read_lpf_ctl(dev, 0x152);
1537         if (b43_nphy_ipa(dev)) {
1538 -               if ((phy->radio_rev == 5 && phy->is_40mhz) ||
1539 +               if ((phy->radio_rev == 5 && b43_is_40mhz(dev)) ||
1540                     phy->radio_rev == 7 || phy->radio_rev == 8) {
1541                         bcap_val = b43_radio_read(dev, 0x16b);
1542                         scap_val = b43_radio_read(dev, 0x16a);
1543                         scap_val_11b = scap_val;
1544                         bcap_val_11b = bcap_val;
1545 -                       if (phy->radio_rev == 5 && phy->is_40mhz) {
1546 +                       if (phy->radio_rev == 5 && b43_is_40mhz(dev)) {
1547                                 scap_val_11n_20 = scap_val;
1548                                 bcap_val_11n_20 = bcap_val;
1549                                 scap_val_11n_40 = bcap_val_11n_40 = 0xc;
1550 @@ -2523,7 +2844,7 @@ static void b43_nphy_workarounds_rev7plu
1551                                         }
1552                                 }
1553                         } else if (phy->radio_rev == 7 || phy->radio_rev == 8) {
1554 -                               if (!phy->is_40mhz) {
1555 +                               if (!b43_is_40mhz(dev)) {
1556                                         b43_radio_write(dev, 0x5F, 0x14);
1557                                         b43_radio_write(dev, 0xE8, 0x12);
1558                                 } else {
1559 @@ -2532,7 +2853,7 @@ static void b43_nphy_workarounds_rev7plu
1560                                 }
1561                         }
1562                 } else {
1563 -                       u16 freq = phy->channel_freq;
1564 +                       u16 freq = phy->chandef->chan->center_freq;
1565                         if ((freq >= 5180 && freq <= 5230) ||
1566                             (freq >= 5745 && freq <= 5805)) {
1567                                 b43_radio_write(dev, 0x7D, 0xFF);
1568 @@ -2596,7 +2917,7 @@ static void b43_nphy_workarounds_rev7plu
1569         b43_ntab_write(dev, B43_NTAB16(7, 0x123), 0x77);
1570         b43_ntab_write(dev, B43_NTAB16(7, 0x12A), 0x77);
1571  
1572 -       if (!phy->is_40mhz) {
1573 +       if (!b43_is_40mhz(dev)) {
1574                 b43_ntab_write(dev, B43_NTAB32(16, 0x03), 0x18D);
1575                 b43_ntab_write(dev, B43_NTAB32(16, 0x7F), 0x18D);
1576         } else {
1577 @@ -2695,7 +3016,7 @@ static void b43_nphy_workarounds_rev3plu
1578  
1579         b43_phy_maskset(dev, B43_NPHY_SGILTRNOFFSET, 0xF0FF, 0x0700);
1580  
1581 -       if (!dev->phy.is_40mhz) {
1582 +       if (!b43_is_40mhz(dev)) {
1583                 b43_ntab_write(dev, B43_NTAB32(16, 3), 0x18D);
1584                 b43_ntab_write(dev, B43_NTAB32(16, 127), 0x18D);
1585         } else {
1586 @@ -2930,6 +3251,7 @@ static void b43_nphy_workarounds(struct
1587         b43_phy_set(dev, B43_NPHY_IQFLIP,
1588                     B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2);
1589  
1590 +       /* TODO: rev19+ */
1591         if (dev->phy.rev >= 7)
1592                 b43_nphy_workarounds_rev7plus(dev);
1593         else if (dev->phy.rev >= 3)
1594 @@ -2950,12 +3272,13 @@ static void b43_nphy_workarounds(struct
1595   * http://bcm-v4.sipsolutions.net/802.11/PHY/N/TXTone
1596   */
1597  static int b43_nphy_tx_tone(struct b43_wldev *dev, u32 freq, u16 max_val,
1598 -                               bool iqmode, bool dac_test)
1599 +                           bool iqmode, bool dac_test, bool modify_bbmult)
1600  {
1601         u16 samp = b43_nphy_gen_load_samples(dev, freq, max_val, dac_test);
1602         if (samp == 0)
1603                 return -1;
1604 -       b43_nphy_run_samples(dev, samp, 0xFFFF, 0, iqmode, dac_test);
1605 +       b43_nphy_run_samples(dev, samp, 0xFFFF, 0, iqmode, dac_test,
1606 +                            modify_bbmult);
1607         return 0;
1608  }
1609  
1610 @@ -2990,6 +3313,7 @@ static void b43_nphy_update_txrx_chain(s
1611  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/stop-playback */
1612  static void b43_nphy_stop_playback(struct b43_wldev *dev)
1613  {
1614 +       struct b43_phy *phy = &dev->phy;
1615         struct b43_phy_n *nphy = dev->phy.n;
1616         u16 tmp;
1617  
1618 @@ -3010,6 +3334,15 @@ static void b43_nphy_stop_playback(struc
1619                 nphy->bb_mult_save = 0;
1620         }
1621  
1622 +       if (phy->rev >= 7) {
1623 +               if (phy->rev >= 19)
1624 +                       b43_nphy_rf_ctl_override_rev19(dev, 0x80, 0, 0, true,
1625 +                                                      1);
1626 +               else
1627 +                       b43_nphy_rf_ctl_override_rev7(dev, 0x80, 0, 0, true, 1);
1628 +               nphy->lpf_bw_overrode_for_sample_play = false;
1629 +       }
1630 +
1631         if (nphy->hang_avoid)
1632                 b43_nphy_stay_in_carrier_search(dev, 0);
1633  }
1634 @@ -3019,16 +3352,23 @@ static void b43_nphy_iq_cal_gain_params(
1635                                         struct nphy_txgains target,
1636                                         struct nphy_iqcal_params *params)
1637  {
1638 +       struct b43_phy *phy = &dev->phy;
1639         int i, j, indx;
1640         u16 gain;
1641  
1642         if (dev->phy.rev >= 3) {
1643 +               params->tx_lpf = target.tx_lpf[core]; /* Rev 7+ */
1644                 params->txgm = target.txgm[core];
1645                 params->pga = target.pga[core];
1646                 params->pad = target.pad[core];
1647                 params->ipa = target.ipa[core];
1648 -               params->cal_gain = (params->txgm << 12) | (params->pga << 8) |
1649 -                                       (params->pad << 4) | (params->ipa);
1650 +               if (phy->rev >= 19) {
1651 +                       /* TODO */
1652 +               } else if (phy->rev >= 7) {
1653 +                       params->cal_gain = (params->txgm << 12) | (params->pga << 8) | (params->pad << 3) | (params->ipa) | (params->tx_lpf << 15);
1654 +               } else {
1655 +                       params->cal_gain = (params->txgm << 12) | (params->pga << 8) | (params->pad << 4) | (params->ipa);
1656 +               }
1657                 for (j = 0; j < 5; j++)
1658                         params->ncorr[j] = 0x79;
1659         } else {
1660 @@ -3069,6 +3409,7 @@ static enum b43_txpwr_result b43_nphy_op
1661  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlEnable */
1662  static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable)
1663  {
1664 +       struct b43_phy *phy = &dev->phy;
1665         struct b43_phy_n *nphy = dev->phy.n;
1666         u8 i;
1667         u16 bmask, val, tmp;
1668 @@ -3118,7 +3459,7 @@ static void b43_nphy_tx_power_ctrl(struc
1669                         b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3,
1670                                 ~B43_NPHY_BPHY_CTL3_SCALE, 0x5A);
1671  
1672 -               if (dev->phy.rev < 2 && dev->phy.is_40mhz)
1673 +               if (dev->phy.rev < 2 && b43_is_40mhz(dev))
1674                         b43_hf_write(dev, b43_hf_read(dev) | B43_HF_TSSIRPSMW);
1675         } else {
1676                 b43_ntab_write_bulk(dev, B43_NTAB16(26, 64), 84,
1677 @@ -3138,12 +3479,25 @@ static void b43_nphy_tx_power_ctrl(struc
1678                 b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD, ~(bmask), val);
1679  
1680                 if (band == IEEE80211_BAND_5GHZ) {
1681 -                       b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD,
1682 -                                       ~B43_NPHY_TXPCTL_CMD_INIT, 0x64);
1683 -                       if (dev->phy.rev > 1)
1684 +                       if (phy->rev >= 19) {
1685 +                               /* TODO */
1686 +                       } else if (phy->rev >= 7) {
1687 +                               b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD,
1688 +                                               ~B43_NPHY_TXPCTL_CMD_INIT,
1689 +                                               0x32);
1690                                 b43_phy_maskset(dev, B43_NPHY_TXPCTL_INIT,
1691                                                 ~B43_NPHY_TXPCTL_INIT_PIDXI1,
1692 +                                               0x32);
1693 +                       } else {
1694 +                               b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD,
1695 +                                               ~B43_NPHY_TXPCTL_CMD_INIT,
1696                                                 0x64);
1697 +                               if (phy->rev > 1)
1698 +                                       b43_phy_maskset(dev,
1699 +                                                       B43_NPHY_TXPCTL_INIT,
1700 +                                                       ~B43_NPHY_TXPCTL_INIT_PIDXI1,
1701 +                                                       0x64);
1702 +                       }
1703                 }
1704  
1705                 if (dev->phy.rev >= 3) {
1706 @@ -3160,6 +3514,10 @@ static void b43_nphy_tx_power_ctrl(struc
1707                         }
1708                 }
1709  
1710 +               if (phy->rev >= 7) {
1711 +                       /* TODO */
1712 +               }
1713 +
1714                 if (dev->phy.rev >= 3) {
1715                         b43_phy_mask(dev, B43_NPHY_AFECTL_OVER1, ~0x100);
1716                         b43_phy_mask(dev, B43_NPHY_AFECTL_OVER, ~0x100);
1717 @@ -3172,7 +3530,7 @@ static void b43_nphy_tx_power_ctrl(struc
1718                 else if (dev->phy.rev < 2)
1719                         b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3, ~0xFF, 0x40);
1720  
1721 -               if (dev->phy.rev < 2 && dev->phy.is_40mhz)
1722 +               if (dev->phy.rev < 2 && b43_is_40mhz(dev))
1723                         b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_TSSIRPSMW);
1724  
1725                 if (b43_nphy_ipa(dev)) {
1726 @@ -3188,18 +3546,20 @@ static void b43_nphy_tx_power_ctrl(struc
1727  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrFix */
1728  static void b43_nphy_tx_power_fix(struct b43_wldev *dev)
1729  {
1730 +       struct b43_phy *phy = &dev->phy;
1731         struct b43_phy_n *nphy = dev->phy.n;
1732         struct ssb_sprom *sprom = dev->dev->bus_sprom;
1733  
1734         u8 txpi[2], bbmult, i;
1735         u16 tmp, radio_gain, dac_gain;
1736 -       u16 freq = dev->phy.channel_freq;
1737 +       u16 freq = phy->chandef->chan->center_freq;
1738         u32 txgain;
1739         /* u32 gaintbl; rev3+ */
1740  
1741         if (nphy->hang_avoid)
1742                 b43_nphy_stay_in_carrier_search(dev, 1);
1743  
1744 +       /* TODO: rev19+ */
1745         if (dev->phy.rev >= 7) {
1746                 txpi[0] = txpi[1] = 30;
1747         } else if (dev->phy.rev >= 3) {
1748 @@ -3238,7 +3598,11 @@ static void b43_nphy_tx_power_fix(struct
1749         */
1750  
1751         for (i = 0; i < 2; i++) {
1752 -               txgain = *(b43_nphy_get_tx_gain_table(dev) + txpi[i]);
1753 +               const u32 *table = b43_nphy_get_tx_gain_table(dev);
1754 +
1755 +               if (!table)
1756 +                       break;
1757 +               txgain = *(table + txpi[i]);
1758  
1759                 if (dev->phy.rev >= 3)
1760                         radio_gain = (txgain >> 16) & 0x1FFFF;
1761 @@ -3298,7 +3662,9 @@ static void b43_nphy_ipa_internal_tssi_s
1762         u8 core;
1763         u16 r; /* routing */
1764  
1765 -       if (phy->rev >= 7) {
1766 +       if (phy->rev >= 19) {
1767 +               /* TODO */
1768 +       } else if (phy->rev >= 7) {
1769                 for (core = 0; core < 2; core++) {
1770                         r = core ? 0x190 : 0x170;
1771                         if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
1772 @@ -3386,24 +3752,32 @@ static void b43_nphy_tx_power_ctl_idle_t
1773         if (b43_nphy_ipa(dev))
1774                 b43_nphy_ipa_internal_tssi_setup(dev);
1775  
1776 -       if (phy->rev >= 7)
1777 +       if (phy->rev >= 19)
1778 +               b43_nphy_rf_ctl_override_rev19(dev, 0x2000, 0, 3, false, 0);
1779 +       else if (phy->rev >= 7)
1780                 b43_nphy_rf_ctl_override_rev7(dev, 0x2000, 0, 3, false, 0);
1781         else if (phy->rev >= 3)
1782                 b43_nphy_rf_ctl_override(dev, 0x2000, 0, 3, false);
1783  
1784         b43_nphy_stop_playback(dev);
1785 -       b43_nphy_tx_tone(dev, 0xFA0, 0, false, false);
1786 +       b43_nphy_tx_tone(dev, 4000, 0, false, false, false);
1787         udelay(20);
1788         tmp = b43_nphy_poll_rssi(dev, N_RSSI_TSSI_2G, rssi, 1);
1789         b43_nphy_stop_playback(dev);
1790 +
1791         b43_nphy_rssi_select(dev, 0, N_RSSI_W1);
1792  
1793 -       if (phy->rev >= 7)
1794 +       if (phy->rev >= 19)
1795 +               b43_nphy_rf_ctl_override_rev19(dev, 0x2000, 0, 3, true, 0);
1796 +       else if (phy->rev >= 7)
1797                 b43_nphy_rf_ctl_override_rev7(dev, 0x2000, 0, 3, true, 0);
1798         else if (phy->rev >= 3)
1799                 b43_nphy_rf_ctl_override(dev, 0x2000, 0, 3, true);
1800  
1801 -       if (phy->rev >= 3) {
1802 +       if (phy->rev >= 19) {
1803 +               /* TODO */
1804 +               return;
1805 +       } else if (phy->rev >= 3) {
1806                 nphy->pwr_ctl_info[0].idle_tssi_5g = (tmp >> 24) & 0xFF;
1807                 nphy->pwr_ctl_info[1].idle_tssi_5g = (tmp >> 8) & 0xFF;
1808         } else {
1809 @@ -3443,21 +3817,21 @@ static void b43_nphy_tx_prepare_adjusted
1810                 delta = 0;
1811                 switch (stf_mode) {
1812                 case 0:
1813 -                       if (dev->phy.is_40mhz && dev->phy.rev >= 5) {
1814 +                       if (b43_is_40mhz(dev) && dev->phy.rev >= 5) {
1815                                 idx = 68;
1816                         } else {
1817                                 delta = 1;
1818 -                               idx = dev->phy.is_40mhz ? 52 : 4;
1819 +                               idx = b43_is_40mhz(dev) ? 52 : 4;
1820                         }
1821                         break;
1822                 case 1:
1823 -                       idx = dev->phy.is_40mhz ? 76 : 28;
1824 +                       idx = b43_is_40mhz(dev) ? 76 : 28;
1825                         break;
1826                 case 2:
1827 -                       idx = dev->phy.is_40mhz ? 84 : 36;
1828 +                       idx = b43_is_40mhz(dev) ? 84 : 36;
1829                         break;
1830                 case 3:
1831 -                       idx = dev->phy.is_40mhz ? 92 : 44;
1832 +                       idx = b43_is_40mhz(dev) ? 92 : 44;
1833                         break;
1834                 }
1835  
1836 @@ -3478,6 +3852,7 @@ static void b43_nphy_tx_prepare_adjusted
1837  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlSetup */
1838  static void b43_nphy_tx_power_ctl_setup(struct b43_wldev *dev)
1839  {
1840 +       struct b43_phy *phy = &dev->phy;
1841         struct b43_phy_n *nphy = dev->phy.n;
1842         struct ssb_sprom *sprom = dev->dev->bus_sprom;
1843  
1844 @@ -3487,7 +3862,7 @@ static void b43_nphy_tx_power_ctl_setup(
1845         s32 num, den, pwr;
1846         u32 regval[64];
1847  
1848 -       u16 freq = dev->phy.channel_freq;
1849 +       u16 freq = phy->chandef->chan->center_freq;
1850         u16 tmp;
1851         u16 r; /* routing */
1852         u8 i, c;
1853 @@ -3594,7 +3969,9 @@ static void b43_nphy_tx_power_ctl_setup(
1854                 udelay(1);
1855         }
1856  
1857 -       if (dev->phy.rev >= 7) {
1858 +       if (phy->rev >= 19) {
1859 +               /* TODO */
1860 +       } else if (phy->rev >= 7) {
1861                 b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD,
1862                                 ~B43_NPHY_TXPCTL_CMD_INIT, 0x19);
1863                 b43_phy_maskset(dev, B43_NPHY_TXPCTL_INIT,
1864 @@ -3651,27 +4028,36 @@ static void b43_nphy_tx_gain_table_uploa
1865         int i;
1866  
1867         table = b43_nphy_get_tx_gain_table(dev);
1868 +       if (!table)
1869 +               return;
1870 +
1871         b43_ntab_write_bulk(dev, B43_NTAB32(26, 192), 128, table);
1872         b43_ntab_write_bulk(dev, B43_NTAB32(27, 192), 128, table);
1873  
1874 -       if (phy->rev >= 3) {
1875 +       if (phy->rev < 3)
1876 +               return;
1877 +
1878  #if 0
1879 -               nphy->gmval = (table[0] >> 16) & 0x7000;
1880 +       nphy->gmval = (table[0] >> 16) & 0x7000;
1881  #endif
1882  
1883 -               for (i = 0; i < 128; i++) {
1884 +       for (i = 0; i < 128; i++) {
1885 +               if (phy->rev >= 19) {
1886 +                       /* TODO */
1887 +                       return;
1888 +               } else if (phy->rev >= 7) {
1889 +                       /* TODO */
1890 +                       return;
1891 +               } else {
1892                         pga_gain = (table[i] >> 24) & 0xF;
1893                         if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
1894 -                               rfpwr_offset =
1895 -                                b43_ntab_papd_pga_gain_delta_ipa_2g[pga_gain];
1896 +                               rfpwr_offset = b43_ntab_papd_pga_gain_delta_ipa_2g[pga_gain];
1897                         else
1898 -                               rfpwr_offset =
1899 -                                0; /* FIXME */
1900 -                       b43_ntab_write(dev, B43_NTAB32(26, 576 + i),
1901 -                                      rfpwr_offset);
1902 -                       b43_ntab_write(dev, B43_NTAB32(27, 576 + i),
1903 -                                      rfpwr_offset);
1904 +                               rfpwr_offset = 0; /* FIXME */
1905                 }
1906 +
1907 +               b43_ntab_write(dev, B43_NTAB32(26, 576 + i), rfpwr_offset);
1908 +               b43_ntab_write(dev, B43_NTAB32(27, 576 + i), rfpwr_offset);
1909         }
1910  }
1911  
1912 @@ -3688,7 +4074,9 @@ static void b43_nphy_pa_override(struct
1913                 nphy->rfctrl_intc2_save = b43_phy_read(dev,
1914                                                        B43_NPHY_RFCTL_INTC2);
1915                 band = b43_current_band(dev->wl);
1916 -               if (dev->phy.rev >= 3) {
1917 +               if (dev->phy.rev >= 7) {
1918 +                       tmp = 0x1480;
1919 +               } else if (dev->phy.rev >= 3) {
1920                         if (band == IEEE80211_BAND_5GHZ)
1921                                 tmp = 0x600;
1922                         else
1923 @@ -3709,21 +4097,28 @@ static void b43_nphy_pa_override(struct
1924         }
1925  }
1926  
1927 -/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxLpFbw */
1928 -static void b43_nphy_tx_lp_fbw(struct b43_wldev *dev)
1929 +/*
1930 + * TX low-pass filter bandwidth setup
1931 + * http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxLpFbw
1932 + */
1933 +static void b43_nphy_tx_lpf_bw(struct b43_wldev *dev)
1934  {
1935         u16 tmp;
1936  
1937 -       if (dev->phy.rev >= 3) {
1938 -               if (b43_nphy_ipa(dev)) {
1939 -                       tmp = 4;
1940 -                       b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S2,
1941 -                             (((((tmp << 3) | tmp) << 3) | tmp) << 3) | tmp);
1942 -               }
1943 +       if (dev->phy.rev < 3 || dev->phy.rev >= 7)
1944 +               return;
1945 +
1946 +       if (b43_nphy_ipa(dev))
1947 +               tmp = b43_is_40mhz(dev) ? 5 : 4;
1948 +       else
1949 +               tmp = b43_is_40mhz(dev) ? 3 : 1;
1950 +       b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S2,
1951 +                     (tmp << 9) | (tmp << 6) | (tmp << 3) | tmp);
1952  
1953 -               tmp = 1;
1954 +       if (b43_nphy_ipa(dev)) {
1955 +               tmp = b43_is_40mhz(dev) ? 4 : 1;
1956                 b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S2,
1957 -                             (((((tmp << 3) | tmp) << 3) | tmp) << 3) | tmp);
1958 +                             (tmp << 9) | (tmp << 6) | (tmp << 3) | tmp);
1959         }
1960  }
1961  
1962 @@ -3996,7 +4391,7 @@ static void b43_nphy_spur_workaround(str
1963  
1964         if (nphy->gband_spurwar_en) {
1965                 /* TODO: N PHY Adjust Analog Pfbw (7) */
1966 -               if (channel == 11 && dev->phy.is_40mhz)
1967 +               if (channel == 11 && b43_is_40mhz(dev))
1968                         ; /* TODO: N PHY Adjust Min Noise Var(2, tone, noise)*/
1969                 else
1970                         ; /* TODO: N PHY Adjust Min Noise Var(0, NULL, NULL)*/
1971 @@ -4128,7 +4523,13 @@ static void b43_nphy_restore_rssi_cal(st
1972                 rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G;
1973         }
1974  
1975 -       if (dev->phy.rev >= 7) {
1976 +       if (dev->phy.rev >= 19) {
1977 +               /* TODO */
1978 +       } else if (dev->phy.rev >= 7) {
1979 +               b43_radio_maskset(dev, R2057_NB_MASTER_CORE0, ~R2057_VCM_MASK,
1980 +                                 rssical_radio_regs[0]);
1981 +               b43_radio_maskset(dev, R2057_NB_MASTER_CORE1, ~R2057_VCM_MASK,
1982 +                                 rssical_radio_regs[1]);
1983         } else {
1984                 b43_radio_maskset(dev, B2056_RX0 | B2056_RX_RSSI_MISC, 0xE3,
1985                                   rssical_radio_regs[0]);
1986 @@ -4152,15 +4553,78 @@ static void b43_nphy_restore_rssi_cal(st
1987         b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Y, rssical_phy_regs[11]);
1988  }
1989  
1990 +static void b43_nphy_tx_cal_radio_setup_rev19(struct b43_wldev *dev)
1991 +{
1992 +       /* TODO */
1993 +}
1994 +
1995 +static void b43_nphy_tx_cal_radio_setup_rev7(struct b43_wldev *dev)
1996 +{
1997 +       struct b43_phy *phy = &dev->phy;
1998 +       struct b43_phy_n *nphy = dev->phy.n;
1999 +       u16 *save = nphy->tx_rx_cal_radio_saveregs;
2000 +       int core, off;
2001 +       u16 r, tmp;
2002 +
2003 +       for (core = 0; core < 2; core++) {
2004 +               r = core ? 0x20 : 0;
2005 +               off = core * 11;
2006 +
2007 +               save[off + 0] = b43_radio_read(dev, r + R2057_TX0_TX_SSI_MASTER);
2008 +               save[off + 1] = b43_radio_read(dev, r + R2057_TX0_IQCAL_VCM_HG);
2009 +               save[off + 2] = b43_radio_read(dev, r + R2057_TX0_IQCAL_IDAC);
2010 +               save[off + 3] = b43_radio_read(dev, r + R2057_TX0_TSSI_VCM);
2011 +               save[off + 4] = 0;
2012 +               save[off + 5] = b43_radio_read(dev, r + R2057_TX0_TX_SSI_MUX);
2013 +               if (phy->radio_rev != 5)
2014 +                       save[off + 6] = b43_radio_read(dev, r + R2057_TX0_TSSIA);
2015 +               save[off + 7] = b43_radio_read(dev, r + R2057_TX0_TSSIG);
2016 +               save[off + 8] = b43_radio_read(dev, r + R2057_TX0_TSSI_MISC1);
2017 +
2018 +               if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
2019 +                       b43_radio_write(dev, r + R2057_TX0_TX_SSI_MASTER, 0xA);
2020 +                       b43_radio_write(dev, r + R2057_TX0_IQCAL_VCM_HG, 0x43);
2021 +                       b43_radio_write(dev, r + R2057_TX0_IQCAL_IDAC, 0x55);
2022 +                       b43_radio_write(dev, r + R2057_TX0_TSSI_VCM, 0);
2023 +                       b43_radio_write(dev, r + R2057_TX0_TSSIG, 0);
2024 +                       if (nphy->use_int_tx_iq_lo_cal) {
2025 +                               b43_radio_write(dev, r + R2057_TX0_TX_SSI_MUX, 0x4);
2026 +                               tmp = true ? 0x31 : 0x21; /* TODO */
2027 +                               b43_radio_write(dev, r + R2057_TX0_TSSIA, tmp);
2028 +                       }
2029 +                       b43_radio_write(dev, r + R2057_TX0_TSSI_MISC1, 0x00);
2030 +               } else {
2031 +                       b43_radio_write(dev, r + R2057_TX0_TX_SSI_MASTER, 0x6);
2032 +                       b43_radio_write(dev, r + R2057_TX0_IQCAL_VCM_HG, 0x43);
2033 +                       b43_radio_write(dev, r + R2057_TX0_IQCAL_IDAC, 0x55);
2034 +                       b43_radio_write(dev, r + R2057_TX0_TSSI_VCM, 0);
2035 +
2036 +                       if (phy->radio_rev != 5)
2037 +                               b43_radio_write(dev, r + R2057_TX0_TSSIA, 0);
2038 +                       if (nphy->use_int_tx_iq_lo_cal) {
2039 +                               b43_radio_write(dev, r + R2057_TX0_TX_SSI_MUX, 0x6);
2040 +                               tmp = true ? 0x31 : 0x21; /* TODO */
2041 +                               b43_radio_write(dev, r + R2057_TX0_TSSIG, tmp);
2042 +                       }
2043 +                       b43_radio_write(dev, r + R2057_TX0_TSSI_MISC1, 0);
2044 +               }
2045 +       }
2046 +}
2047 +
2048  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalRadioSetup */
2049  static void b43_nphy_tx_cal_radio_setup(struct b43_wldev *dev)
2050  {
2051 +       struct b43_phy *phy = &dev->phy;
2052         struct b43_phy_n *nphy = dev->phy.n;
2053         u16 *save = nphy->tx_rx_cal_radio_saveregs;
2054         u16 tmp;
2055         u8 offset, i;
2056  
2057 -       if (dev->phy.rev >= 3) {
2058 +       if (phy->rev >= 19) {
2059 +               b43_nphy_tx_cal_radio_setup_rev19(dev);
2060 +       } else if (phy->rev >= 7) {
2061 +               b43_nphy_tx_cal_radio_setup_rev7(dev);
2062 +       } else if (phy->rev >= 3) {
2063             for (i = 0; i < 2; i++) {
2064                 tmp = (i == 0) ? 0x2000 : 0x3000;
2065                 offset = i * 11;
2066 @@ -4290,7 +4754,7 @@ static void b43_nphy_int_pa_set_tx_dig_f
2067                         b43_phy_write(dev, B43_PHY_N(offset[i] + j),
2068                                         tbl_tx_filter_coef_rev4[i][j]);
2069  
2070 -       if (dev->phy.is_40mhz) {
2071 +       if (b43_is_40mhz(dev)) {
2072                 for (j = 0; j < 15; j++)
2073                         b43_phy_write(dev, B43_PHY_N(offset[0] + j),
2074                                         tbl_tx_filter_coef_rev4[3][j]);
2075 @@ -4325,7 +4789,13 @@ static struct nphy_txgains b43_nphy_get_
2076                         b43_nphy_stay_in_carrier_search(dev, false);
2077  
2078                 for (i = 0; i < 2; ++i) {
2079 -                       if (dev->phy.rev >= 3) {
2080 +                       if (dev->phy.rev >= 7) {
2081 +                               target.ipa[i] = curr_gain[i] & 0x0007;
2082 +                               target.pad[i] = (curr_gain[i] & 0x00F8) >> 3;
2083 +                               target.pga[i] = (curr_gain[i] & 0x0F00) >> 8;
2084 +                               target.txgm[i] = (curr_gain[i] & 0x7000) >> 12;
2085 +                               target.tx_lpf[i] = (curr_gain[i] & 0x8000) >> 15;
2086 +                       } else if (dev->phy.rev >= 3) {
2087                                 target.ipa[i] = curr_gain[i] & 0x000F;
2088                                 target.pad[i] = (curr_gain[i] & 0x00F0) >> 4;
2089                                 target.pga[i] = (curr_gain[i] & 0x0F00) >> 8;
2090 @@ -4349,7 +4819,16 @@ static struct nphy_txgains b43_nphy_get_
2091  
2092                 for (i = 0; i < 2; ++i) {
2093                         table = b43_nphy_get_tx_gain_table(dev);
2094 -                       if (dev->phy.rev >= 3) {
2095 +                       if (!table)
2096 +                               break;
2097 +
2098 +                       if (dev->phy.rev >= 7) {
2099 +                               target.ipa[i] = (table[index[i]] >> 16) & 0x7;
2100 +                               target.pad[i] = (table[index[i]] >> 19) & 0x1F;
2101 +                               target.pga[i] = (table[index[i]] >> 24) & 0xF;
2102 +                               target.txgm[i] = (table[index[i]] >> 28) & 0x7;
2103 +                               target.tx_lpf[i] = (table[index[i]] >> 31) & 0x1;
2104 +                       } else if (dev->phy.rev >= 3) {
2105                                 target.ipa[i] = (table[index[i]] >> 16) & 0xF;
2106                                 target.pad[i] = (table[index[i]] >> 20) & 0xF;
2107                                 target.pga[i] = (table[index[i]] >> 24) & 0xF;
2108 @@ -4398,6 +4877,8 @@ static void b43_nphy_tx_cal_phy_cleanup(
2109  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalPhySetup */
2110  static void b43_nphy_tx_cal_phy_setup(struct b43_wldev *dev)
2111  {
2112 +       struct b43_phy *phy = &dev->phy;
2113 +       struct b43_phy_n *nphy = dev->phy.n;
2114         u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs;
2115         u16 tmp;
2116  
2117 @@ -4429,7 +4910,12 @@ static void b43_nphy_tx_cal_phy_setup(st
2118                 regs[7] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
2119                 regs[8] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
2120  
2121 -               b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_PA, 1, 3);
2122 +               if (!nphy->use_int_tx_iq_lo_cal)
2123 +                       b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_PA,
2124 +                                                     1, 3);
2125 +               else
2126 +                       b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_PA,
2127 +                                                     0, 3);
2128                 b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_TRSW, 2, 1);
2129                 b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_TRSW, 8, 2);
2130  
2131 @@ -4437,6 +4923,33 @@ static void b43_nphy_tx_cal_phy_setup(st
2132                 regs[10] = b43_phy_read(dev, B43_NPHY_PAPD_EN1);
2133                 b43_phy_mask(dev, B43_NPHY_PAPD_EN0, ~0x0001);
2134                 b43_phy_mask(dev, B43_NPHY_PAPD_EN1, ~0x0001);
2135 +
2136 +               tmp = b43_nphy_read_lpf_ctl(dev, 0);
2137 +               if (phy->rev >= 19)
2138 +                       b43_nphy_rf_ctl_override_rev19(dev, 0x80, tmp, 0, false,
2139 +                                                      1);
2140 +               else if (phy->rev >= 7)
2141 +                       b43_nphy_rf_ctl_override_rev7(dev, 0x80, tmp, 0, false,
2142 +                                                     1);
2143 +
2144 +               if (nphy->use_int_tx_iq_lo_cal && true /* FIXME */) {
2145 +                       if (phy->rev >= 19) {
2146 +                               b43_nphy_rf_ctl_override_rev19(dev, 0x8, 0, 0x3,
2147 +                                                              false, 0);
2148 +                       } else if (phy->rev >= 8) {
2149 +                               b43_nphy_rf_ctl_override_rev7(dev, 0x8, 0, 0x3,
2150 +                                                             false, 0);
2151 +                       } else if (phy->rev == 7) {
2152 +                               b43_radio_maskset(dev, R2057_OVR_REG0, 1 << 4, 1 << 4);
2153 +                               if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
2154 +                                       b43_radio_maskset(dev, R2057_PAD2G_TUNE_PUS_CORE0, ~1, 0);
2155 +                                       b43_radio_maskset(dev, R2057_PAD2G_TUNE_PUS_CORE1, ~1, 0);
2156 +                               } else {
2157 +                                       b43_radio_maskset(dev, R2057_IPA5G_CASCOFFV_PU_CORE0, ~1, 0);
2158 +                                       b43_radio_maskset(dev, R2057_IPA5G_CASCOFFV_PU_CORE1, ~1, 0);
2159 +                               }
2160 +                       }
2161 +               }
2162         } else {
2163                 b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, 0xA000);
2164                 b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, 0xA000);
2165 @@ -4465,6 +4978,7 @@ static void b43_nphy_tx_cal_phy_setup(st
2166  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SaveCal */
2167  static void b43_nphy_save_cal(struct b43_wldev *dev)
2168  {
2169 +       struct b43_phy *phy = &dev->phy;
2170         struct b43_phy_n *nphy = dev->phy.n;
2171  
2172         struct b43_phy_n_iq_comp *rxcal_coeffs = NULL;
2173 @@ -4489,7 +5003,26 @@ static void b43_nphy_save_cal(struct b43
2174  
2175         b43_nphy_rx_iq_coeffs(dev, false, rxcal_coeffs);
2176         /* TODO use some definitions */
2177 -       if (dev->phy.rev >= 3) {
2178 +       if (phy->rev >= 19) {
2179 +               /* TODO */
2180 +       } else if (phy->rev >= 7) {
2181 +               txcal_radio_regs[0] = b43_radio_read(dev,
2182 +                                                    R2057_TX0_LOFT_FINE_I);
2183 +               txcal_radio_regs[1] = b43_radio_read(dev,
2184 +                                                    R2057_TX0_LOFT_FINE_Q);
2185 +               txcal_radio_regs[4] = b43_radio_read(dev,
2186 +                                                    R2057_TX0_LOFT_COARSE_I);
2187 +               txcal_radio_regs[5] = b43_radio_read(dev,
2188 +                                                    R2057_TX0_LOFT_COARSE_Q);
2189 +               txcal_radio_regs[2] = b43_radio_read(dev,
2190 +                                                    R2057_TX1_LOFT_FINE_I);
2191 +               txcal_radio_regs[3] = b43_radio_read(dev,
2192 +                                                    R2057_TX1_LOFT_FINE_Q);
2193 +               txcal_radio_regs[6] = b43_radio_read(dev,
2194 +                                                    R2057_TX1_LOFT_COARSE_I);
2195 +               txcal_radio_regs[7] = b43_radio_read(dev,
2196 +                                                    R2057_TX1_LOFT_COARSE_Q);
2197 +       } else if (phy->rev >= 3) {
2198                 txcal_radio_regs[0] = b43_radio_read(dev, 0x2021);
2199                 txcal_radio_regs[1] = b43_radio_read(dev, 0x2022);
2200                 txcal_radio_regs[2] = b43_radio_read(dev, 0x3021);
2201 @@ -4504,8 +5037,9 @@ static void b43_nphy_save_cal(struct b43
2202                 txcal_radio_regs[2] = b43_radio_read(dev, 0x8D);
2203                 txcal_radio_regs[3] = b43_radio_read(dev, 0xBC);
2204         }
2205 -       iqcal_chanspec->center_freq = dev->phy.channel_freq;
2206 -       iqcal_chanspec->channel_type = dev->phy.channel_type;
2207 +       iqcal_chanspec->center_freq = dev->phy.chandef->chan->center_freq;
2208 +       iqcal_chanspec->channel_type =
2209 +                               cfg80211_get_chandef_type(dev->phy.chandef);
2210         b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 8, table);
2211  
2212         if (nphy->hang_avoid)
2213 @@ -4515,6 +5049,7 @@ static void b43_nphy_save_cal(struct b43
2214  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RestoreCal */
2215  static void b43_nphy_restore_cal(struct b43_wldev *dev)
2216  {
2217 +       struct b43_phy *phy = &dev->phy;
2218         struct b43_phy_n *nphy = dev->phy.n;
2219  
2220         u16 coef[4];
2221 @@ -4562,7 +5097,26 @@ static void b43_nphy_restore_cal(struct
2222         }
2223  
2224         /* TODO use some definitions */
2225 -       if (dev->phy.rev >= 3) {
2226 +       if (phy->rev >= 19) {
2227 +               /* TODO */
2228 +       } else if (phy->rev >= 7) {
2229 +               b43_radio_write(dev, R2057_TX0_LOFT_FINE_I,
2230 +                               txcal_radio_regs[0]);
2231 +               b43_radio_write(dev, R2057_TX0_LOFT_FINE_Q,
2232 +                               txcal_radio_regs[1]);
2233 +               b43_radio_write(dev, R2057_TX0_LOFT_COARSE_I,
2234 +                               txcal_radio_regs[4]);
2235 +               b43_radio_write(dev, R2057_TX0_LOFT_COARSE_Q,
2236 +                               txcal_radio_regs[5]);
2237 +               b43_radio_write(dev, R2057_TX1_LOFT_FINE_I,
2238 +                               txcal_radio_regs[2]);
2239 +               b43_radio_write(dev, R2057_TX1_LOFT_FINE_Q,
2240 +                               txcal_radio_regs[3]);
2241 +               b43_radio_write(dev, R2057_TX1_LOFT_COARSE_I,
2242 +                               txcal_radio_regs[6]);
2243 +               b43_radio_write(dev, R2057_TX1_LOFT_COARSE_Q,
2244 +                               txcal_radio_regs[7]);
2245 +       } else if (phy->rev >= 3) {
2246                 b43_radio_write(dev, 0x2021, txcal_radio_regs[0]);
2247                 b43_radio_write(dev, 0x2022, txcal_radio_regs[1]);
2248                 b43_radio_write(dev, 0x3021, txcal_radio_regs[2]);
2249 @@ -4585,6 +5139,7 @@ static int b43_nphy_cal_tx_iq_lo(struct
2250                                 struct nphy_txgains target,
2251                                 bool full, bool mphase)
2252  {
2253 +       struct b43_phy *phy = &dev->phy;
2254         struct b43_phy_n *nphy = dev->phy.n;
2255         int i;
2256         int error = 0;
2257 @@ -4625,7 +5180,7 @@ static int b43_nphy_cal_tx_iq_lo(struct
2258                 (dev->phy.rev == 5 && nphy->ipa2g_on &&
2259                 b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ);
2260         if (phy6or5x) {
2261 -               if (dev->phy.is_40mhz) {
2262 +               if (b43_is_40mhz(dev)) {
2263                         b43_ntab_write_bulk(dev, B43_NTAB16(15, 0), 18,
2264                                         tbl_tx_iqlo_cal_loft_ladder_40);
2265                         b43_ntab_write_bulk(dev, B43_NTAB16(15, 32), 18,
2266 @@ -4638,18 +5193,24 @@ static int b43_nphy_cal_tx_iq_lo(struct
2267                 }
2268         }
2269  
2270 -       b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8AA9);
2271 +       if (phy->rev >= 19) {
2272 +               /* TODO */
2273 +       } else if (phy->rev >= 7) {
2274 +               b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8AD9);
2275 +       } else {
2276 +               b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8AA9);
2277 +       }
2278  
2279 -       if (!dev->phy.is_40mhz)
2280 +       if (!b43_is_40mhz(dev))
2281                 freq = 2500;
2282         else
2283                 freq = 5000;
2284  
2285         if (nphy->mphase_cal_phase_id > 2)
2286 -               b43_nphy_run_samples(dev, (dev->phy.is_40mhz ? 40 : 20) * 8,
2287 -                                       0xFFFF, 0, true, false);
2288 +               b43_nphy_run_samples(dev, (b43_is_40mhz(dev) ? 40 : 20) * 8,
2289 +                                    0xFFFF, 0, true, false, false);
2290         else
2291 -               error = b43_nphy_tx_tone(dev, freq, 250, true, false);
2292 +               error = b43_nphy_tx_tone(dev, freq, 250, true, false, false);
2293  
2294         if (error == 0) {
2295                 if (nphy->mphase_cal_phase_id > 2) {
2296 @@ -4777,9 +5338,9 @@ static int b43_nphy_cal_tx_iq_lo(struct
2297                                                 nphy->txiqlocal_bestc);
2298                         nphy->txiqlocal_coeffsvalid = true;
2299                         nphy->txiqlocal_chanspec.center_freq =
2300 -                                                       dev->phy.channel_freq;
2301 +                                               phy->chandef->chan->center_freq;
2302                         nphy->txiqlocal_chanspec.channel_type =
2303 -                                                       dev->phy.channel_type;
2304 +                                       cfg80211_get_chandef_type(phy->chandef);
2305                 } else {
2306                         length = 11;
2307                         if (dev->phy.rev < 3)
2308 @@ -4815,8 +5376,8 @@ static void b43_nphy_reapply_tx_cal_coef
2309         bool equal = true;
2310  
2311         if (!nphy->txiqlocal_coeffsvalid ||
2312 -           nphy->txiqlocal_chanspec.center_freq != dev->phy.channel_freq ||
2313 -           nphy->txiqlocal_chanspec.channel_type != dev->phy.channel_type)
2314 +           nphy->txiqlocal_chanspec.center_freq != dev->phy.chandef->chan->center_freq ||
2315 +           nphy->txiqlocal_chanspec.channel_type != cfg80211_get_chandef_type(dev->phy.chandef))
2316                 return;
2317  
2318         b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer);
2319 @@ -4972,11 +5533,11 @@ static int b43_nphy_rev2_cal_rx_iq(struc
2320                         if (playtone) {
2321                                 ret = b43_nphy_tx_tone(dev, 4000,
2322                                                 (nphy->rxcalparams & 0xFFFF),
2323 -                                               false, false);
2324 +                                               false, false, true);
2325                                 playtone = false;
2326                         } else {
2327 -                               b43_nphy_run_samples(dev, 160, 0xFFFF, 0,
2328 -                                                       false, false);
2329 +                               b43_nphy_run_samples(dev, 160, 0xFFFF, 0, false,
2330 +                                                    false, true);
2331                         }
2332  
2333                         if (ret == 0) {
2334 @@ -5032,6 +5593,9 @@ static int b43_nphy_rev3_cal_rx_iq(struc
2335  static int b43_nphy_cal_rx_iq(struct b43_wldev *dev,
2336                         struct nphy_txgains target, u8 type, bool debug)
2337  {
2338 +       if (dev->phy.rev >= 7)
2339 +               type = 0;
2340 +
2341         if (dev->phy.rev >= 3)
2342                 return b43_nphy_rev3_cal_rx_iq(dev, target, type, debug);
2343         else
2344 @@ -5118,6 +5682,9 @@ static void b43_nphy_bphy_init(struct b4
2345  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SuperSwitchInit */
2346  static void b43_nphy_superswitch_init(struct b43_wldev *dev, bool init)
2347  {
2348 +       if (dev->phy.rev >= 7)
2349 +               return;
2350 +
2351         if (dev->phy.rev >= 3) {
2352                 if (!init)
2353                         return;
2354 @@ -5193,6 +5760,10 @@ static int b43_phy_initn(struct b43_wlde
2355  #endif
2356                 }
2357         }
2358 +       nphy->use_int_tx_iq_lo_cal = b43_nphy_ipa(dev) ||
2359 +               phy->rev >= 7 ||
2360 +               (phy->rev >= 5 &&
2361 +                sprom->boardflags2_hi & B43_BFH2_INTERNDET_TXIQCAL);
2362         nphy->deaf_count = 0;
2363         b43_nphy_tables_init(dev);
2364         nphy->crsminpwr_adjusted = false;
2365 @@ -5202,6 +5773,16 @@ static int b43_phy_initn(struct b43_wlde
2366         if (dev->phy.rev >= 3) {
2367                 b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S1, 0);
2368                 b43_phy_write(dev, B43_NPHY_RFCTL_OVER, 0);
2369 +               if (phy->rev >= 7) {
2370 +                       b43_phy_write(dev, B43_NPHY_REV7_RF_CTL_OVER3, 0);
2371 +                       b43_phy_write(dev, B43_NPHY_REV7_RF_CTL_OVER4, 0);
2372 +                       b43_phy_write(dev, B43_NPHY_REV7_RF_CTL_OVER5, 0);
2373 +                       b43_phy_write(dev, B43_NPHY_REV7_RF_CTL_OVER6, 0);
2374 +               }
2375 +               if (phy->rev >= 19) {
2376 +                       /* TODO */
2377 +               }
2378 +
2379                 b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S0, 0);
2380                 b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S1, 0);
2381         } else {
2382 @@ -5239,7 +5820,9 @@ static int b43_phy_initn(struct b43_wlde
2383         b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x50);
2384         b43_phy_write(dev, B43_NPHY_TXRIFS_FRDEL, 0x30);
2385  
2386 -       b43_nphy_update_mimo_config(dev, nphy->preamble_override);
2387 +       if (phy->rev < 8)
2388 +               b43_nphy_update_mimo_config(dev, nphy->preamble_override);
2389 +
2390         b43_nphy_update_txrx_chain(dev);
2391  
2392         if (phy->rev < 2) {
2393 @@ -5271,10 +5854,12 @@ static int b43_phy_initn(struct b43_wlde
2394  
2395         b43_mac_phy_clock_set(dev, true);
2396  
2397 -       b43_nphy_pa_override(dev, false);
2398 -       b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX);
2399 -       b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
2400 -       b43_nphy_pa_override(dev, true);
2401 +       if (phy->rev < 7) {
2402 +               b43_nphy_pa_override(dev, false);
2403 +               b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX);
2404 +               b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
2405 +               b43_nphy_pa_override(dev, true);
2406 +       }
2407  
2408         b43_nphy_classifier(dev, 0, 0);
2409         b43_nphy_read_clip_detection(dev, clip);
2410 @@ -5348,7 +5933,7 @@ static int b43_phy_initn(struct b43_wlde
2411         b43_phy_write(dev, B43_NPHY_TXMACDELAY, 0x0320);
2412         if (phy->rev >= 3 && phy->rev <= 6)
2413                 b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x0032);
2414 -       b43_nphy_tx_lp_fbw(dev);
2415 +       b43_nphy_tx_lpf_bw(dev);
2416         if (phy->rev >= 3)
2417                 b43_nphy_spur_workaround(dev);
2418  
2419 @@ -5434,14 +6019,14 @@ static void b43_nphy_channel_setup(struc
2420         if (dev->phy.rev < 3)
2421                 b43_nphy_adjust_lna_gain_table(dev);
2422  
2423 -       b43_nphy_tx_lp_fbw(dev);
2424 +       b43_nphy_tx_lpf_bw(dev);
2425  
2426         if (dev->phy.rev >= 3 &&
2427             dev->phy.n->spur_avoid != B43_SPUR_AVOID_DISABLE) {
2428                 bool avoid = false;
2429                 if (dev->phy.n->spur_avoid == B43_SPUR_AVOID_FORCE) {
2430                         avoid = true;
2431 -               } else if (!b43_channel_type_is_40mhz(phy->channel_type)) {
2432 +               } else if (!b43_is_40mhz(dev)) {
2433                         if ((ch >= 5 && ch <= 8) || ch == 13 || ch == 14)
2434                                 avoid = true;
2435                 } else { /* 40MHz */
2436 @@ -5488,10 +6073,20 @@ static int b43_nphy_set_channel(struct b
2437  
2438         const struct b43_nphy_channeltab_entry_rev2 *tabent_r2 = NULL;
2439         const struct b43_nphy_channeltab_entry_rev3 *tabent_r3 = NULL;
2440 +       const struct b43_nphy_chantabent_rev7 *tabent_r7 = NULL;
2441 +       const struct b43_nphy_chantabent_rev7_2g *tabent_r7_2g = NULL;
2442  
2443         u8 tmp;
2444  
2445 -       if (dev->phy.rev >= 3) {
2446 +       if (phy->rev >= 19) {
2447 +               return -ESRCH;
2448 +               /* TODO */
2449 +       } else if (phy->rev >= 7) {
2450 +               r2057_get_chantabent_rev7(dev, channel->center_freq,
2451 +                                         &tabent_r7, &tabent_r7_2g);
2452 +               if (!tabent_r7 && !tabent_r7_2g)
2453 +                       return -ESRCH;
2454 +       } else if (phy->rev >= 3) {
2455                 tabent_r3 = b43_nphy_get_chantabent_rev3(dev,
2456                                                         channel->center_freq);
2457                 if (!tabent_r3)
2458 @@ -5506,20 +6101,38 @@ static int b43_nphy_set_channel(struct b
2459         /* Channel is set later in common code, but we need to set it on our
2460            own to let this function's subcalls work properly. */
2461         phy->channel = channel->hw_value;
2462 -       phy->channel_freq = channel->center_freq;
2463  
2464 +#if 0
2465         if (b43_channel_type_is_40mhz(phy->channel_type) !=
2466                 b43_channel_type_is_40mhz(channel_type))
2467                 ; /* TODO: BMAC BW Set (channel_type) */
2468 +#endif
2469  
2470 -       if (channel_type == NL80211_CHAN_HT40PLUS)
2471 -               b43_phy_set(dev, B43_NPHY_RXCTL,
2472 -                               B43_NPHY_RXCTL_BSELU20);
2473 -       else if (channel_type == NL80211_CHAN_HT40MINUS)
2474 -               b43_phy_mask(dev, B43_NPHY_RXCTL,
2475 -                               ~B43_NPHY_RXCTL_BSELU20);
2476 +       if (channel_type == NL80211_CHAN_HT40PLUS) {
2477 +               b43_phy_set(dev, B43_NPHY_RXCTL, B43_NPHY_RXCTL_BSELU20);
2478 +               if (phy->rev >= 7)
2479 +                       b43_phy_set(dev, 0x310, 0x8000);
2480 +       } else if (channel_type == NL80211_CHAN_HT40MINUS) {
2481 +               b43_phy_mask(dev, B43_NPHY_RXCTL, ~B43_NPHY_RXCTL_BSELU20);
2482 +               if (phy->rev >= 7)
2483 +                       b43_phy_mask(dev, 0x310, (u16)~0x8000);
2484 +       }
2485  
2486 -       if (dev->phy.rev >= 3) {
2487 +       if (phy->rev >= 19) {
2488 +               /* TODO */
2489 +       } else if (phy->rev >= 7) {
2490 +               const struct b43_phy_n_sfo_cfg *phy_regs = tabent_r7 ?
2491 +                       &(tabent_r7->phy_regs) : &(tabent_r7_2g->phy_regs);
2492 +
2493 +               if (phy->radio_rev <= 4 || phy->radio_rev == 6) {
2494 +                       tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 2 : 0;
2495 +                       b43_radio_maskset(dev, R2057_TIA_CONFIG_CORE0, ~2, tmp);
2496 +                       b43_radio_maskset(dev, R2057_TIA_CONFIG_CORE1, ~2, tmp);
2497 +               }
2498 +
2499 +               b43_radio_2057_setup(dev, tabent_r7, tabent_r7_2g);
2500 +               b43_nphy_channel_setup(dev, phy_regs, channel);
2501 +       } else if (phy->rev >= 3) {
2502                 tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 4 : 0;
2503                 b43_radio_maskset(dev, 0x08, 0xFFFB, tmp);
2504                 b43_radio_2056_setup(dev, tabent_r3);
2505 @@ -5561,7 +6174,6 @@ static void b43_nphy_op_prepare_structs(
2506         nphy->hang_avoid = (phy->rev == 3 || phy->rev == 4);
2507         nphy->spur_avoid = (phy->rev >= 3) ?
2508                                 B43_SPUR_AVOID_AUTO : B43_SPUR_AVOID_DISABLE;
2509 -       nphy->init_por = true;
2510         nphy->gain_boost = true; /* this way we follow wl, assume it is true */
2511         nphy->txrx_chain = 2; /* sth different than 0 and 1 for now */
2512         nphy->phyrxchain = 3; /* to avoid b43_nphy_set_rx_core_state like wl */
2513 @@ -5602,8 +6214,6 @@ static void b43_nphy_op_prepare_structs(
2514                 nphy->ipa2g_on = sprom->fem.ghz2.extpa_gain == 2;
2515                 nphy->ipa5g_on = sprom->fem.ghz5.extpa_gain == 2;
2516         }
2517 -
2518 -       nphy->init_por = true;
2519  }
2520  
2521  static void b43_nphy_op_free(struct b43_wldev *dev)
2522 @@ -5663,7 +6273,7 @@ static void b43_nphy_op_maskset(struct b
2523  static u16 b43_nphy_op_radio_read(struct b43_wldev *dev, u16 reg)
2524  {
2525         /* Register 1 is a 32-bit register. */
2526 -       B43_WARN_ON(reg == 1);
2527 +       B43_WARN_ON(dev->phy.rev < 7 && reg == 1);
2528  
2529         if (dev->phy.rev >= 7)
2530                 reg |= 0x200; /* Radio 0x2057 */
2531 @@ -5677,7 +6287,7 @@ static u16 b43_nphy_op_radio_read(struct
2532  static void b43_nphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
2533  {
2534         /* Register 1 is a 32-bit register. */
2535 -       B43_WARN_ON(reg == 1);
2536 +       B43_WARN_ON(dev->phy.rev < 7 && reg == 1);
2537  
2538         b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
2539         b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
2540 @@ -5687,15 +6297,23 @@ static void b43_nphy_op_radio_write(stru
2541  static void b43_nphy_op_software_rfkill(struct b43_wldev *dev,
2542                                         bool blocked)
2543  {
2544 +       struct b43_phy *phy = &dev->phy;
2545 +
2546         if (b43_read32(dev, B43_MMIO_MACCTL) & B43_MACCTL_ENABLED)
2547                 b43err(dev->wl, "MAC not suspended\n");
2548  
2549         if (blocked) {
2550 -               b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
2551 -                               ~B43_NPHY_RFCTL_CMD_CHIP0PU);
2552 -               if (dev->phy.rev >= 7) {
2553 +               if (phy->rev >= 19) {
2554                         /* TODO */
2555 -               } else if (dev->phy.rev >= 3) {
2556 +               } else if (phy->rev >= 8) {
2557 +                       b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
2558 +                                    ~B43_NPHY_RFCTL_CMD_CHIP0PU);
2559 +               } else if (phy->rev >= 7) {
2560 +                       /* Nothing needed */
2561 +               } else if (phy->rev >= 3) {
2562 +                       b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
2563 +                                    ~B43_NPHY_RFCTL_CMD_CHIP0PU);
2564 +
2565                         b43_radio_mask(dev, 0x09, ~0x2);
2566  
2567                         b43_radio_write(dev, 0x204D, 0);
2568 @@ -5713,11 +6331,15 @@ static void b43_nphy_op_software_rfkill(
2569                         b43_radio_write(dev, 0x3064, 0);
2570                 }
2571         } else {
2572 -               if (dev->phy.rev >= 7) {
2573 -                       b43_radio_2057_init(dev);
2574 +               if (phy->rev >= 19) {
2575 +                       /* TODO */
2576 +               } else if (phy->rev >= 7) {
2577 +                       if (!dev->phy.radio_on)
2578 +                               b43_radio_2057_init(dev);
2579                         b43_switch_channel(dev, dev->phy.channel);
2580 -               } else if (dev->phy.rev >= 3) {
2581 -                       b43_radio_init2056(dev);
2582 +               } else if (phy->rev >= 3) {
2583 +                       if (!dev->phy.radio_on)
2584 +                               b43_radio_init2056(dev);
2585                         b43_switch_channel(dev, dev->phy.channel);
2586                 } else {
2587                         b43_radio_init2055(dev);
2588 @@ -5728,10 +6350,13 @@ static void b43_nphy_op_software_rfkill(
2589  /* http://bcm-v4.sipsolutions.net/802.11/PHY/Anacore */
2590  static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on)
2591  {
2592 +       struct b43_phy *phy = &dev->phy;
2593         u16 override = on ? 0x0 : 0x7FFF;
2594         u16 core = on ? 0xD : 0x00FD;
2595  
2596 -       if (dev->phy.rev >= 3) {
2597 +       if (phy->rev >= 19) {
2598 +               /* TODO */
2599 +       } else if (phy->rev >= 3) {
2600                 if (on) {
2601                         b43_phy_write(dev, B43_NPHY_AFECTL_C1, core);
2602                         b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, override);
2603 --- a/drivers/net/wireless/b43/phy_n.h
2604 +++ b/drivers/net/wireless/b43/phy_n.h
2605 @@ -857,6 +857,15 @@
2606  #define B43_NPHY_REV3_C2_CLIP2_GAIN_A          B43_PHY_N(0x2AF)
2607  #define B43_NPHY_REV3_C2_CLIP2_GAIN_B          B43_PHY_N(0x2B0)
2608  
2609 +#define B43_NPHY_REV7_RF_CTL_MISC_REG3         B43_PHY_N(0x340)
2610 +#define B43_NPHY_REV7_RF_CTL_MISC_REG4         B43_PHY_N(0x341)
2611 +#define B43_NPHY_REV7_RF_CTL_OVER3             B43_PHY_N(0x342)
2612 +#define B43_NPHY_REV7_RF_CTL_OVER4             B43_PHY_N(0x343)
2613 +#define B43_NPHY_REV7_RF_CTL_MISC_REG5         B43_PHY_N(0x344)
2614 +#define B43_NPHY_REV7_RF_CTL_MISC_REG6         B43_PHY_N(0x345)
2615 +#define B43_NPHY_REV7_RF_CTL_OVER5             B43_PHY_N(0x346)
2616 +#define B43_NPHY_REV7_RF_CTL_OVER6             B43_PHY_N(0x347)
2617 +
2618  #define B43_PHY_B_BBCFG                                B43_PHY_N_BMODE(0x001) /* BB config */
2619  #define B43_PHY_B_TEST                         B43_PHY_N_BMODE(0x00A)
2620  
2621 @@ -931,11 +940,12 @@ struct b43_phy_n {
2622         u16 papd_epsilon_offset[2];
2623         s32 preamble_override;
2624         u32 bb_mult_save;
2625 -       bool init_por;
2626  
2627         bool gain_boost;
2628         bool elna_gain_config;
2629         bool band5g_pwrgain;
2630 +       bool use_int_tx_iq_lo_cal;
2631 +       bool lpf_bw_overrode_for_sample_play;
2632  
2633         u8 mphase_cal_phase_id;
2634         u16 mphase_txcal_cmdidx;
2635 --- a/drivers/net/wireless/b43/tables_nphy.c
2636 +++ b/drivers/net/wireless/b43/tables_nphy.c
2637 @@ -2146,7 +2146,196 @@ static const u16 b43_ntab_antswctl_r3[4]
2638         }
2639  };
2640  
2641 -/* TX gain tables */
2642 +/* static tables, PHY revision >= 7 */
2643 +
2644 +/* Copied from brcmsmac (5.75.11) */
2645 +static const u32 b43_ntab_tmap_r7[] = {
2646 +       0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
2647 +       0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
2648 +       0xf1111110, 0x11111111, 0x11f11111, 0x00000111,
2649 +       0x11000000, 0x1111f111, 0x11111111, 0x111111f1,
2650 +       0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x000aa888,
2651 +       0x88880000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
2652 +       0xa1111110, 0x11111111, 0x11c11111, 0x00000111,
2653 +       0x11000000, 0x1111a111, 0x11111111, 0x111111a1,
2654 +       0xa2222220, 0x22222222, 0x22c22222, 0x00000222,
2655 +       0x22000000, 0x2222a222, 0x22222222, 0x222222a2,
2656 +       0xf1111110, 0x11111111, 0x11f11111, 0x00011111,
2657 +       0x11110000, 0x1111f111, 0x11111111, 0x111111f1,
2658 +       0xa8aa88a0, 0xa88888a8, 0xa8a8a88a, 0x00088aaa,
2659 +       0xaaaa0000, 0xa8a8aa88, 0xa88aaaaa, 0xaaaa8a8a,
2660 +       0xaaa8aaa0, 0x8aaa8aaa, 0xaa8a8a8a, 0x000aaa88,
2661 +       0x8aaa0000, 0xaaa8a888, 0x8aa88a8a, 0x8a88a888,
2662 +       0x08080a00, 0x0a08080a, 0x080a0a08, 0x00080808,
2663 +       0x080a0000, 0x080a0808, 0x080a0808, 0x0a0a0a08,
2664 +       0xa0a0a0a0, 0x80a0a080, 0x8080a0a0, 0x00008080,
2665 +       0x80a00000, 0x80a080a0, 0xa080a0a0, 0x8080a0a0,
2666 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
2667 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
2668 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
2669 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
2670 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
2671 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
2672 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
2673 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
2674 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
2675 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
2676 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
2677 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
2678 +       0x99999000, 0x9b9b99bb, 0x9bb99999, 0x9999b9b9,
2679 +       0x9b99bb90, 0x9bbbbb9b, 0x9b9b9bb9, 0x00000999,
2680 +       0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
2681 +       0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00aaa888,
2682 +       0x22000000, 0x2222b222, 0x22222222, 0x222222b2,
2683 +       0xb2222220, 0x22222222, 0x22d22222, 0x00000222,
2684 +       0x11000000, 0x1111a111, 0x11111111, 0x111111a1,
2685 +       0xa1111110, 0x11111111, 0x11c11111, 0x00000111,
2686 +       0x33000000, 0x3333b333, 0x33333333, 0x333333b3,
2687 +       0xb3333330, 0x33333333, 0x33d33333, 0x00000333,
2688 +       0x22000000, 0x2222a222, 0x22222222, 0x222222a2,
2689 +       0xa2222220, 0x22222222, 0x22c22222, 0x00000222,
2690 +       0x99b99b00, 0x9b9b99bb, 0x9bb99999, 0x9999b9b9,
2691 +       0x9b99bb99, 0x9bbbbb9b, 0x9b9b9bb9, 0x00000999,
2692 +       0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
2693 +       0x8a88aa88, 0x8aaaaa8a, 0x8a8a8aa8, 0x08aaa888,
2694 +       0x22222200, 0x2222f222, 0x22222222, 0x222222f2,
2695 +       0x22222222, 0x22222222, 0x22f22222, 0x00000222,
2696 +       0x11000000, 0x1111f111, 0x11111111, 0x11111111,
2697 +       0xf1111111, 0x11111111, 0x11f11111, 0x01111111,
2698 +       0xbb9bb900, 0xb9b9bb99, 0xb99bbbbb, 0xbbbb9b9b,
2699 +       0xb9bb99bb, 0xb99999b9, 0xb9b9b99b, 0x00000bbb,
2700 +       0xaa000000, 0xa8a8aa88, 0xa88aaaaa, 0xaaaa8a8a,
2701 +       0xa8aa88aa, 0xa88888a8, 0xa8a8a88a, 0x0a888aaa,
2702 +       0xaa000000, 0xa8a8aa88, 0xa88aaaaa, 0xaaaa8a8a,
2703 +       0xa8aa88a0, 0xa88888a8, 0xa8a8a88a, 0x00000aaa,
2704 +       0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
2705 +       0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
2706 +       0xbbbbbb00, 0x999bbbbb, 0x9bb99b9b, 0xb9b9b9bb,
2707 +       0xb9b99bbb, 0xb9b9b9bb, 0xb9bb9b99, 0x00000999,
2708 +       0x8a000000, 0xaa88a888, 0xa88888aa, 0xa88a8a88,
2709 +       0xa88aa88a, 0x88a8aaaa, 0xa8aa8aaa, 0x0888a88a,
2710 +       0x0b0b0b00, 0x090b0b0b, 0x0b090b0b, 0x0909090b,
2711 +       0x09090b0b, 0x09090b0b, 0x09090b09, 0x00000909,
2712 +       0x0a000000, 0x0a080808, 0x080a080a, 0x080a0a08,
2713 +       0x080a080a, 0x0808080a, 0x0a0a0a08, 0x0808080a,
2714 +       0xb0b0b000, 0x9090b0b0, 0x90b09090, 0xb0b0b090,
2715 +       0xb0b090b0, 0x90b0b0b0, 0xb0b09090, 0x00000090,
2716 +       0x80000000, 0xa080a080, 0xa08080a0, 0xa0808080,
2717 +       0xa080a080, 0x80a0a0a0, 0xa0a080a0, 0x00a0a0a0,
2718 +       0x22000000, 0x2222f222, 0x22222222, 0x222222f2,
2719 +       0xf2222220, 0x22222222, 0x22f22222, 0x00000222,
2720 +       0x11000000, 0x1111f111, 0x11111111, 0x111111f1,
2721 +       0xf1111110, 0x11111111, 0x11f11111, 0x00000111,
2722 +       0x33000000, 0x3333f333, 0x33333333, 0x333333f3,
2723 +       0xf3333330, 0x33333333, 0x33f33333, 0x00000333,
2724 +       0x22000000, 0x2222f222, 0x22222222, 0x222222f2,
2725 +       0xf2222220, 0x22222222, 0x22f22222, 0x00000222,
2726 +       0x99000000, 0x9b9b99bb, 0x9bb99999, 0x9999b9b9,
2727 +       0x9b99bb90, 0x9bbbbb9b, 0x9b9b9bb9, 0x00000999,
2728 +       0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
2729 +       0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
2730 +       0x88888000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
2731 +       0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
2732 +       0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
2733 +       0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00aaa888,
2734 +       0x88a88a00, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
2735 +       0x8a88aa88, 0x8aaaaa8a, 0x8a8a8aa8, 0x000aa888,
2736 +       0x88880000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
2737 +       0x8a88aa88, 0x8aaaaa8a, 0x8a8a8aa8, 0x08aaa888,
2738 +       0x11000000, 0x1111a111, 0x11111111, 0x111111a1,
2739 +       0xa1111110, 0x11111111, 0x11c11111, 0x00000111,
2740 +       0x11000000, 0x1111a111, 0x11111111, 0x111111a1,
2741 +       0xa1111110, 0x11111111, 0x11c11111, 0x00000111,
2742 +       0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
2743 +       0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
2744 +       0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
2745 +       0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
2746 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
2747 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
2748 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
2749 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
2750 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
2751 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
2752 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
2753 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
2754 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
2755 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
2756 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
2757 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
2758 +};
2759 +
2760 +/* Extracted from MMIO dump of 6.30.223.141 */
2761 +static const u32 b43_ntab_noisevar_r7[] = {
2762 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2763 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2764 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2765 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2766 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2767 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2768 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2769 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2770 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2771 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2772 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2773 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2774 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2775 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2776 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2777 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2778 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2779 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2780 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2781 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2782 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2783 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2784 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2785 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2786 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2787 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2788 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2789 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2790 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2791 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2792 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2793 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2794 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2795 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2796 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2797 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2798 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2799 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2800 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2801 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2802 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2803 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2804 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2805 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2806 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2807 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2808 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2809 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2810 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2811 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2812 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2813 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2814 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2815 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2816 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2817 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2818 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2819 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2820 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2821 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2822 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2823 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2824 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2825 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2826 +};
2827 +
2828 +/**************************************************
2829 + * TX gain tables
2830 + **************************************************/
2831 +
2832  static const u32 b43_ntab_tx_gain_rev0_1_2[] = {
2833         0x03cc2b44, 0x03cc2b42, 0x03cc2a44, 0x03cc2a42,
2834         0x03cc2944, 0x03c82b44, 0x03c82b42, 0x03c82a44,
2835 @@ -2182,7 +2371,9 @@ static const u32 b43_ntab_tx_gain_rev0_1
2836         0x03801442, 0x03801344, 0x03801342, 0x00002b00,
2837  };
2838  
2839 -static const u32 b43_ntab_tx_gain_rev3plus_2ghz[] = {
2840 +/* EPA 2 GHz */
2841 +
2842 +static const u32 b43_ntab_tx_gain_epa_rev3_2g[] = {
2843         0x1f410044, 0x1f410042, 0x1f410040, 0x1f41003e,
2844         0x1f41003c, 0x1f41003b, 0x1f410039, 0x1f410037,
2845         0x1e410044, 0x1e410042, 0x1e410040, 0x1e41003e,
2846 @@ -2217,7 +2408,44 @@ static const u32 b43_ntab_tx_gain_rev3pl
2847         0x1041003c, 0x1041003b, 0x10410039, 0x10410037,
2848  };
2849  
2850 -static const u32 b43_ntab_tx_gain_rev3_5ghz[] = {
2851 +static const u32 b43_ntab_tx_gain_epa_rev3_hi_pwr_2g[] = {
2852 +       0x0f410044, 0x0f410042, 0x0f410040, 0x0f41003e,
2853 +       0x0f41003c, 0x0f41003b, 0x0f410039, 0x0f410037,
2854 +       0x0e410044, 0x0e410042, 0x0e410040, 0x0e41003e,
2855 +       0x0e41003c, 0x0e41003b, 0x0e410039, 0x0e410037,
2856 +       0x0d410044, 0x0d410042, 0x0d410040, 0x0d41003e,
2857 +       0x0d41003c, 0x0d41003b, 0x0d410039, 0x0d410037,
2858 +       0x0c410044, 0x0c410042, 0x0c410040, 0x0c41003e,
2859 +       0x0c41003c, 0x0c41003b, 0x0c410039, 0x0c410037,
2860 +       0x0b410044, 0x0b410042, 0x0b410040, 0x0b41003e,
2861 +       0x0b41003c, 0x0b41003b, 0x0b410039, 0x0b410037,
2862 +       0x0a410044, 0x0a410042, 0x0a410040, 0x0a41003e,
2863 +       0x0a41003c, 0x0a41003b, 0x0a410039, 0x0a410037,
2864 +       0x09410044, 0x09410042, 0x09410040, 0x0941003e,
2865 +       0x0941003c, 0x0941003b, 0x09410039, 0x09410037,
2866 +       0x08410044, 0x08410042, 0x08410040, 0x0841003e,
2867 +       0x0841003c, 0x0841003b, 0x08410039, 0x08410037,
2868 +       0x07410044, 0x07410042, 0x07410040, 0x0741003e,
2869 +       0x0741003c, 0x0741003b, 0x07410039, 0x07410037,
2870 +       0x06410044, 0x06410042, 0x06410040, 0x0641003e,
2871 +       0x0641003c, 0x0641003b, 0x06410039, 0x06410037,
2872 +       0x05410044, 0x05410042, 0x05410040, 0x0541003e,
2873 +       0x0541003c, 0x0541003b, 0x05410039, 0x05410037,
2874 +       0x04410044, 0x04410042, 0x04410040, 0x0441003e,
2875 +       0x0441003c, 0x0441003b, 0x04410039, 0x04410037,
2876 +       0x03410044, 0x03410042, 0x03410040, 0x0341003e,
2877 +       0x0341003c, 0x0341003b, 0x03410039, 0x03410037,
2878 +       0x02410044, 0x02410042, 0x02410040, 0x0241003e,
2879 +       0x0241003c, 0x0241003b, 0x02410039, 0x02410037,
2880 +       0x01410044, 0x01410042, 0x01410040, 0x0141003e,
2881 +       0x0141003c, 0x0141003b, 0x01410039, 0x01410037,
2882 +       0x00410044, 0x00410042, 0x00410040, 0x0041003e,
2883 +       0x0041003c, 0x0041003b, 0x00410039, 0x00410037
2884 +};
2885 +
2886 +/* EPA 5 GHz */
2887 +
2888 +static const u32 b43_ntab_tx_gain_epa_rev3_5g[] = {
2889         0xcff70044, 0xcff70042, 0xcff70040, 0xcff7003e,
2890         0xcff7003c, 0xcff7003b, 0xcff70039, 0xcff70037,
2891         0xcef70044, 0xcef70042, 0xcef70040, 0xcef7003e,
2892 @@ -2252,7 +2480,7 @@ static const u32 b43_ntab_tx_gain_rev3_5
2893         0xc0f7003c, 0xc0f7003b, 0xc0f70039, 0xc0f70037,
2894  };
2895  
2896 -static const u32 b43_ntab_tx_gain_rev4_5ghz[] = {
2897 +static const u32 b43_ntab_tx_gain_epa_rev4_5g[] = {
2898         0x2ff20044, 0x2ff20042, 0x2ff20040, 0x2ff2003e,
2899         0x2ff2003c, 0x2ff2003b, 0x2ff20039, 0x2ff20037,
2900         0x2ef20044, 0x2ef20042, 0x2ef20040, 0x2ef2003e,
2901 @@ -2287,7 +2515,42 @@ static const u32 b43_ntab_tx_gain_rev4_5
2902         0x20d2003a, 0x20d20038, 0x20d20036, 0x20d20034,
2903  };
2904  
2905 -static const u32 b43_ntab_tx_gain_rev5plus_5ghz[] = {
2906 +static const u32 b43_ntab_tx_gain_epa_rev4_hi_pwr_5g[] = {
2907 +       0x2ff10044, 0x2ff10042, 0x2ff10040, 0x2ff1003e,
2908 +       0x2ff1003c, 0x2ff1003b, 0x2ff10039, 0x2ff10037,
2909 +       0x2ef10044, 0x2ef10042, 0x2ef10040, 0x2ef1003e,
2910 +       0x2ef1003c, 0x2ef1003b, 0x2ef10039, 0x2ef10037,
2911 +       0x2df10044, 0x2df10042, 0x2df10040, 0x2df1003e,
2912 +       0x2df1003c, 0x2df1003b, 0x2df10039, 0x2df10037,
2913 +       0x2cf10044, 0x2cf10042, 0x2cf10040, 0x2cf1003e,
2914 +       0x2cf1003c, 0x2cf1003b, 0x2cf10039, 0x2cf10037,
2915 +       0x2bf10044, 0x2bf10042, 0x2bf10040, 0x2bf1003e,
2916 +       0x2bf1003c, 0x2bf1003b, 0x2bf10039, 0x2bf10037,
2917 +       0x2af10044, 0x2af10042, 0x2af10040, 0x2af1003e,
2918 +       0x2af1003c, 0x2af1003b, 0x2af10039, 0x2af10037,
2919 +       0x29f10044, 0x29f10042, 0x29f10040, 0x29f1003e,
2920 +       0x29f1003c, 0x29f1003b, 0x29f10039, 0x29f10037,
2921 +       0x28f10044, 0x28f10042, 0x28f10040, 0x28f1003e,
2922 +       0x28f1003c, 0x28f1003b, 0x28f10039, 0x28f10037,
2923 +       0x27f10044, 0x27f10042, 0x27f10040, 0x27f1003e,
2924 +       0x27f1003c, 0x27f1003b, 0x27f10039, 0x27f10037,
2925 +       0x26f10044, 0x26f10042, 0x26f10040, 0x26f1003e,
2926 +       0x26f1003c, 0x26f1003b, 0x26f10039, 0x26f10037,
2927 +       0x25f10044, 0x25f10042, 0x25f10040, 0x25f1003e,
2928 +       0x25f1003c, 0x25f1003b, 0x25f10039, 0x25f10037,
2929 +       0x24f10044, 0x24f10042, 0x24f10040, 0x24f1003e,
2930 +       0x24f1003c, 0x24f1003b, 0x24f10039, 0x24f10038,
2931 +       0x23f10041, 0x23f10040, 0x23f1003f, 0x23f1003e,
2932 +       0x23f1003c, 0x23f1003b, 0x23f10039, 0x23f10037,
2933 +       0x22f10044, 0x22f10042, 0x22f10040, 0x22f1003e,
2934 +       0x22f1003c, 0x22f1003b, 0x22f10039, 0x22f10037,
2935 +       0x21f10044, 0x21f10042, 0x21f10040, 0x21f1003e,
2936 +       0x21f1003c, 0x21f1003b, 0x21f10039, 0x21f10037,
2937 +       0x20d10043, 0x20d10041, 0x20d1003e, 0x20d1003c,
2938 +       0x20d1003a, 0x20d10038, 0x20d10036, 0x20d10034
2939 +};
2940 +
2941 +static const u32 b43_ntab_tx_gain_epa_rev5_5g[] = {
2942         0x0f62004a, 0x0f620048, 0x0f620046, 0x0f620044,
2943         0x0f620042, 0x0f620040, 0x0f62003e, 0x0f62003c,
2944         0x0e620044, 0x0e620042, 0x0e620040, 0x0e62003e,
2945 @@ -2322,7 +2585,9 @@ static const u32 b43_ntab_tx_gain_rev5pl
2946         0x0062003b, 0x00620039, 0x00620037, 0x00620035,
2947  };
2948  
2949 -static const u32 txpwrctrl_tx_gain_ipa[] = {
2950 +/* IPA 2 GHz */
2951 +
2952 +static const u32 b43_ntab_tx_gain_ipa_rev3_2g[] = {
2953         0x5ff7002d, 0x5ff7002b, 0x5ff7002a, 0x5ff70029,
2954         0x5ff70028, 0x5ff70027, 0x5ff70026, 0x5ff70025,
2955         0x5ef7002d, 0x5ef7002b, 0x5ef7002a, 0x5ef70029,
2956 @@ -2357,7 +2622,7 @@ static const u32 txpwrctrl_tx_gain_ipa[]
2957         0x50f70028, 0x50f70027, 0x50f70026, 0x50f70025,
2958  };
2959  
2960 -static const u32 txpwrctrl_tx_gain_ipa_rev5[] = {
2961 +static const u32 b43_ntab_tx_gain_ipa_rev5_2g[] = {
2962         0x1ff7002d, 0x1ff7002b, 0x1ff7002a, 0x1ff70029,
2963         0x1ff70028, 0x1ff70027, 0x1ff70026, 0x1ff70025,
2964         0x1ef7002d, 0x1ef7002b, 0x1ef7002a, 0x1ef70029,
2965 @@ -2392,7 +2657,7 @@ static const u32 txpwrctrl_tx_gain_ipa_r
2966         0x10f70028, 0x10f70027, 0x10f70026, 0x10f70025,
2967  };
2968  
2969 -static const u32 txpwrctrl_tx_gain_ipa_rev6[] = {
2970 +static const u32 b43_ntab_tx_gain_ipa_rev6_2g[] = {
2971         0x0ff7002d, 0x0ff7002b, 0x0ff7002a, 0x0ff70029,
2972         0x0ff70028, 0x0ff70027, 0x0ff70026, 0x0ff70025,
2973         0x0ef7002d, 0x0ef7002b, 0x0ef7002a, 0x0ef70029,
2974 @@ -2427,7 +2692,81 @@ static const u32 txpwrctrl_tx_gain_ipa_r
2975         0x00f70028, 0x00f70027, 0x00f70026, 0x00f70025,
2976  };
2977  
2978 -static const u32 txpwrctrl_tx_gain_ipa_5g[] = {
2979 +/* Copied from brcmsmac (5.75.11): nphy_tpc_txgain_ipa_2g_2057rev5 */
2980 +static const u32 b43_ntab_tx_gain_ipa_2057_rev5_2g[] = {
2981 +       0x30ff0031, 0x30e70031, 0x30e7002e, 0x30cf002e,
2982 +       0x30bf002e, 0x30af002e, 0x309f002f, 0x307f0033,
2983 +       0x307f0031, 0x307f002e, 0x3077002e, 0x306f002e,
2984 +       0x3067002e, 0x305f002f, 0x30570030, 0x3057002d,
2985 +       0x304f002e, 0x30470031, 0x3047002e, 0x3047002c,
2986 +       0x30470029, 0x303f002c, 0x303f0029, 0x3037002d,
2987 +       0x3037002a, 0x30370028, 0x302f002c, 0x302f002a,
2988 +       0x302f0028, 0x302f0026, 0x3027002c, 0x30270029,
2989 +       0x30270027, 0x30270025, 0x30270023, 0x301f002c,
2990 +       0x301f002a, 0x301f0028, 0x301f0025, 0x301f0024,
2991 +       0x301f0022, 0x301f001f, 0x3017002d, 0x3017002b,
2992 +       0x30170028, 0x30170026, 0x30170024, 0x30170022,
2993 +       0x30170020, 0x3017001e, 0x3017001d, 0x3017001b,
2994 +       0x3017001a, 0x30170018, 0x30170017, 0x30170015,
2995 +       0x300f002c, 0x300f0029, 0x300f0027, 0x300f0024,
2996 +       0x300f0022, 0x300f0021, 0x300f001f, 0x300f001d,
2997 +       0x300f001b, 0x300f001a, 0x300f0018, 0x300f0017,
2998 +       0x300f0016, 0x300f0015, 0x300f0115, 0x300f0215,
2999 +       0x300f0315, 0x300f0415, 0x300f0515, 0x300f0615,
3000 +       0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3001 +       0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3002 +       0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3003 +       0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3004 +       0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3005 +       0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3006 +       0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3007 +       0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3008 +       0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3009 +       0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3010 +       0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3011 +       0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3012 +       0x300f0715, 0x300f0715, 0x300f0715, 0x300f0715,
3013 +};
3014 +
3015 +/* Extracted from MMIO dump of 6.30.223.141 */
3016 +static const u32 b43_ntab_tx_gain_ipa_2057_rev9_2g[] = {
3017 +       0x60ff0031, 0x60e7002c, 0x60cf002a, 0x60c70029,
3018 +       0x60b70029, 0x60a70029, 0x609f002a, 0x6097002b,
3019 +       0x6087002e, 0x60770031, 0x606f0032, 0x60670034,
3020 +       0x60670031, 0x605f0033, 0x605f0031, 0x60570033,
3021 +       0x60570030, 0x6057002d, 0x6057002b, 0x604f002d,
3022 +       0x604f002b, 0x604f0029, 0x604f0026, 0x60470029,
3023 +       0x60470027, 0x603f0029, 0x603f0027, 0x603f0025,
3024 +       0x60370029, 0x60370027, 0x60370024, 0x602f002a,
3025 +       0x602f0028, 0x602f0026, 0x602f0024, 0x6027002a,
3026 +       0x60270028, 0x60270026, 0x60270024, 0x60270022,
3027 +       0x601f002b, 0x601f0029, 0x601f0027, 0x601f0024,
3028 +       0x601f0022, 0x601f0020, 0x601f001f, 0x601f001d,
3029 +       0x60170029, 0x60170027, 0x60170025, 0x60170023,
3030 +       0x60170021, 0x6017001f, 0x6017001d, 0x6017001c,
3031 +       0x6017001a, 0x60170018, 0x60170018, 0x60170016,
3032 +       0x60170015, 0x600f0029, 0x600f0027, 0x600f0025,
3033 +       0x600f0023, 0x600f0021, 0x600f001f, 0x600f001d,
3034 +       0x600f001c, 0x600f001a, 0x600f0019, 0x600f0018,
3035 +       0x600f0016, 0x600f0015, 0x600f0115, 0x600f0215,
3036 +       0x600f0315, 0x600f0415, 0x600f0515, 0x600f0615,
3037 +       0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
3038 +       0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
3039 +       0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
3040 +       0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
3041 +       0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
3042 +       0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
3043 +       0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
3044 +       0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
3045 +       0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
3046 +       0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
3047 +       0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
3048 +       0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
3049 +};
3050 +
3051 +/* IPA 2 5Hz */
3052 +
3053 +static const u32 b43_ntab_tx_gain_ipa_rev3_5g[] = {
3054         0x7ff70035, 0x7ff70033, 0x7ff70032, 0x7ff70031,
3055         0x7ff7002f, 0x7ff7002e, 0x7ff7002d, 0x7ff7002b,
3056         0x7ff7002a, 0x7ff70029, 0x7ff70028, 0x7ff70027,
3057 @@ -2462,6 +2801,42 @@ static const u32 txpwrctrl_tx_gain_ipa_5
3058         0x70f70021, 0x70f70020, 0x70f70020, 0x70f7001f,
3059  };
3060  
3061 +/* Extracted from MMIO dump of 6.30.223.141 */
3062 +static const u32 b43_ntab_tx_gain_ipa_2057_rev9_5g[] = {
3063 +       0x7f7f0053, 0x7f7f004b, 0x7f7f0044, 0x7f7f003f,
3064 +       0x7f7f0039, 0x7f7f0035, 0x7f7f0032, 0x7f7f0030,
3065 +       0x7f7f002d, 0x7e7f0030, 0x7e7f002d, 0x7d7f0032,
3066 +       0x7d7f002f, 0x7d7f002c, 0x7c7f0032, 0x7c7f0030,
3067 +       0x7c7f002d, 0x7b7f0030, 0x7b7f002e, 0x7b7f002b,
3068 +       0x7a7f0032, 0x7a7f0030, 0x7a7f002d, 0x7a7f002b,
3069 +       0x797f0030, 0x797f002e, 0x797f002b, 0x797f0029,
3070 +       0x787f0030, 0x787f002d, 0x787f002b, 0x777f0032,
3071 +       0x777f0030, 0x777f002d, 0x777f002b, 0x767f0031,
3072 +       0x767f002f, 0x767f002c, 0x767f002a, 0x757f0031,
3073 +       0x757f002f, 0x757f002c, 0x757f002a, 0x747f0030,
3074 +       0x747f002d, 0x747f002b, 0x737f0032, 0x737f002f,
3075 +       0x737f002c, 0x737f002a, 0x727f0030, 0x727f002d,
3076 +       0x727f002b, 0x727f0029, 0x717f0030, 0x717f002d,
3077 +       0x717f002b, 0x707f0031, 0x707f002f, 0x707f002c,
3078 +       0x707f002a, 0x707f0027, 0x707f0025, 0x707f0023,
3079 +       0x707f0021, 0x707f001f, 0x707f001d, 0x707f001c,
3080 +       0x707f001a, 0x707f0019, 0x707f0017, 0x707f0016,
3081 +       0x707f0015, 0x707f0014, 0x707f0012, 0x707f0012,
3082 +       0x707f0011, 0x707f0010, 0x707f000f, 0x707f000e,
3083 +       0x707f000d, 0x707f000d, 0x707f000c, 0x707f000b,
3084 +       0x707f000a, 0x707f000a, 0x707f0009, 0x707f0008,
3085 +       0x707f0008, 0x707f0008, 0x707f0008, 0x707f0007,
3086 +       0x707f0007, 0x707f0006, 0x707f0006, 0x707f0006,
3087 +       0x707f0005, 0x707f0005, 0x707f0005, 0x707f0004,
3088 +       0x707f0004, 0x707f0004, 0x707f0003, 0x707f0003,
3089 +       0x707f0003, 0x707f0003, 0x707f0003, 0x707f0003,
3090 +       0x707f0003, 0x707f0003, 0x707f0003, 0x707f0003,
3091 +       0x707f0002, 0x707f0002, 0x707f0002, 0x707f0002,
3092 +       0x707f0002, 0x707f0002, 0x707f0002, 0x707f0002,
3093 +       0x707f0002, 0x707f0001, 0x707f0001, 0x707f0001,
3094 +       0x707f0001, 0x707f0001, 0x707f0001, 0x707f0001,
3095 +};
3096 +
3097  const s8 b43_ntab_papd_pga_gain_delta_ipa_2g[] = {
3098         -114, -108, -98, -91, -84, -78, -70, -62,
3099         -54, -46, -39, -31, -23, -15, -8, 0
3100 @@ -3031,31 +3406,8 @@ void b43_ntab_write_bulk(struct b43_wlde
3101                 b43_ntab_write_bulk(dev, offset, ARRAY_SIZE(data), data); \
3102         } while (0)
3103  
3104 -static void b43_nphy_tables_init_rev3(struct b43_wldev *dev)
3105 +static void b43_nphy_tables_init_shared_lut(struct b43_wldev *dev)
3106  {
3107 -       struct ssb_sprom *sprom = dev->dev->bus_sprom;
3108 -       u8 antswlut;
3109 -
3110 -       if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
3111 -               antswlut = sprom->fem.ghz5.antswlut;
3112 -       else
3113 -               antswlut = sprom->fem.ghz2.antswlut;
3114 -
3115 -       /* Static tables */
3116 -       ntab_upload(dev, B43_NTAB_FRAMESTRUCT_R3, b43_ntab_framestruct_r3);
3117 -       ntab_upload(dev, B43_NTAB_PILOT_R3, b43_ntab_pilot_r3);
3118 -       ntab_upload(dev, B43_NTAB_TMAP_R3, b43_ntab_tmap_r3);
3119 -       ntab_upload(dev, B43_NTAB_INTLEVEL_R3, b43_ntab_intlevel_r3);
3120 -       ntab_upload(dev, B43_NTAB_TDTRN_R3, b43_ntab_tdtrn_r3);
3121 -       ntab_upload(dev, B43_NTAB_NOISEVAR_R3, b43_ntab_noisevar_r3);
3122 -       ntab_upload(dev, B43_NTAB_MCS_R3, b43_ntab_mcs_r3);
3123 -       ntab_upload(dev, B43_NTAB_TDI20A0_R3, b43_ntab_tdi20a0_r3);
3124 -       ntab_upload(dev, B43_NTAB_TDI20A1_R3, b43_ntab_tdi20a1_r3);
3125 -       ntab_upload(dev, B43_NTAB_TDI40A0_R3, b43_ntab_tdi40a0_r3);
3126 -       ntab_upload(dev, B43_NTAB_TDI40A1_R3, b43_ntab_tdi40a1_r3);
3127 -       ntab_upload(dev, B43_NTAB_PILOTLT_R3, b43_ntab_pilotlt_r3);
3128 -       ntab_upload(dev, B43_NTAB_CHANEST_R3, b43_ntab_channelest_r3);
3129 -       ntab_upload(dev, B43_NTAB_FRAMELT_R3, b43_ntab_framelookup_r3);
3130         ntab_upload(dev, B43_NTAB_C0_ESTPLT_R3, b43_ntab_estimatepowerlt0_r3);
3131         ntab_upload(dev, B43_NTAB_C1_ESTPLT_R3, b43_ntab_estimatepowerlt1_r3);
3132         ntab_upload(dev, B43_NTAB_C0_ADJPLT_R3, b43_ntab_adjustpower0_r3);
3133 @@ -3066,6 +3418,107 @@ static void b43_nphy_tables_init_rev3(st
3134         ntab_upload(dev, B43_NTAB_C1_IQLT_R3, b43_ntab_iqlt1_r3);
3135         ntab_upload(dev, B43_NTAB_C0_LOFEEDTH_R3, b43_ntab_loftlt0_r3);
3136         ntab_upload(dev, B43_NTAB_C1_LOFEEDTH_R3, b43_ntab_loftlt1_r3);
3137 +}
3138 +
3139 +static void b43_nphy_tables_init_rev7_volatile(struct b43_wldev *dev)
3140 +{
3141 +       struct ssb_sprom *sprom = dev->dev->bus_sprom;
3142 +       u8 antswlut;
3143 +       int core, offset, i;
3144 +
3145 +       const int antswlut0_offsets[] = { 0, 4, 8, }; /* Offsets for values */
3146 +       const u8 antswlut0_values[][3] = {
3147 +               { 0x2, 0x12, 0x8 }, /* Core 0 */
3148 +               { 0x2, 0x18, 0x2 }, /* Core 1 */
3149 +       };
3150 +
3151 +       if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
3152 +               antswlut = sprom->fem.ghz5.antswlut;
3153 +       else
3154 +               antswlut = sprom->fem.ghz2.antswlut;
3155 +
3156 +       switch (antswlut) {
3157 +       case 0:
3158 +               for (core = 0; core < 2; core++) {
3159 +                       for (i = 0; i < ARRAY_SIZE(antswlut0_values[0]); i++) {
3160 +                               offset = core ? 0x20 : 0x00;
3161 +                               offset += antswlut0_offsets[i];
3162 +                               b43_ntab_write(dev, B43_NTAB8(9, offset),
3163 +                                              antswlut0_values[core][i]);
3164 +                       }
3165 +               }
3166 +               break;
3167 +       default:
3168 +               b43err(dev->wl, "Unsupported antswlut: %d\n", antswlut);
3169 +               break;
3170 +       }
3171 +}
3172 +
3173 +static void b43_nphy_tables_init_rev16(struct b43_wldev *dev)
3174 +{
3175 +       /* Static tables */
3176 +       if (dev->phy.do_full_init) {
3177 +               ntab_upload(dev, B43_NTAB_NOISEVAR_R7, b43_ntab_noisevar_r7);
3178 +               b43_nphy_tables_init_shared_lut(dev);
3179 +       }
3180 +
3181 +       /* Volatile tables */
3182 +       b43_nphy_tables_init_rev7_volatile(dev);
3183 +}
3184 +
3185 +static void b43_nphy_tables_init_rev7(struct b43_wldev *dev)
3186 +{
3187 +       /* Static tables */
3188 +       if (dev->phy.do_full_init) {
3189 +               ntab_upload(dev, B43_NTAB_FRAMESTRUCT_R3, b43_ntab_framestruct_r3);
3190 +               ntab_upload(dev, B43_NTAB_PILOT_R3, b43_ntab_pilot_r3);
3191 +               ntab_upload(dev, B43_NTAB_TMAP_R7, b43_ntab_tmap_r7);
3192 +               ntab_upload(dev, B43_NTAB_INTLEVEL_R3, b43_ntab_intlevel_r3);
3193 +               ntab_upload(dev, B43_NTAB_TDTRN_R3, b43_ntab_tdtrn_r3);
3194 +               ntab_upload(dev, B43_NTAB_NOISEVAR_R7, b43_ntab_noisevar_r7);
3195 +               ntab_upload(dev, B43_NTAB_MCS_R3, b43_ntab_mcs_r3);
3196 +               ntab_upload(dev, B43_NTAB_TDI20A0_R3, b43_ntab_tdi20a0_r3);
3197 +               ntab_upload(dev, B43_NTAB_TDI20A1_R3, b43_ntab_tdi20a1_r3);
3198 +               ntab_upload(dev, B43_NTAB_TDI40A0_R3, b43_ntab_tdi40a0_r3);
3199 +               ntab_upload(dev, B43_NTAB_TDI40A1_R3, b43_ntab_tdi40a1_r3);
3200 +               ntab_upload(dev, B43_NTAB_PILOTLT_R3, b43_ntab_pilotlt_r3);
3201 +               ntab_upload(dev, B43_NTAB_CHANEST_R3, b43_ntab_channelest_r3);
3202 +               ntab_upload(dev, B43_NTAB_FRAMELT_R3, b43_ntab_framelookup_r3);
3203 +               b43_nphy_tables_init_shared_lut(dev);
3204 +       }
3205 +
3206 +       /* Volatile tables */
3207 +       b43_nphy_tables_init_rev7_volatile(dev);
3208 +}
3209 +
3210 +static void b43_nphy_tables_init_rev3(struct b43_wldev *dev)
3211 +{
3212 +       struct ssb_sprom *sprom = dev->dev->bus_sprom;
3213 +       u8 antswlut;
3214 +
3215 +       if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
3216 +               antswlut = sprom->fem.ghz5.antswlut;
3217 +       else
3218 +               antswlut = sprom->fem.ghz2.antswlut;
3219 +
3220 +       /* Static tables */
3221 +       if (dev->phy.do_full_init) {
3222 +               ntab_upload(dev, B43_NTAB_FRAMESTRUCT_R3, b43_ntab_framestruct_r3);
3223 +               ntab_upload(dev, B43_NTAB_PILOT_R3, b43_ntab_pilot_r3);
3224 +               ntab_upload(dev, B43_NTAB_TMAP_R3, b43_ntab_tmap_r3);
3225 +               ntab_upload(dev, B43_NTAB_INTLEVEL_R3, b43_ntab_intlevel_r3);
3226 +               ntab_upload(dev, B43_NTAB_TDTRN_R3, b43_ntab_tdtrn_r3);
3227 +               ntab_upload(dev, B43_NTAB_NOISEVAR_R3, b43_ntab_noisevar_r3);
3228 +               ntab_upload(dev, B43_NTAB_MCS_R3, b43_ntab_mcs_r3);
3229 +               ntab_upload(dev, B43_NTAB_TDI20A0_R3, b43_ntab_tdi20a0_r3);
3230 +               ntab_upload(dev, B43_NTAB_TDI20A1_R3, b43_ntab_tdi20a1_r3);
3231 +               ntab_upload(dev, B43_NTAB_TDI40A0_R3, b43_ntab_tdi40a0_r3);
3232 +               ntab_upload(dev, B43_NTAB_TDI40A1_R3, b43_ntab_tdi40a1_r3);
3233 +               ntab_upload(dev, B43_NTAB_PILOTLT_R3, b43_ntab_pilotlt_r3);
3234 +               ntab_upload(dev, B43_NTAB_CHANEST_R3, b43_ntab_channelest_r3);
3235 +               ntab_upload(dev, B43_NTAB_FRAMELT_R3, b43_ntab_framelookup_r3);
3236 +               b43_nphy_tables_init_shared_lut(dev);
3237 +       }
3238  
3239         /* Volatile tables */
3240         if (antswlut < ARRAY_SIZE(b43_ntab_antswctl_r3))
3241 @@ -3078,20 +3531,22 @@ static void b43_nphy_tables_init_rev3(st
3242  static void b43_nphy_tables_init_rev0(struct b43_wldev *dev)
3243  {
3244         /* Static tables */
3245 -       ntab_upload(dev, B43_NTAB_FRAMESTRUCT, b43_ntab_framestruct);
3246 -       ntab_upload(dev, B43_NTAB_FRAMELT, b43_ntab_framelookup);
3247 -       ntab_upload(dev, B43_NTAB_TMAP, b43_ntab_tmap);
3248 -       ntab_upload(dev, B43_NTAB_TDTRN, b43_ntab_tdtrn);
3249 -       ntab_upload(dev, B43_NTAB_INTLEVEL, b43_ntab_intlevel);
3250 -       ntab_upload(dev, B43_NTAB_PILOT, b43_ntab_pilot);
3251 -       ntab_upload(dev, B43_NTAB_TDI20A0, b43_ntab_tdi20a0);
3252 -       ntab_upload(dev, B43_NTAB_TDI20A1, b43_ntab_tdi20a1);
3253 -       ntab_upload(dev, B43_NTAB_TDI40A0, b43_ntab_tdi40a0);
3254 -       ntab_upload(dev, B43_NTAB_TDI40A1, b43_ntab_tdi40a1);
3255 -       ntab_upload(dev, B43_NTAB_CHANEST, b43_ntab_channelest);
3256 -       ntab_upload(dev, B43_NTAB_MCS, b43_ntab_mcs);
3257 -       ntab_upload(dev, B43_NTAB_NOISEVAR10, b43_ntab_noisevar10);
3258 -       ntab_upload(dev, B43_NTAB_NOISEVAR11, b43_ntab_noisevar11);
3259 +       if (dev->phy.do_full_init) {
3260 +               ntab_upload(dev, B43_NTAB_FRAMESTRUCT, b43_ntab_framestruct);
3261 +               ntab_upload(dev, B43_NTAB_FRAMELT, b43_ntab_framelookup);
3262 +               ntab_upload(dev, B43_NTAB_TMAP, b43_ntab_tmap);
3263 +               ntab_upload(dev, B43_NTAB_TDTRN, b43_ntab_tdtrn);
3264 +               ntab_upload(dev, B43_NTAB_INTLEVEL, b43_ntab_intlevel);
3265 +               ntab_upload(dev, B43_NTAB_PILOT, b43_ntab_pilot);
3266 +               ntab_upload(dev, B43_NTAB_TDI20A0, b43_ntab_tdi20a0);
3267 +               ntab_upload(dev, B43_NTAB_TDI20A1, b43_ntab_tdi20a1);
3268 +               ntab_upload(dev, B43_NTAB_TDI40A0, b43_ntab_tdi40a0);
3269 +               ntab_upload(dev, B43_NTAB_TDI40A1, b43_ntab_tdi40a1);
3270 +               ntab_upload(dev, B43_NTAB_CHANEST, b43_ntab_channelest);
3271 +               ntab_upload(dev, B43_NTAB_MCS, b43_ntab_mcs);
3272 +               ntab_upload(dev, B43_NTAB_NOISEVAR10, b43_ntab_noisevar10);
3273 +               ntab_upload(dev, B43_NTAB_NOISEVAR11, b43_ntab_noisevar11);
3274 +       }
3275  
3276         /* Volatile tables */
3277         ntab_upload(dev, B43_NTAB_BDI, b43_ntab_bdi);
3278 @@ -3111,7 +3566,11 @@ static void b43_nphy_tables_init_rev0(st
3279  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/InitTables */
3280  void b43_nphy_tables_init(struct b43_wldev *dev)
3281  {
3282 -       if (dev->phy.rev >= 3)
3283 +       if (dev->phy.rev >= 16)
3284 +               b43_nphy_tables_init_rev16(dev);
3285 +       else if (dev->phy.rev >= 7)
3286 +               b43_nphy_tables_init_rev7(dev);
3287 +       else if (dev->phy.rev >= 3)
3288                 b43_nphy_tables_init_rev3(dev);
3289         else
3290                 b43_nphy_tables_init_rev0(dev);
3291 @@ -3120,23 +3579,51 @@ void b43_nphy_tables_init(struct b43_wld
3292  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetIpaGainTbl */
3293  static const u32 *b43_nphy_get_ipa_gain_table(struct b43_wldev *dev)
3294  {
3295 +       struct b43_phy *phy = &dev->phy;
3296 +
3297         if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
3298 -               if (dev->phy.rev >= 6) {
3299 -                       if (dev->dev->chip_id == 47162)
3300 -                               return txpwrctrl_tx_gain_ipa_rev5;
3301 -                       return txpwrctrl_tx_gain_ipa_rev6;
3302 -               } else if (dev->phy.rev >= 5) {
3303 -                       return txpwrctrl_tx_gain_ipa_rev5;
3304 -               } else {
3305 -                       return txpwrctrl_tx_gain_ipa;
3306 +               switch (phy->rev) {
3307 +               case 16:
3308 +                       if (phy->radio_rev == 9)
3309 +                               return b43_ntab_tx_gain_ipa_2057_rev9_2g;
3310 +                       break;
3311 +               case 8:
3312 +                       if (phy->radio_rev == 5)
3313 +                               return b43_ntab_tx_gain_ipa_2057_rev5_2g;
3314 +                       break;
3315 +               case 6:
3316 +                       if (dev->dev->chip_id == BCMA_CHIP_ID_BCM47162)
3317 +                               return b43_ntab_tx_gain_ipa_rev5_2g;
3318 +                       return b43_ntab_tx_gain_ipa_rev6_2g;
3319 +               case 5:
3320 +                       return b43_ntab_tx_gain_ipa_rev5_2g;
3321 +               case 4:
3322 +               case 3:
3323 +                       return b43_ntab_tx_gain_ipa_rev3_2g;
3324                 }
3325 +
3326 +               b43err(dev->wl,
3327 +                      "No 2GHz IPA gain table available for this device\n");
3328 +               return NULL;
3329         } else {
3330 -               return txpwrctrl_tx_gain_ipa_5g;
3331 +               switch (phy->rev) {
3332 +               case 16:
3333 +                       if (phy->radio_rev == 9)
3334 +                               return b43_ntab_tx_gain_ipa_2057_rev9_5g;
3335 +                       break;
3336 +               case 3 ... 6:
3337 +                       return b43_ntab_tx_gain_ipa_rev3_5g;
3338 +               }
3339 +
3340 +               b43err(dev->wl,
3341 +                      "No 5GHz IPA gain table available for this device\n");
3342 +               return NULL;
3343         }
3344  }
3345  
3346  const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev)
3347  {
3348 +       struct b43_phy *phy = &dev->phy;
3349         enum ieee80211_band band = b43_current_band(dev->wl);
3350         struct ssb_sprom *sprom = dev->dev->bus_sprom;
3351  
3352 @@ -3148,19 +3635,36 @@ const u32 *b43_nphy_get_tx_gain_table(st
3353             (dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ)) {
3354                 return b43_nphy_get_ipa_gain_table(dev);
3355         } else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
3356 -               if (dev->phy.rev == 3)
3357 -                       return b43_ntab_tx_gain_rev3_5ghz;
3358 -               if (dev->phy.rev == 4)
3359 +               switch (phy->rev) {
3360 +               case 6:
3361 +               case 5:
3362 +                       return b43_ntab_tx_gain_epa_rev5_5g;
3363 +               case 4:
3364                         return sprom->fem.ghz5.extpa_gain == 3 ?
3365 -                               b43_ntab_tx_gain_rev4_5ghz :
3366 -                               b43_ntab_tx_gain_rev4_5ghz; /* FIXME */
3367 -               else
3368 -                       return b43_ntab_tx_gain_rev5plus_5ghz;
3369 +                               b43_ntab_tx_gain_epa_rev4_5g :
3370 +                               b43_ntab_tx_gain_epa_rev4_hi_pwr_5g;
3371 +               case 3:
3372 +                       return b43_ntab_tx_gain_epa_rev3_5g;
3373 +               default:
3374 +                       b43err(dev->wl,
3375 +                              "No 5GHz EPA gain table available for this device\n");
3376 +                       return NULL;
3377 +               }
3378         } else {
3379 -               if (dev->phy.rev >= 5 && sprom->fem.ghz5.extpa_gain == 3)
3380 -                       return b43_ntab_tx_gain_rev3plus_2ghz; /* FIXME */
3381 -               else
3382 -                       return b43_ntab_tx_gain_rev3plus_2ghz;
3383 +               switch (phy->rev) {
3384 +               case 6:
3385 +               case 5:
3386 +                       if (sprom->fem.ghz5.extpa_gain == 3)
3387 +                               return b43_ntab_tx_gain_epa_rev3_hi_pwr_2g;
3388 +                       /* fall through */
3389 +               case 4:
3390 +               case 3:
3391 +                       return b43_ntab_tx_gain_epa_rev3_2g;
3392 +               default:
3393 +                       b43err(dev->wl,
3394 +                              "No 2GHz EPA gain table available for this device\n");
3395 +                       return NULL;
3396 +               }
3397         }
3398  }
3399  
3400 @@ -3187,7 +3691,7 @@ struct nphy_gain_ctl_workaround_entry *b
3401         /* Some workarounds to the workarounds... */
3402         if (ghz5 && dev->phy.rev >= 6) {
3403                 if (dev->phy.radio_rev == 11 &&
3404 -                   !b43_channel_type_is_40mhz(dev->phy.channel_type))
3405 +                   !b43_is_40mhz(dev))
3406                         e->cliplo_gain = 0x2d;
3407         } else if (!ghz5 && dev->phy.rev >= 5) {
3408                 static const int gain_data[] = {0x0062, 0x0064, 0x006a, 0x106a,
3409 --- a/drivers/net/wireless/b43/Kconfig
3410 +++ b/drivers/net/wireless/b43/Kconfig
3411 @@ -37,7 +37,7 @@ config B43_SSB
3412  choice
3413         prompt "Supported bus types"
3414         depends on B43
3415 -       default B43_BCMA_AND_SSB
3416 +       default B43_BUSES_BCMA_AND_SSB
3417  
3418  config B43_BUSES_BCMA_AND_SSB
3419         bool "BCMA and SSB"
3420 @@ -123,6 +123,15 @@ config B43_PIO
3421         select SSB_BLOCKIO
3422         default y
3423  
3424 +config B43_PHY_G
3425 +       bool "Support for G-PHY (802.11g) devices"
3426 +       depends on B43 && B43_SSB
3427 +       default y
3428 +       ---help---
3429 +         This PHY type can be found in the following chipsets:
3430 +         PCI: BCM4306, BCM4311, BCM4318
3431 +         SoC: BCM4712, BCM5352E
3432 +
3433  config B43_PHY_N
3434         bool "Support for 802.11n (N-PHY) devices"
3435         depends on B43
3436 --- a/drivers/net/wireless/b43/phy_ht.c
3437 +++ b/drivers/net/wireless/b43/phy_ht.c
3438 @@ -596,7 +596,7 @@ static void b43_phy_ht_tx_power_ctl_setu
3439         u8 target[3];
3440         s16 a1[3], b0[3], b1[3];
3441  
3442 -       u16 freq = dev->phy.channel_freq;
3443 +       u16 freq = dev->phy.chandef->chan->center_freq;
3444         int i, c;
3445  
3446         if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
3447 --- a/drivers/net/wireless/b43/phy_a.h
3448 +++ b/drivers/net/wireless/b43/phy_a.h
3449 @@ -123,8 +123,4 @@ struct b43_phy_a {
3450   */
3451  void b43_phy_inita(struct b43_wldev *dev);
3452  
3453 -
3454 -struct b43_phy_operations;
3455 -extern const struct b43_phy_operations b43_phyops_a;
3456 -
3457  #endif /* LINUX_B43_PHY_A_H_ */
3458 --- a/drivers/net/wireless/b43/Makefile
3459 +++ b/drivers/net/wireless/b43/Makefile
3460 @@ -1,13 +1,11 @@
3461  b43-y                          += main.o
3462  b43-y                          += bus.o
3463 -b43-y                          += tables.o
3464 +b43-$(CPTCFG_B43_PHY_G)                += phy_a.o phy_g.o tables.o lo.o wa.o
3465  b43-$(CPTCFG_B43_PHY_N)                += tables_nphy.o
3466  b43-$(CPTCFG_B43_PHY_N)                += radio_2055.o
3467  b43-$(CPTCFG_B43_PHY_N)                += radio_2056.o
3468  b43-$(CPTCFG_B43_PHY_N)                += radio_2057.o
3469  b43-y                          += phy_common.o
3470 -b43-y                          += phy_g.o
3471 -b43-y                          += phy_a.o
3472  b43-$(CPTCFG_B43_PHY_N)                += phy_n.o
3473  b43-$(CPTCFG_B43_PHY_LP)       += phy_lp.o
3474  b43-$(CPTCFG_B43_PHY_LP)       += tables_lpphy.o
3475 @@ -17,8 +15,6 @@ b43-$(CPTCFG_B43_PHY_HT)      += radio_2059.o
3476  b43-$(CPTCFG_B43_PHY_LCN)      += phy_lcn.o tables_phy_lcn.o
3477  b43-y                          += sysfs.o
3478  b43-y                          += xmit.o
3479 -b43-y                          += lo.o
3480 -b43-y                          += wa.o
3481  b43-y                          += dma.o
3482  b43-y                          += pio.o
3483  b43-y                          += rfkill.o
3484 --- a/drivers/net/wireless/b43/phy_a.c
3485 +++ b/drivers/net/wireless/b43/phy_a.c
3486 @@ -573,7 +573,7 @@ static void b43_aphy_op_pwork_60sec(stru
3487  {//TODO
3488  }
3489  
3490 -const struct b43_phy_operations b43_phyops_a = {
3491 +static const struct b43_phy_operations b43_phyops_a = {
3492         .allocate               = b43_aphy_op_allocate,
3493         .free                   = b43_aphy_op_free,
3494         .prepare_structs        = b43_aphy_op_prepare_structs,
3495 --- a/drivers/net/wireless/b43/radio_2057.c
3496 +++ b/drivers/net/wireless/b43/radio_2057.c
3497 @@ -26,7 +26,7 @@
3498  #include "radio_2057.h"
3499  #include "phy_common.h"
3500  
3501 -static u16 r2057_rev4_init[42][2] = {
3502 +static u16 r2057_rev4_init[][2] = {
3503         { 0x0E, 0x20 }, { 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 },
3504         { 0x35, 0x26 }, { 0x3C, 0xff }, { 0x3D, 0xff }, { 0x3E, 0xff },
3505         { 0x3F, 0xff }, { 0x62, 0x33 }, { 0x8A, 0xf0 }, { 0x8B, 0x10 },
3506 @@ -40,7 +40,7 @@ static u16 r2057_rev4_init[42][2] = {
3507         { 0x1AB, 0x00 }, { 0x1AC, 0x00 },
3508  };
3509  
3510 -static u16 r2057_rev5_init[44][2] = {
3511 +static u16 r2057_rev5_init[][2] = {
3512         { 0x00, 0x00 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x23, 0x6 },
3513         { 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 },
3514         { 0x59, 0x88 }, { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f },
3515 @@ -54,7 +54,7 @@ static u16 r2057_rev5_init[44][2] = {
3516         { 0x1AC, 0x00 }, { 0x1B7, 0x0c }, { 0x1C1, 0x01 }, { 0x1C2, 0x80 },
3517  };
3518  
3519 -static u16 r2057_rev5a_init[45][2] = {
3520 +static u16 r2057_rev5a_init[][2] = {
3521         { 0x00, 0x15 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x23, 0x6 },
3522         { 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 },
3523         { 0x59, 0x88 }, { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f },
3524 @@ -69,7 +69,7 @@ static u16 r2057_rev5a_init[45][2] = {
3525         { 0x1C2, 0x80 },
3526  };
3527  
3528 -static u16 r2057_rev7_init[54][2] = {
3529 +static u16 r2057_rev7_init[][2] = {
3530         { 0x00, 0x00 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x31, 0x00 },
3531         { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 }, { 0x59, 0x88 },
3532         { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f }, { 0x64, 0x13 },
3533 @@ -86,7 +86,8 @@ static u16 r2057_rev7_init[54][2] = {
3534         { 0x1B7, 0x05 }, { 0x1C2, 0xa0 },
3535  };
3536  
3537 -static u16 r2057_rev8_init[54][2] = {
3538 +/* TODO: Which devices should use it?
3539 +static u16 r2057_rev8_init[][2] = {
3540         { 0x00, 0x08 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x31, 0x00 },
3541         { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 }, { 0x59, 0x88 },
3542         { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f }, { 0x64, 0x0f },
3543 @@ -102,6 +103,346 @@ static u16 r2057_rev8_init[54][2] = {
3544         { 0x1A6, 0x00 }, { 0x1AA, 0x00 }, { 0x1AB, 0x00 }, { 0x1AC, 0x00 },
3545         { 0x1B7, 0x05 }, { 0x1C2, 0xa0 },
3546  };
3547 +*/
3548 +
3549 +/* Extracted from MMIO dump of 6.30.223.141 */
3550 +static u16 r2057_rev9_init[][2] = {
3551 +       { 0x27, 0x1f }, { 0x28, 0x0a }, { 0x29, 0x2f }, { 0x42, 0x1f },
3552 +       { 0x48, 0x3f }, { 0x5c, 0x41 }, { 0x63, 0x14 }, { 0x64, 0x12 },
3553 +       { 0x66, 0xff }, { 0x74, 0xa3 }, { 0x7b, 0x14 }, { 0x7c, 0x14 },
3554 +       { 0x7d, 0xee }, { 0x86, 0xc0 }, { 0xc4, 0x10 }, { 0xc9, 0x01 },
3555 +       { 0xe1, 0x41 }, { 0xe8, 0x14 }, { 0xe9, 0x12 }, { 0xeb, 0xff },
3556 +       { 0xf5, 0x0a }, { 0xf8, 0x09 }, { 0xf9, 0xa3 }, { 0x100, 0x14 },
3557 +       { 0x101, 0x10 }, { 0x102, 0xee }, { 0x10b, 0xc0 }, { 0x149, 0x10 },
3558 +       { 0x14e, 0x01 }, { 0x1b7, 0x05 }, { 0x1c2, 0xa0 },
3559 +};
3560 +
3561 +#define RADIOREGS7(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \
3562 +                  r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, \
3563 +                  r20, r21, r22, r23, r24, r25, r26, r27) \
3564 +       .radio_vcocal_countval0                 = r00,  \
3565 +       .radio_vcocal_countval1                 = r01,  \
3566 +       .radio_rfpll_refmaster_sparextalsize    = r02,  \
3567 +       .radio_rfpll_loopfilter_r1              = r03,  \
3568 +       .radio_rfpll_loopfilter_c2              = r04,  \
3569 +       .radio_rfpll_loopfilter_c1              = r05,  \
3570 +       .radio_cp_kpd_idac                      = r06,  \
3571 +       .radio_rfpll_mmd0                       = r07,  \
3572 +       .radio_rfpll_mmd1                       = r08,  \
3573 +       .radio_vcobuf_tune                      = r09,  \
3574 +       .radio_logen_mx2g_tune                  = r10,  \
3575 +       .radio_logen_mx5g_tune                  = r11,  \
3576 +       .radio_logen_indbuf2g_tune              = r12,  \
3577 +       .radio_logen_indbuf5g_tune              = r13,  \
3578 +       .radio_txmix2g_tune_boost_pu_core0      = r14,  \
3579 +       .radio_pad2g_tune_pus_core0             = r15,  \
3580 +       .radio_pga_boost_tune_core0             = r16,  \
3581 +       .radio_txmix5g_boost_tune_core0         = r17,  \
3582 +       .radio_pad5g_tune_misc_pus_core0        = r18,  \
3583 +       .radio_lna2g_tune_core0                 = r19,  \
3584 +       .radio_lna5g_tune_core0                 = r20,  \
3585 +       .radio_txmix2g_tune_boost_pu_core1      = r21,  \
3586 +       .radio_pad2g_tune_pus_core1             = r22,  \
3587 +       .radio_pga_boost_tune_core1             = r23,  \
3588 +       .radio_txmix5g_boost_tune_core1         = r24,  \
3589 +       .radio_pad5g_tune_misc_pus_core1        = r25,  \
3590 +       .radio_lna2g_tune_core1                 = r26,  \
3591 +       .radio_lna5g_tune_core1                 = r27
3592 +
3593 +#define RADIOREGS7_2G(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \
3594 +                     r10, r11, r12, r13, r14, r15, r16, r17) \
3595 +       .radio_vcocal_countval0                 = r00,  \
3596 +       .radio_vcocal_countval1                 = r01,  \
3597 +       .radio_rfpll_refmaster_sparextalsize    = r02,  \
3598 +       .radio_rfpll_loopfilter_r1              = r03,  \
3599 +       .radio_rfpll_loopfilter_c2              = r04,  \
3600 +       .radio_rfpll_loopfilter_c1              = r05,  \
3601 +       .radio_cp_kpd_idac                      = r06,  \
3602 +       .radio_rfpll_mmd0                       = r07,  \
3603 +       .radio_rfpll_mmd1                       = r08,  \
3604 +       .radio_vcobuf_tune                      = r09,  \
3605 +       .radio_logen_mx2g_tune                  = r10,  \
3606 +       .radio_logen_indbuf2g_tune              = r11,  \
3607 +       .radio_lna2g_tune_core0                 = r12,  \
3608 +       .radio_txmix2g_tune_boost_pu_core0      = r13,  \
3609 +       .radio_pad2g_tune_pus_core0             = r14,  \
3610 +       .radio_lna2g_tune_core1                 = r15,  \
3611 +       .radio_txmix2g_tune_boost_pu_core1      = r16,  \
3612 +       .radio_pad2g_tune_pus_core1             = r17
3613 +
3614 +#define PHYREGS(r0, r1, r2, r3, r4, r5)        \
3615 +       .phy_regs.phy_bw1a      = r0,   \
3616 +       .phy_regs.phy_bw2       = r1,   \
3617 +       .phy_regs.phy_bw3       = r2,   \
3618 +       .phy_regs.phy_bw4       = r3,   \
3619 +       .phy_regs.phy_bw5       = r4,   \
3620 +       .phy_regs.phy_bw6       = r5
3621 +
3622 +/* Copied from brcmsmac (5.75.11): chan_info_nphyrev8_2057_rev5 */
3623 +static const struct b43_nphy_chantabent_rev7_2g b43_nphy_chantab_phy_rev8_radio_rev5[] = {
3624 +       {
3625 +               .freq                   = 2412,
3626 +               RADIOREGS7_2G(0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c,
3627 +                             0x09, 0x0d, 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61,
3628 +                             0x03, 0xff),
3629 +               PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
3630 +       },
3631 +       {
3632 +               .freq                   = 2417,
3633 +               RADIOREGS7_2G(0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71,
3634 +                             0x09, 0x0d, 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61,
3635 +                             0x03, 0xff),
3636 +               PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
3637 +       },
3638 +       {
3639 +               .freq                   = 2422,
3640 +               RADIOREGS7_2G(0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76,
3641 +                             0x09, 0x0d, 0x08, 0x0e, 0x61, 0x03, 0xef, 0x61,
3642 +                             0x03, 0xef),
3643 +               PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
3644 +       },
3645 +       {
3646 +               .freq                   = 2427,
3647 +               RADIOREGS7_2G(0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b,
3648 +                             0x09, 0x0c, 0x08, 0x0e, 0x61, 0x03, 0xdf, 0x61,
3649 +                             0x03, 0xdf),
3650 +               PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
3651 +       },
3652 +       {
3653 +               .freq                   = 2432,
3654 +               RADIOREGS7_2G(0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80,
3655 +                             0x09, 0x0c, 0x07, 0x0d, 0x61, 0x03, 0xcf, 0x61,
3656 +                             0x03, 0xcf),
3657 +               PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
3658 +       },
3659 +       {
3660 +               .freq                   = 2437,
3661 +               RADIOREGS7_2G(0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85,
3662 +                             0x09, 0x0c, 0x07, 0x0d, 0x61, 0x03, 0xbf, 0x61,
3663 +                             0x03, 0xbf),
3664 +               PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
3665 +       },
3666 +       {
3667 +               .freq                   = 2442,
3668 +               RADIOREGS7_2G(0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a,
3669 +                             0x09, 0x0b, 0x07, 0x0d, 0x61, 0x03, 0xaf, 0x61,
3670 +                             0x03, 0xaf),
3671 +               PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
3672 +       },
3673 +       {
3674 +               .freq                   = 2447,
3675 +               RADIOREGS7_2G(0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f,
3676 +                             0x09, 0x0b, 0x07, 0x0d, 0x61, 0x03, 0x9f, 0x61,
3677 +                             0x03, 0x9f),
3678 +               PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
3679 +       },
3680 +       {
3681 +               .freq                   = 2452,
3682 +               RADIOREGS7_2G(0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94,
3683 +                             0x09, 0x0b, 0x07, 0x0d, 0x61, 0x03, 0x8f, 0x61,
3684 +                             0x03, 0x8f),
3685 +               PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
3686 +       },
3687 +       {
3688 +               .freq                   = 2457,
3689 +               RADIOREGS7_2G(0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99,
3690 +                             0x09, 0x0b, 0x07, 0x0c, 0x61, 0x03, 0x7f, 0x61,
3691 +                             0x03, 0x7f),
3692 +               PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
3693 +       },
3694 +       {
3695 +               .freq                   = 2462,
3696 +               RADIOREGS7_2G(0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e,
3697 +                             0x09, 0x0b, 0x07, 0x0c, 0x61, 0x03, 0x6f, 0x61,
3698 +                             0x03, 0x6f),
3699 +               PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
3700 +       },
3701 +       {
3702 +               .freq                   = 2467,
3703 +               RADIOREGS7_2G(0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3,
3704 +                             0x09, 0x0b, 0x06, 0x0c, 0x61, 0x03, 0x5f, 0x61,
3705 +                             0x03, 0x5f),
3706 +               PHYREGS(0x03df, 0x03db, 0x03d7, 0x0422, 0x0427, 0x042b),
3707 +       },
3708 +       {
3709 +               .freq                   = 2472,
3710 +               RADIOREGS7_2G(0x70, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa8,
3711 +                             0x09, 0x0a, 0x06, 0x0b, 0x61, 0x03, 0x4f, 0x61,
3712 +                             0x03, 0x4f),
3713 +               PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429),
3714 +       },
3715 +       {
3716 +               .freq                   = 2484,
3717 +               RADIOREGS7_2G(0x78, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xb4,
3718 +                             0x09, 0x0a, 0x06, 0x0b, 0x61, 0x03, 0x3f, 0x61,
3719 +                             0x03, 0x3f),
3720 +               PHYREGS(0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424),
3721 +       }
3722 +};
3723 +
3724 +/* Extracted from MMIO dump of 6.30.223.141 */
3725 +static const struct b43_nphy_chantabent_rev7 b43_nphy_chantab_phy_rev16_radio_rev9[] = {
3726 +       {
3727 +               .freq                   = 2412,
3728 +               RADIOREGS7(0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c,
3729 +                          0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x41, 0x63,
3730 +                          0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
3731 +                          0x00, 0x00, 0xf0, 0x00),
3732 +               PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
3733 +       },
3734 +       {
3735 +               .freq                   = 2417,
3736 +               RADIOREGS7(0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71,
3737 +                          0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x41, 0x63,
3738 +                          0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
3739 +                          0x00, 0x00, 0xf0, 0x00),
3740 +               PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
3741 +       },
3742 +       {
3743 +               .freq                   = 2422,
3744 +               RADIOREGS7(0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76,
3745 +                          0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x41, 0x63,
3746 +                          0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
3747 +                          0x00, 0x00, 0xf0, 0x00),
3748 +               PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
3749 +       },
3750 +       {
3751 +               .freq                   = 2427,
3752 +               RADIOREGS7(0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b,
3753 +                          0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x41, 0x63,
3754 +                          0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
3755 +                          0x00, 0x00, 0xf0, 0x00),
3756 +               PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
3757 +       },
3758 +       {
3759 +               .freq                   = 2432,
3760 +               RADIOREGS7(0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80,
3761 +                          0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x41, 0x63,
3762 +                          0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
3763 +                          0x00, 0x00, 0xf0, 0x00),
3764 +               PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
3765 +       },
3766 +       {
3767 +               .freq                   = 2437,
3768 +               RADIOREGS7(0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85,
3769 +                          0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x41, 0x63,
3770 +                          0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
3771 +                          0x00, 0x00, 0xf0, 0x00),
3772 +               PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
3773 +       },
3774 +       {
3775 +               .freq                   = 2442,
3776 +               RADIOREGS7(0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a,
3777 +                          0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x41, 0x63,
3778 +                          0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
3779 +                          0x00, 0x00, 0xf0, 0x00),
3780 +               PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
3781 +       },
3782 +       {
3783 +               .freq                   = 2447,
3784 +               RADIOREGS7(0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f,
3785 +                          0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x41, 0x63,
3786 +                          0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
3787 +                          0x00, 0x00, 0xf0, 0x00),
3788 +               PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
3789 +       },
3790 +       {
3791 +               .freq                   = 2452,
3792 +               RADIOREGS7(0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94,
3793 +                          0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x41, 0x63,
3794 +                          0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
3795 +                          0x00, 0x00, 0xf0, 0x00),
3796 +               PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
3797 +       },
3798 +       {
3799 +               .freq                   = 2457,
3800 +               RADIOREGS7(0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99,
3801 +                          0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x41, 0x63,
3802 +                          0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
3803 +                          0x00, 0x00, 0xf0, 0x00),
3804 +               PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
3805 +       },
3806 +       {
3807 +               .freq                   = 2462,
3808 +               RADIOREGS7(0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e,
3809 +                          0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x41, 0x63,
3810 +                          0x00, 0x00, 0x00, 0xf0, 0x00, 0x41, 0x63, 0x00,
3811 +                          0x00, 0x00, 0xf0, 0x00),
3812 +               PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
3813 +       },
3814 +       {
3815 +               .freq                   = 5180,
3816 +               RADIOREGS7(0xbe, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x06,
3817 +                          0x02, 0x0e, 0x00, 0x0e, 0x00, 0x9e, 0x00, 0x00,
3818 +                          0x9f, 0x2f, 0xa3, 0x00, 0xfc, 0x00, 0x00, 0x4f,
3819 +                          0x3a, 0x83, 0x00, 0xfc),
3820 +               PHYREGS(0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb),
3821 +       },
3822 +       {
3823 +               .freq                   = 5200,
3824 +               RADIOREGS7(0xc5, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x08,
3825 +                          0x02, 0x0e, 0x00, 0x0e, 0x00, 0x9e, 0x00, 0x00,
3826 +                          0x7f, 0x2f, 0x83, 0x00, 0xf8, 0x00, 0x00, 0x4c,
3827 +                          0x4a, 0x83, 0x00, 0xf8),
3828 +               PHYREGS(0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9),
3829 +       },
3830 +       {
3831 +               .freq                   = 5220,
3832 +               RADIOREGS7(0xcc, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x0a,
3833 +                          0x02, 0x0e, 0x00, 0x0e, 0x00, 0x9e, 0x00, 0x00,
3834 +                          0x6d, 0x3d, 0x83, 0x00, 0xf8, 0x00, 0x00, 0x2d,
3835 +                          0x2a, 0x73, 0x00, 0xf8),
3836 +               PHYREGS(0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7),
3837 +       },
3838 +       {
3839 +               .freq                   = 5240,
3840 +               RADIOREGS7(0xd2, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x0c,
3841 +                          0x02, 0x0d, 0x00, 0x0d, 0x00, 0x8d, 0x00, 0x00,
3842 +                          0x4d, 0x1c, 0x73, 0x00, 0xf8, 0x00, 0x00, 0x4d,
3843 +                          0x2b, 0x73, 0x00, 0xf8),
3844 +               PHYREGS(0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5),
3845 +       },
3846 +       {
3847 +               .freq                   = 5745,
3848 +               RADIOREGS7(0x7b, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x7d,
3849 +                          0x04, 0x08, 0x00, 0x06, 0x00, 0x15, 0x00, 0x00,
3850 +                          0x08, 0x03, 0x03, 0x00, 0x30, 0x00, 0x00, 0x06,
3851 +                          0x02, 0x03, 0x00, 0x30),
3852 +               PHYREGS(0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9),
3853 +       },
3854 +       {
3855 +               .freq                   = 5765,
3856 +               RADIOREGS7(0x81, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x81,
3857 +                          0x04, 0x08, 0x00, 0x06, 0x00, 0x15, 0x00, 0x00,
3858 +                          0x06, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x05,
3859 +                          0x02, 0x03, 0x00, 0x00),
3860 +               PHYREGS(0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8),
3861 +       },
3862 +       {
3863 +               .freq                   = 5785,
3864 +               RADIOREGS7(0x88, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x85,
3865 +                          0x04, 0x08, 0x00, 0x06, 0x00, 0x15, 0x00, 0x00,
3866 +                          0x08, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x05,
3867 +                          0x21, 0x03, 0x00, 0x00),
3868 +               PHYREGS(0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6),
3869 +       },
3870 +       {
3871 +               .freq                   = 5805,
3872 +               RADIOREGS7(0x8f, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x89,
3873 +                          0x04, 0x07, 0x00, 0x06, 0x00, 0x04, 0x00, 0x00,
3874 +                          0x06, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03,
3875 +                          0x00, 0x03, 0x00, 0x00),
3876 +               PHYREGS(0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4),
3877 +       },
3878 +       {
3879 +               .freq                   = 5825,
3880 +               RADIOREGS7(0x95, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x8d,
3881 +                          0x04, 0x07, 0x00, 0x05, 0x00, 0x03, 0x00, 0x00,
3882 +                          0x05, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03,
3883 +                          0x00, 0x03, 0x00, 0x00),
3884 +               PHYREGS(0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3),
3885 +       },
3886 +};
3887  
3888  void r2057_upload_inittabs(struct b43_wldev *dev)
3889  {
3890 @@ -109,33 +450,87 @@ void r2057_upload_inittabs(struct b43_wl
3891         u16 *table = NULL;
3892         u16 size, i;
3893  
3894 -       if (phy->rev == 7) {
3895 +       switch (phy->rev) {
3896 +       case 7:
3897                 table = r2057_rev4_init[0];
3898                 size = ARRAY_SIZE(r2057_rev4_init);
3899 -       } else if (phy->rev == 8 || phy->rev == 9) {
3900 +               break;
3901 +       case 8:
3902                 if (phy->radio_rev == 5) {
3903 -                       if (phy->radio_rev == 8) {
3904 -                               table = r2057_rev5_init[0];
3905 -                               size = ARRAY_SIZE(r2057_rev5_init);
3906 -                       } else {
3907 -                               table = r2057_rev5a_init[0];
3908 -                               size = ARRAY_SIZE(r2057_rev5a_init);
3909 -                       }
3910 +                       table = r2057_rev5_init[0];
3911 +                       size = ARRAY_SIZE(r2057_rev5_init);
3912                 } else if (phy->radio_rev == 7) {
3913                         table = r2057_rev7_init[0];
3914                         size = ARRAY_SIZE(r2057_rev7_init);
3915 -               } else if (phy->radio_rev == 9) {
3916 -                       table = r2057_rev8_init[0];
3917 -                       size = ARRAY_SIZE(r2057_rev8_init);
3918                 }
3919 +               break;
3920 +       case 9:
3921 +               if (phy->radio_rev == 5) {
3922 +                       table = r2057_rev5a_init[0];
3923 +                       size = ARRAY_SIZE(r2057_rev5a_init);
3924 +               }
3925 +               break;
3926 +       case 16:
3927 +               if (phy->radio_rev == 9) {
3928 +                       table = r2057_rev9_init[0];
3929 +                       size = ARRAY_SIZE(r2057_rev9_init);
3930 +               }
3931 +               break;
3932         }
3933  
3934 +       B43_WARN_ON(!table);
3935 +
3936         if (table) {
3937 -               for (i = 0; i < 10; i++) {
3938 -                       pr_info("radio_write 0x%X ", *table);
3939 -                       table++;
3940 -                       pr_info("0x%X\n", *table);
3941 -                       table++;
3942 +               for (i = 0; i < size; i++, table += 2)
3943 +                       b43_radio_write(dev, table[0], table[1]);
3944 +       }
3945 +}
3946 +
3947 +void r2057_get_chantabent_rev7(struct b43_wldev *dev, u16 freq,
3948 +                              const struct b43_nphy_chantabent_rev7 **tabent_r7,
3949 +                              const struct b43_nphy_chantabent_rev7_2g **tabent_r7_2g)
3950 +{
3951 +       struct b43_phy *phy = &dev->phy;
3952 +       const struct b43_nphy_chantabent_rev7 *e_r7 = NULL;
3953 +       const struct b43_nphy_chantabent_rev7_2g *e_r7_2g = NULL;
3954 +       unsigned int len, i;
3955 +
3956 +       *tabent_r7 = NULL;
3957 +       *tabent_r7_2g = NULL;
3958 +
3959 +       /* TODO */
3960 +       switch (phy->rev) {
3961 +       case 8:
3962 +               if (phy->radio_rev == 5) {
3963 +                       e_r7_2g = b43_nphy_chantab_phy_rev8_radio_rev5;
3964 +                       len = ARRAY_SIZE(b43_nphy_chantab_phy_rev8_radio_rev5);
3965 +               }
3966 +               break;
3967 +       case 16:
3968 +               if (phy->radio_rev == 9) {
3969 +                       e_r7 = b43_nphy_chantab_phy_rev16_radio_rev9;
3970 +                       len = ARRAY_SIZE(b43_nphy_chantab_phy_rev16_radio_rev9);
3971 +               }
3972 +               break;
3973 +       default:
3974 +               break;
3975 +       }
3976 +
3977 +       if (e_r7) {
3978 +               for (i = 0; i < len; i++, e_r7++) {
3979 +                       if (e_r7->freq == freq) {
3980 +                               *tabent_r7 = e_r7;
3981 +                               return;
3982 +                       }
3983 +               }
3984 +       } else if (e_r7_2g) {
3985 +               for (i = 0; i < len; i++, e_r7_2g++) {
3986 +                       if (e_r7_2g->freq == freq) {
3987 +                               *tabent_r7_2g = e_r7_2g;
3988 +                               return;
3989 +                       }
3990                 }
3991 +       } else {
3992 +               B43_WARN_ON(1);
3993         }
3994  }
3995 --- a/drivers/net/wireless/b43/radio_2057.h
3996 +++ b/drivers/net/wireless/b43/radio_2057.h
3997 @@ -84,6 +84,8 @@
3998  #define R2057_CMOSBUF_RX_RCCR                  0x04c
3999  #define R2057_LOGEN_SEL_PKDET                  0x04d
4000  #define R2057_CMOSBUF_SHAREIQ_PTAT             0x04e
4001 +
4002 +/* MISC core 0 */
4003  #define R2057_RXTXBIAS_CONFIG_CORE0            0x04f
4004  #define R2057_TXGM_TXRF_PUS_CORE0              0x050
4005  #define R2057_TXGM_IDAC_BLEED_CORE0            0x051
4006 @@ -204,6 +206,8 @@
4007  #define R2057_RXBB_GPAIOSEL_RXLPF_RCCAL_CORE0  0x0d1
4008  #define R2057_LPF_GAIN_CORE0                   0x0d2
4009  #define R2057_DACBUF_IDACS_BW_CORE0            0x0d3
4010 +
4011 +/* MISC core 1 */
4012  #define R2057_RXTXBIAS_CONFIG_CORE1            0x0d4
4013  #define R2057_TXGM_TXRF_PUS_CORE1              0x0d5
4014  #define R2057_TXGM_IDAC_BLEED_CORE1            0x0d6
4015 @@ -324,6 +328,7 @@
4016  #define R2057_RXBB_GPAIOSEL_RXLPF_RCCAL_CORE1  0x156
4017  #define R2057_LPF_GAIN_CORE1                   0x157
4018  #define R2057_DACBUF_IDACS_BW_CORE1            0x158
4019 +
4020  #define R2057_DACBUF_VINCM_CORE1               0x159
4021  #define R2057_RCCAL_START_R1_Q1_P1             0x15a
4022  #define R2057_RCCAL_X1                         0x15b
4023 @@ -345,6 +350,8 @@
4024  #define R2057_RCCAL_BCAP_VAL                   0x16b
4025  #define R2057_RCCAL_HPC_VAL                    0x16c
4026  #define R2057_RCCAL_OVERRIDES                  0x16d
4027 +
4028 +/* TX core 0 */
4029  #define R2057_TX0_IQCAL_GAIN_BW                        0x170
4030  #define R2057_TX0_LOFT_FINE_I                  0x171
4031  #define R2057_TX0_LOFT_FINE_Q                  0x172
4032 @@ -362,6 +369,8 @@
4033  #define R2057_TX0_TXRXCOUPLE_2G_PWRUP          0x17e
4034  #define R2057_TX0_TXRXCOUPLE_5G_ATTEN          0x17f
4035  #define R2057_TX0_TXRXCOUPLE_5G_PWRUP          0x180
4036 +
4037 +/* TX core 1 */
4038  #define R2057_TX1_IQCAL_GAIN_BW                        0x190
4039  #define R2057_TX1_LOFT_FINE_I                  0x191
4040  #define R2057_TX1_LOFT_FINE_Q                  0x192
4041 @@ -379,6 +388,7 @@
4042  #define R2057_TX1_TXRXCOUPLE_2G_PWRUP          0x19e
4043  #define R2057_TX1_TXRXCOUPLE_5G_ATTEN          0x19f
4044  #define R2057_TX1_TXRXCOUPLE_5G_PWRUP          0x1a0
4045 +
4046  #define R2057_AFE_VCM_CAL_MASTER_CORE0         0x1a1
4047  #define R2057_AFE_SET_VCM_I_CORE0              0x1a2
4048  #define R2057_AFE_SET_VCM_Q_CORE0              0x1a3
4049 @@ -425,6 +435,72 @@
4050  
4051  #define R2057_VCM_MASK                         0x7
4052  
4053 +struct b43_nphy_chantabent_rev7 {
4054 +       /* The channel frequency in MHz */
4055 +       u16 freq;
4056 +       /* Radio regs values on channelswitch */
4057 +       u8 radio_vcocal_countval0;
4058 +       u8 radio_vcocal_countval1;
4059 +       u8 radio_rfpll_refmaster_sparextalsize;
4060 +       u8 radio_rfpll_loopfilter_r1;
4061 +       u8 radio_rfpll_loopfilter_c2;
4062 +       u8 radio_rfpll_loopfilter_c1;
4063 +       u8 radio_cp_kpd_idac;
4064 +       u8 radio_rfpll_mmd0;
4065 +       u8 radio_rfpll_mmd1;
4066 +       u8 radio_vcobuf_tune;
4067 +       u8 radio_logen_mx2g_tune;
4068 +       u8 radio_logen_mx5g_tune;
4069 +       u8 radio_logen_indbuf2g_tune;
4070 +       u8 radio_logen_indbuf5g_tune;
4071 +       u8 radio_txmix2g_tune_boost_pu_core0;
4072 +       u8 radio_pad2g_tune_pus_core0;
4073 +       u8 radio_pga_boost_tune_core0;
4074 +       u8 radio_txmix5g_boost_tune_core0;
4075 +       u8 radio_pad5g_tune_misc_pus_core0;
4076 +       u8 radio_lna2g_tune_core0;
4077 +       u8 radio_lna5g_tune_core0;
4078 +       u8 radio_txmix2g_tune_boost_pu_core1;
4079 +       u8 radio_pad2g_tune_pus_core1;
4080 +       u8 radio_pga_boost_tune_core1;
4081 +       u8 radio_txmix5g_boost_tune_core1;
4082 +       u8 radio_pad5g_tune_misc_pus_core1;
4083 +       u8 radio_lna2g_tune_core1;
4084 +       u8 radio_lna5g_tune_core1;
4085 +       /* PHY res values on channelswitch */
4086 +       struct b43_phy_n_sfo_cfg phy_regs;
4087 +};
4088 +
4089 +struct b43_nphy_chantabent_rev7_2g {
4090 +       /* The channel frequency in MHz */
4091 +       u16 freq;
4092 +       /* Radio regs values on channelswitch */
4093 +       u8 radio_vcocal_countval0;
4094 +       u8 radio_vcocal_countval1;
4095 +       u8 radio_rfpll_refmaster_sparextalsize;
4096 +       u8 radio_rfpll_loopfilter_r1;
4097 +       u8 radio_rfpll_loopfilter_c2;
4098 +       u8 radio_rfpll_loopfilter_c1;
4099 +       u8 radio_cp_kpd_idac;
4100 +       u8 radio_rfpll_mmd0;
4101 +       u8 radio_rfpll_mmd1;
4102 +       u8 radio_vcobuf_tune;
4103 +       u8 radio_logen_mx2g_tune;
4104 +       u8 radio_logen_indbuf2g_tune;
4105 +       u8 radio_txmix2g_tune_boost_pu_core0;
4106 +       u8 radio_pad2g_tune_pus_core0;
4107 +       u8 radio_lna2g_tune_core0;
4108 +       u8 radio_txmix2g_tune_boost_pu_core1;
4109 +       u8 radio_pad2g_tune_pus_core1;
4110 +       u8 radio_lna2g_tune_core1;
4111 +       /* PHY regs values on channelswitch */
4112 +       struct b43_phy_n_sfo_cfg phy_regs;
4113 +};
4114 +
4115  void r2057_upload_inittabs(struct b43_wldev *dev);
4116  
4117 +void r2057_get_chantabent_rev7(struct b43_wldev *dev, u16 freq,
4118 +                              const struct b43_nphy_chantabent_rev7 **tabent_r7,
4119 +                              const struct b43_nphy_chantabent_rev7_2g **tabent_r7_2g);
4120 +
4121  #endif /* B43_RADIO_2057_H_ */
4122 --- a/drivers/net/wireless/b43/tables_nphy.h
4123 +++ b/drivers/net/wireless/b43/tables_nphy.h
4124 @@ -165,6 +165,10 @@ struct nphy_gain_ctl_workaround_entry *b
4125  #define B43_NTAB_C1_LOFEEDTH_R3                B43_NTAB16(27, 448) /* Local Oscillator Feed Through lookup 1 */
4126  #define B43_NTAB_C1_PAPD_COMP_R3       B43_NTAB16(27, 576)
4127  
4128 +/* Static N-PHY tables, PHY revision >= 7 */
4129 +#define B43_NTAB_TMAP_R7               B43_NTAB32(12,   0) /* TM AP */
4130 +#define B43_NTAB_NOISEVAR_R7           B43_NTAB32(16,   0) /* noise variance */
4131 +
4132  #define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_40_SIZE       18
4133  #define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_20_SIZE       18
4134  #define B43_NTAB_TX_IQLO_CAL_IQIMB_LADDER_40_SIZE      18