mac80211: b43: backport b43 patches from wireless testing
[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-10
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 @@ -2201,52 +2205,82 @@ err_format:
20         return -EPROTO;
21  }
22  
23 +/* http://bcm-v4.sipsolutions.net/802.11/Init/Firmware */
24  static int b43_try_request_fw(struct b43_request_fw_context *ctx)
25  {
26         struct b43_wldev *dev = ctx->dev;
27         struct b43_firmware *fw = &ctx->dev->fw;
28 +       struct b43_phy *phy = &dev->phy;
29         const u8 rev = ctx->dev->dev->core_rev;
30         const char *filename;
31 -       u32 tmshigh;
32         int err;
33  
34 -       /* Files for HT and LCN were found by trying one by one */
35 -
36         /* Get microcode */
37 -       if ((rev >= 5) && (rev <= 10)) {
38 -               filename = "ucode5";
39 -       } else if ((rev >= 11) && (rev <= 12)) {
40 -               filename = "ucode11";
41 -       } else if (rev == 13) {
42 -               filename = "ucode13";
43 -       } else if (rev == 14) {
44 -               filename = "ucode14";
45 -       } else if (rev == 15) {
46 +       filename = NULL;
47 +       switch (rev) {
48 +       case 42:
49 +               if (phy->type == B43_PHYTYPE_AC)
50 +                       filename = "ucode42";
51 +               break;
52 +       case 40:
53 +               if (phy->type == B43_PHYTYPE_AC)
54 +                       filename = "ucode40";
55 +               break;
56 +       case 33:
57 +               if (phy->type == B43_PHYTYPE_LCN40)
58 +                       filename = "ucode33_lcn40";
59 +               break;
60 +       case 30:
61 +               if (phy->type == B43_PHYTYPE_N)
62 +                       filename = "ucode30_mimo";
63 +               break;
64 +       case 29:
65 +               if (phy->type == B43_PHYTYPE_HT)
66 +                       filename = "ucode29_mimo";
67 +               break;
68 +       case 26:
69 +               if (phy->type == B43_PHYTYPE_HT)
70 +                       filename = "ucode26_mimo";
71 +               break;
72 +       case 28:
73 +       case 25:
74 +               if (phy->type == B43_PHYTYPE_N)
75 +                       filename = "ucode25_mimo";
76 +               else if (phy->type == B43_PHYTYPE_LCN)
77 +                       filename = "ucode25_lcn";
78 +               break;
79 +       case 24:
80 +               if (phy->type == B43_PHYTYPE_LCN)
81 +                       filename = "ucode24_lcn";
82 +               break;
83 +       case 23:
84 +               if (phy->type == B43_PHYTYPE_N)
85 +                       filename = "ucode16_mimo";
86 +               break;
87 +       case 16 ... 19:
88 +               if (phy->type == B43_PHYTYPE_N)
89 +                       filename = "ucode16_mimo";
90 +               else if (phy->type == B43_PHYTYPE_LP)
91 +                       filename = "ucode16_lp";
92 +               break;
93 +       case 15:
94                 filename = "ucode15";
95 -       } else {
96 -               switch (dev->phy.type) {
97 -               case B43_PHYTYPE_N:
98 -                       if (rev >= 16)
99 -                               filename = "ucode16_mimo";
100 -                       else
101 -                               goto err_no_ucode;
102 -                       break;
103 -               case B43_PHYTYPE_HT:
104 -                       if (rev == 29)
105 -                               filename = "ucode29_mimo";
106 -                       else
107 -                               goto err_no_ucode;
108 -                       break;
109 -               case B43_PHYTYPE_LCN:
110 -                       if (rev == 24)
111 -                               filename = "ucode24_mimo";
112 -                       else
113 -                               goto err_no_ucode;
114 -                       break;
115 -               default:
116 -                       goto err_no_ucode;
117 -               }
118 +               break;
119 +       case 14:
120 +               filename = "ucode14";
121 +               break;
122 +       case 13:
123 +               filename = "ucode13";
124 +               break;
125 +       case 11 ... 12:
126 +               filename = "ucode11";
127 +               break;
128 +       case 5 ... 10:
129 +               filename = "ucode5";
130 +               break;
131         }
132 +       if (!filename)
133 +               goto err_no_ucode;
134         err = b43_do_request_fw(ctx, filename, &fw->ucode, true);
135         if (err)
136                 goto err_load;
137 @@ -2268,117 +2302,121 @@ static int b43_try_request_fw(struct b43
138                 goto err_load;
139  
140         /* Get initvals */
141 +       filename = NULL;
142         switch (dev->phy.type) {
143 -       case B43_PHYTYPE_A:
144 -               if ((rev >= 5) && (rev <= 10)) {
145 -                       tmshigh = ssb_read32(dev->dev->sdev, SSB_TMSHIGH);
146 -                       if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY)
147 -                               filename = "a0g1initvals5";
148 -                       else
149 -                               filename = "a0g0initvals5";
150 -               } else
151 -                       goto err_no_initvals;
152 -               break;
153         case B43_PHYTYPE_G:
154 -               if ((rev >= 5) && (rev <= 10))
155 -                       filename = "b0g0initvals5";
156 -               else if (rev >= 13)
157 +               if (rev == 13)
158                         filename = "b0g0initvals13";
159 -               else
160 -                       goto err_no_initvals;
161 +               else if (rev >= 5 && rev <= 10)
162 +                       filename = "b0g0initvals5";
163                 break;
164         case B43_PHYTYPE_N:
165 -               if (rev >= 16)
166 +               if (rev == 30)
167 +                       filename = "n16initvals30";
168 +               else if (rev == 28 || rev == 25)
169 +                       filename = "n0initvals25";
170 +               else if (rev == 24)
171 +                       filename = "n0initvals24";
172 +               else if (rev == 23)
173 +                       filename = "n0initvals16"; /* What about n0initvals22? */
174 +               else if (rev >= 16 && rev <= 18)
175                         filename = "n0initvals16";
176 -               else if ((rev >= 11) && (rev <= 12))
177 +               else if (rev >= 11 && rev <= 12)
178                         filename = "n0initvals11";
179 -               else
180 -                       goto err_no_initvals;
181                 break;
182         case B43_PHYTYPE_LP:
183 -               if (rev == 13)
184 -                       filename = "lp0initvals13";
185 +               if (rev >= 16 && rev <= 18)
186 +                       filename = "lp0initvals16";
187 +               else if (rev == 15)
188 +                       filename = "lp0initvals15";
189                 else if (rev == 14)
190                         filename = "lp0initvals14";
191 -               else if (rev >= 15)
192 -                       filename = "lp0initvals15";
193 -               else
194 -                       goto err_no_initvals;
195 +               else if (rev == 13)
196 +                       filename = "lp0initvals13";
197                 break;
198         case B43_PHYTYPE_HT:
199                 if (rev == 29)
200                         filename = "ht0initvals29";
201 -               else
202 -                       goto err_no_initvals;
203 +               else if (rev == 26)
204 +                       filename = "ht0initvals26";
205                 break;
206         case B43_PHYTYPE_LCN:
207                 if (rev == 24)
208                         filename = "lcn0initvals24";
209 -               else
210 -                       goto err_no_initvals;
211                 break;
212 -       default:
213 -               goto err_no_initvals;
214 +       case B43_PHYTYPE_LCN40:
215 +               if (rev == 33)
216 +                       filename = "lcn400initvals33";
217 +               break;
218 +       case B43_PHYTYPE_AC:
219 +               if (rev == 42)
220 +                       filename = "ac1initvals42";
221 +               else if (rev == 40)
222 +                       filename = "ac0initvals40";
223 +               break;
224         }
225 +       if (!filename)
226 +               goto err_no_initvals;
227         err = b43_do_request_fw(ctx, filename, &fw->initvals, false);
228         if (err)
229                 goto err_load;
230  
231         /* Get bandswitch initvals */
232 +       filename = NULL;
233         switch (dev->phy.type) {
234 -       case B43_PHYTYPE_A:
235 -               if ((rev >= 5) && (rev <= 10)) {
236 -                       tmshigh = ssb_read32(dev->dev->sdev, SSB_TMSHIGH);
237 -                       if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY)
238 -                               filename = "a0g1bsinitvals5";
239 -                       else
240 -                               filename = "a0g0bsinitvals5";
241 -               } else if (rev >= 11)
242 -                       filename = NULL;
243 -               else
244 -                       goto err_no_initvals;
245 -               break;
246         case B43_PHYTYPE_G:
247 -               if ((rev >= 5) && (rev <= 10))
248 +               if (rev == 13)
249 +                       filename = "b0g0bsinitvals13";
250 +               else if (rev >= 5 && rev <= 10)
251                         filename = "b0g0bsinitvals5";
252 -               else if (rev >= 11)
253 -                       filename = NULL;
254 -               else
255 -                       goto err_no_initvals;
256                 break;
257         case B43_PHYTYPE_N:
258 -               if (rev >= 16)
259 +               if (rev == 30)
260 +                       filename = "n16bsinitvals30";
261 +               else if (rev == 28 || rev == 25)
262 +                       filename = "n0bsinitvals25";
263 +               else if (rev == 24)
264 +                       filename = "n0bsinitvals24";
265 +               else if (rev == 23)
266 +                       filename = "n0bsinitvals16"; /* What about n0bsinitvals22? */
267 +               else if (rev >= 16 && rev <= 18)
268                         filename = "n0bsinitvals16";
269 -               else if ((rev >= 11) && (rev <= 12))
270 +               else if (rev >= 11 && rev <= 12)
271                         filename = "n0bsinitvals11";
272 -               else
273 -                       goto err_no_initvals;
274                 break;
275         case B43_PHYTYPE_LP:
276 -               if (rev == 13)
277 -                       filename = "lp0bsinitvals13";
278 +               if (rev >= 16 && rev <= 18)
279 +                       filename = "lp0bsinitvals16";
280 +               else if (rev == 15)
281 +                       filename = "lp0bsinitvals15";
282                 else if (rev == 14)
283                         filename = "lp0bsinitvals14";
284 -               else if (rev >= 15)
285 -                       filename = "lp0bsinitvals15";
286 -               else
287 -                       goto err_no_initvals;
288 +               else if (rev == 13)
289 +                       filename = "lp0bsinitvals13";
290                 break;
291         case B43_PHYTYPE_HT:
292                 if (rev == 29)
293                         filename = "ht0bsinitvals29";
294 -               else
295 -                       goto err_no_initvals;
296 +               else if (rev == 26)
297 +                       filename = "ht0bsinitvals26";
298                 break;
299         case B43_PHYTYPE_LCN:
300                 if (rev == 24)
301                         filename = "lcn0bsinitvals24";
302 -               else
303 -                       goto err_no_initvals;
304                 break;
305 -       default:
306 -               goto err_no_initvals;
307 +       case B43_PHYTYPE_LCN40:
308 +               if (rev == 33)
309 +                       filename = "lcn400bsinitvals33";
310 +               break;
311 +       case B43_PHYTYPE_AC:
312 +               if (rev == 42)
313 +                       filename = "ac1bsinitvals42";
314 +               else if (rev == 40)
315 +                       filename = "ac0bsinitvals40";
316 +               break;
317         }
318 +       if (!filename)
319 +               goto err_no_initvals;
320         err = b43_do_request_fw(ctx, filename, &fw->initvals_band, false);
321         if (err)
322                 goto err_load;
323 @@ -3742,7 +3780,9 @@ static int b43_switch_band(struct b43_wl
324         b43dbg(dev->wl, "Switching to %s GHz band\n",
325                band_to_string(chan->band));
326  
327 -       b43_software_rfkill(dev, true);
328 +       /* Some new devices don't need disabling radio for band switching */
329 +       if (!(phy->type == B43_PHYTYPE_N && phy->rev >= 3))
330 +               b43_software_rfkill(dev, true);
331  
332         phy->gmode = gmode;
333         b43_phy_put_into_reset(dev);
334 @@ -3796,38 +3836,29 @@ static void b43_set_retry_limits(struct
335  static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
336  {
337         struct b43_wl *wl = hw_to_b43_wl(hw);
338 -       struct b43_wldev *dev;
339 -       struct b43_phy *phy;
340 +       struct b43_wldev *dev = wl->current_dev;
341 +       struct b43_phy *phy = &dev->phy;
342         struct ieee80211_conf *conf = &hw->conf;
343         int antenna;
344         int err = 0;
345 -       bool reload_bss = false;
346  
347         mutex_lock(&wl->mutex);
348 -
349 -       dev = wl->current_dev;
350 -
351         b43_mac_suspend(dev);
352  
353 -       /* Switch the band (if necessary). This might change the active core. */
354 -       err = b43_switch_band(dev, conf->chandef.chan);
355 -       if (err)
356 -               goto out_unlock_mutex;
357 +       if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
358 +               phy->chandef = &conf->chandef;
359 +               phy->channel = conf->chandef.chan->hw_value;
360  
361 -       /* Need to reload all settings if the core changed */
362 -       if (dev != wl->current_dev) {
363 -               dev = wl->current_dev;
364 -               changed = ~0;
365 -               reload_bss = true;
366 -       }
367 +               /* Switch the band (if necessary). */
368 +               err = b43_switch_band(dev, conf->chandef.chan);
369 +               if (err)
370 +                       goto out_mac_enable;
371  
372 -       phy = &dev->phy;
373 -
374 -       if (conf_is_ht(conf))
375 -               phy->is_40mhz =
376 -                       (conf_is_ht40_minus(conf) || conf_is_ht40_plus(conf));
377 -       else
378 -               phy->is_40mhz = false;
379 +               /* Switch to the requested channel.
380 +                * The firmware takes care of races with the TX handler.
381 +                */
382 +               b43_switch_channel(dev, phy->channel);
383 +       }
384  
385         if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
386                 b43_set_retry_limits(dev, conf->short_frame_max_tx_count,
387 @@ -3836,11 +3867,6 @@ static int b43_op_config(struct ieee8021
388         if (!changed)
389                 goto out_mac_enable;
390  
391 -       /* Switch to the requested channel.
392 -        * The firmware takes care of races with the TX handler. */
393 -       if (conf->chandef.chan->hw_value != phy->channel)
394 -               b43_switch_channel(dev, conf->chandef.chan->hw_value);
395 -
396         dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_MONITOR);
397  
398         /* Adjust the desired TX power level. */
399 @@ -3876,12 +3902,8 @@ static int b43_op_config(struct ieee8021
400  
401  out_mac_enable:
402         b43_mac_enable(dev);
403 -out_unlock_mutex:
404         mutex_unlock(&wl->mutex);
405  
406 -       if (wl->vif && reload_bss)
407 -               b43_op_bss_info_changed(hw, wl->vif, &wl->vif->bss_conf, ~0);
408 -
409         return err;
410  }
411  
412 @@ -4307,6 +4329,7 @@ static char *b43_phy_name(struct b43_wld
413  static int b43_phy_versioning(struct b43_wldev *dev)
414  {
415         struct b43_phy *phy = &dev->phy;
416 +       const u8 core_rev = dev->dev->core_rev;
417         u32 tmp;
418         u8 analog_type;
419         u8 phy_type;
420 @@ -4321,20 +4344,20 @@ static int b43_phy_versioning(struct b43
421         analog_type = (tmp & B43_PHYVER_ANALOG) >> B43_PHYVER_ANALOG_SHIFT;
422         phy_type = (tmp & B43_PHYVER_TYPE) >> B43_PHYVER_TYPE_SHIFT;
423         phy_rev = (tmp & B43_PHYVER_VERSION);
424 +
425 +       /* LCNXN is continuation of N which run out of revisions */
426 +       if (phy_type == B43_PHYTYPE_LCNXN) {
427 +               phy_type = B43_PHYTYPE_N;
428 +               phy_rev += 16;
429 +       }
430 +
431         switch (phy_type) {
432 -       case B43_PHYTYPE_A:
433 -               if (phy_rev >= 4)
434 -                       unsupported = 1;
435 -               break;
436 -       case B43_PHYTYPE_B:
437 -               if (phy_rev != 2 && phy_rev != 4 && phy_rev != 6
438 -                   && phy_rev != 7)
439 -                       unsupported = 1;
440 -               break;
441 +#ifdef CPTCFG_B43_PHY_G
442         case B43_PHYTYPE_G:
443                 if (phy_rev > 9)
444                         unsupported = 1;
445                 break;
446 +#endif
447  #ifdef CPTCFG_B43_PHY_N
448         case B43_PHYTYPE_N:
449                 if (phy_rev > 9)
450 @@ -4372,7 +4395,15 @@ static int b43_phy_versioning(struct b43
451                 analog_type, phy_type, b43_phy_name(dev, phy_type), phy_rev);
452  
453         /* Get RADIO versioning */
454 -       if (dev->dev->core_rev >= 24) {
455 +       if (core_rev == 40 || core_rev == 42) {
456 +               radio_manuf = 0x17F;
457 +
458 +               b43_write16(dev, B43_MMIO_RADIO24_CONTROL, 0);
459 +               radio_rev = b43_read16(dev, B43_MMIO_RADIO24_DATA);
460 +
461 +               b43_write16(dev, B43_MMIO_RADIO24_CONTROL, 1);
462 +               radio_ver = b43_read16(dev, B43_MMIO_RADIO24_DATA);
463 +       } else if (core_rev >= 24) {
464                 u16 radio24[3];
465  
466                 for (tmp = 0; tmp < 3; tmp++) {
467 @@ -5164,6 +5195,7 @@ static void b43_supported_bands(struct b
468  static int b43_wireless_core_attach(struct b43_wldev *dev)
469  {
470         struct b43_wl *wl = dev->wl;
471 +       struct b43_phy *phy = &dev->phy;
472         int err;
473         u32 tmp;
474         bool have_2ghz_phy = false, have_5ghz_phy = false;
475 @@ -5181,6 +5213,8 @@ static int b43_wireless_core_attach(stru
476                 goto out;
477         }
478  
479 +       phy->do_full_init = true;
480 +
481         /* Try to guess supported bands for the first init needs */
482         switch (dev->dev->bus_type) {
483  #ifdef CPTCFG_B43_BCMA
484 --- a/drivers/net/wireless/b43/phy_common.c
485 +++ b/drivers/net/wireless/b43/phy_common.c
486 @@ -45,11 +45,10 @@ int b43_phy_allocate(struct b43_wldev *d
487         phy->ops = NULL;
488  
489         switch (phy->type) {
490 -       case B43_PHYTYPE_A:
491 -               phy->ops = &b43_phyops_a;
492 -               break;
493         case B43_PHYTYPE_G:
494 +#ifdef CPTCFG_B43_PHY_G
495                 phy->ops = &b43_phyops_g;
496 +#endif
497                 break;
498         case B43_PHYTYPE_N:
499  #ifdef CPTCFG_B43_PHY_N
500 @@ -94,18 +93,25 @@ int b43_phy_init(struct b43_wldev *dev)
501         const struct b43_phy_operations *ops = phy->ops;
502         int err;
503  
504 -       phy->channel = ops->get_default_chan(dev);
505 +       /* During PHY init we need to use some channel. On the first init this
506 +        * function is called *before* b43_op_config, so our pointer is NULL.
507 +        */
508 +       if (!phy->chandef) {
509 +               phy->chandef = &dev->wl->hw->conf.chandef;
510 +               phy->channel = phy->chandef->chan->hw_value;
511 +       }
512  
513         phy->ops->switch_analog(dev, true);
514         b43_software_rfkill(dev, false);
515 +
516         err = ops->init(dev);
517         if (err) {
518                 b43err(dev->wl, "PHY init failed\n");
519                 goto err_block_rf;
520         }
521 -       /* Make sure to switch hardware and firmware (SHM) to
522 -        * the default channel. */
523 -       err = b43_switch_channel(dev, ops->get_default_chan(dev));
524 +       phy->do_full_init = false;
525 +
526 +       err = b43_switch_channel(dev, phy->channel);
527         if (err) {
528                 b43err(dev->wl, "PHY init: Channel switch to default failed\n");
529                 goto err_phy_exit;
530 @@ -114,6 +120,7 @@ int b43_phy_init(struct b43_wldev *dev)
531         return 0;
532  
533  err_phy_exit:
534 +       phy->do_full_init = true;
535         if (ops->exit)
536                 ops->exit(dev);
537  err_block_rf:
538 @@ -127,6 +134,7 @@ void b43_phy_exit(struct b43_wldev *dev)
539         const struct b43_phy_operations *ops = dev->phy.ops;
540  
541         b43_software_rfkill(dev, true);
542 +       dev->phy.do_full_init = true;
543         if (ops->exit)
544                 ops->exit(dev);
545  }
546 @@ -403,9 +411,6 @@ int b43_switch_channel(struct b43_wldev
547         u16 channelcookie, savedcookie;
548         int err;
549  
550 -       if (new_channel == B43_DEFAULT_CHANNEL)
551 -               new_channel = phy->ops->get_default_chan(dev);
552 -
553         /* First we set the channel radio code to prevent the
554          * firmware from sending ghost packets.
555          */
556 @@ -423,7 +428,6 @@ int b43_switch_channel(struct b43_wldev
557         if (err)
558                 goto err_restore_cookie;
559  
560 -       dev->phy.channel = new_channel;
561         /* Wait for the radio to tune to the channel and stabilize. */
562         msleep(8);
563  
564 @@ -542,10 +546,9 @@ void b43_phyop_switch_analog_generic(str
565  }
566  
567  
568 -bool b43_channel_type_is_40mhz(enum nl80211_channel_type channel_type)
569 +bool b43_is_40mhz(struct b43_wldev *dev)
570  {
571 -       return (channel_type == NL80211_CHAN_HT40MINUS ||
572 -               channel_type == NL80211_CHAN_HT40PLUS);
573 +       return dev->phy.chandef->width == NL80211_CHAN_WIDTH_40;
574  }
575  
576  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/BmacPhyClkFgc */
577 --- a/drivers/net/wireless/b43/phy_common.h
578 +++ b/drivers/net/wireless/b43/phy_common.h
579 @@ -228,12 +228,12 @@ struct b43_phy {
580         bool supports_2ghz;
581         bool supports_5ghz;
582  
583 -       /* HT info */
584 -       bool is_40mhz;
585 -
586         /* Is GMODE (2 GHz mode) bit enabled? */
587         bool gmode;
588  
589 +       /* After power reset full init has to be performed */
590 +       bool do_full_init;
591 +
592         /* Analog Type */
593         u8 analog;
594         /* B43_PHYTYPE_ */
595 @@ -264,9 +264,8 @@ struct b43_phy {
596         unsigned long next_txpwr_check_time;
597  
598         /* Current channel */
599 +       struct cfg80211_chan_def *chandef;
600         unsigned int channel;
601 -       u16 channel_freq;
602 -       enum nl80211_channel_type channel_type;
603  
604         /* PHY TX errors counter. */
605         atomic_t txerr_cnt;
606 @@ -397,10 +396,6 @@ void b43_phy_take_out_of_reset(struct b4
607   * b43_switch_channel - Switch to another channel
608   */
609  int b43_switch_channel(struct b43_wldev *dev, unsigned int new_channel);
610 -/**
611 - * B43_DEFAULT_CHANNEL - Switch to the default channel.
612 - */
613 -#define B43_DEFAULT_CHANNEL    UINT_MAX
614  
615  /**
616   * b43_software_rfkill - Turn the radio ON or OFF in software.
617 @@ -451,7 +446,7 @@ int b43_phy_shm_tssi_read(struct b43_wld
618   */
619  void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on);
620  
621 -bool b43_channel_type_is_40mhz(enum nl80211_channel_type channel_type);
622 +bool b43_is_40mhz(struct b43_wldev *dev);
623  
624  void b43_phy_force_clock(struct b43_wldev *dev, bool force);
625  
626 --- a/drivers/net/wireless/b43/phy_n.c
627 +++ b/drivers/net/wireless/b43/phy_n.c
628 @@ -590,7 +590,103 @@ static void b43_nphy_set_rf_sequence(str
629   * Radio 0x2057
630   **************************************************/
631  
632 -/* http://bcm-v4.sipsolutions.net/PHY/radio2057_rcal */
633 +static void b43_radio_2057_chantab_upload(struct b43_wldev *dev,
634 +                                         const struct b43_nphy_chantabent_rev7 *e_r7,
635 +                                         const struct b43_nphy_chantabent_rev7_2g *e_r7_2g)
636 +{
637 +       if (e_r7_2g) {
638 +               b43_radio_write(dev, R2057_VCOCAL_COUNTVAL0, e_r7_2g->radio_vcocal_countval0);
639 +               b43_radio_write(dev, R2057_VCOCAL_COUNTVAL1, e_r7_2g->radio_vcocal_countval1);
640 +               b43_radio_write(dev, R2057_RFPLL_REFMASTER_SPAREXTALSIZE, e_r7_2g->radio_rfpll_refmaster_sparextalsize);
641 +               b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_R1, e_r7_2g->radio_rfpll_loopfilter_r1);
642 +               b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C2, e_r7_2g->radio_rfpll_loopfilter_c2);
643 +               b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C1, e_r7_2g->radio_rfpll_loopfilter_c1);
644 +               b43_radio_write(dev, R2057_CP_KPD_IDAC, e_r7_2g->radio_cp_kpd_idac);
645 +               b43_radio_write(dev, R2057_RFPLL_MMD0, e_r7_2g->radio_rfpll_mmd0);
646 +               b43_radio_write(dev, R2057_RFPLL_MMD1, e_r7_2g->radio_rfpll_mmd1);
647 +               b43_radio_write(dev, R2057_VCOBUF_TUNE, e_r7_2g->radio_vcobuf_tune);
648 +               b43_radio_write(dev, R2057_LOGEN_MX2G_TUNE, e_r7_2g->radio_logen_mx2g_tune);
649 +               b43_radio_write(dev, R2057_LOGEN_INDBUF2G_TUNE, e_r7_2g->radio_logen_indbuf2g_tune);
650 +               b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE0, e_r7_2g->radio_txmix2g_tune_boost_pu_core0);
651 +               b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE0, e_r7_2g->radio_pad2g_tune_pus_core0);
652 +               b43_radio_write(dev, R2057_LNA2G_TUNE_CORE0, e_r7_2g->radio_lna2g_tune_core0);
653 +               b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE1, e_r7_2g->radio_txmix2g_tune_boost_pu_core1);
654 +               b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE1, e_r7_2g->radio_pad2g_tune_pus_core1);
655 +               b43_radio_write(dev, R2057_LNA2G_TUNE_CORE1, e_r7_2g->radio_lna2g_tune_core1);
656 +
657 +       } else {
658 +               b43_radio_write(dev, R2057_VCOCAL_COUNTVAL0, e_r7->radio_vcocal_countval0);
659 +               b43_radio_write(dev, R2057_VCOCAL_COUNTVAL1, e_r7->radio_vcocal_countval1);
660 +               b43_radio_write(dev, R2057_RFPLL_REFMASTER_SPAREXTALSIZE, e_r7->radio_rfpll_refmaster_sparextalsize);
661 +               b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_R1, e_r7->radio_rfpll_loopfilter_r1);
662 +               b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C2, e_r7->radio_rfpll_loopfilter_c2);
663 +               b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C1, e_r7->radio_rfpll_loopfilter_c1);
664 +               b43_radio_write(dev, R2057_CP_KPD_IDAC, e_r7->radio_cp_kpd_idac);
665 +               b43_radio_write(dev, R2057_RFPLL_MMD0, e_r7->radio_rfpll_mmd0);
666 +               b43_radio_write(dev, R2057_RFPLL_MMD1, e_r7->radio_rfpll_mmd1);
667 +               b43_radio_write(dev, R2057_VCOBUF_TUNE, e_r7->radio_vcobuf_tune);
668 +               b43_radio_write(dev, R2057_LOGEN_MX2G_TUNE, e_r7->radio_logen_mx2g_tune);
669 +               b43_radio_write(dev, R2057_LOGEN_MX5G_TUNE, e_r7->radio_logen_mx5g_tune);
670 +               b43_radio_write(dev, R2057_LOGEN_INDBUF2G_TUNE, e_r7->radio_logen_indbuf2g_tune);
671 +               b43_radio_write(dev, R2057_LOGEN_INDBUF5G_TUNE, e_r7->radio_logen_indbuf5g_tune);
672 +               b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE0, e_r7->radio_txmix2g_tune_boost_pu_core0);
673 +               b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE0, e_r7->radio_pad2g_tune_pus_core0);
674 +               b43_radio_write(dev, R2057_PGA_BOOST_TUNE_CORE0, e_r7->radio_pga_boost_tune_core0);
675 +               b43_radio_write(dev, R2057_TXMIX5G_BOOST_TUNE_CORE0, e_r7->radio_txmix5g_boost_tune_core0);
676 +               b43_radio_write(dev, R2057_PAD5G_TUNE_MISC_PUS_CORE0, e_r7->radio_pad5g_tune_misc_pus_core0);
677 +               b43_radio_write(dev, R2057_LNA2G_TUNE_CORE0, e_r7->radio_lna2g_tune_core0);
678 +               b43_radio_write(dev, R2057_LNA5G_TUNE_CORE0, e_r7->radio_lna5g_tune_core0);
679 +               b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE1, e_r7->radio_txmix2g_tune_boost_pu_core1);
680 +               b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE1, e_r7->radio_pad2g_tune_pus_core1);
681 +               b43_radio_write(dev, R2057_PGA_BOOST_TUNE_CORE1, e_r7->radio_pga_boost_tune_core1);
682 +               b43_radio_write(dev, R2057_TXMIX5G_BOOST_TUNE_CORE1, e_r7->radio_txmix5g_boost_tune_core1);
683 +               b43_radio_write(dev, R2057_PAD5G_TUNE_MISC_PUS_CORE1, e_r7->radio_pad5g_tune_misc_pus_core1);
684 +               b43_radio_write(dev, R2057_LNA2G_TUNE_CORE1, e_r7->radio_lna2g_tune_core1);
685 +               b43_radio_write(dev, R2057_LNA5G_TUNE_CORE1, e_r7->radio_lna5g_tune_core1);
686 +       }
687 +}
688 +
689 +static void b43_radio_2057_setup(struct b43_wldev *dev,
690 +                                const struct b43_nphy_chantabent_rev7 *tabent_r7,
691 +                                const struct b43_nphy_chantabent_rev7_2g *tabent_r7_2g)
692 +{
693 +       struct b43_phy *phy = &dev->phy;
694 +
695 +       b43_radio_2057_chantab_upload(dev, tabent_r7, tabent_r7_2g);
696 +
697 +       switch (phy->radio_rev) {
698 +       case 0 ... 4:
699 +       case 6:
700 +               if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
701 +                       b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_R1, 0x3f);
702 +                       b43_radio_write(dev, R2057_CP_KPD_IDAC, 0x3f);
703 +                       b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C1, 0x8);
704 +                       b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C2, 0x8);
705 +               } else {
706 +                       b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_R1, 0x1f);
707 +                       b43_radio_write(dev, R2057_CP_KPD_IDAC, 0x3f);
708 +                       b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C1, 0x8);
709 +                       b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C2, 0x8);
710 +               }
711 +               break;
712 +       /* TODO */
713 +       }
714 +
715 +       /* TODO */
716 +
717 +       usleep_range(50, 100);
718 +
719 +       /* VCO calibration */
720 +       b43_radio_mask(dev, R2057_RFPLL_MISC_EN, ~0x01);
721 +       b43_radio_mask(dev, R2057_RFPLL_MISC_CAL_RESETN, ~0x04);
722 +       b43_radio_set(dev, R2057_RFPLL_MISC_CAL_RESETN, 0x4);
723 +       b43_radio_set(dev, R2057_RFPLL_MISC_EN, 0x01);
724 +       usleep_range(300, 600);
725 +}
726 +
727 +/* Calibrate resistors in LPF of PLL?
728 + * http://bcm-v4.sipsolutions.net/PHY/radio205x_rcal
729 + */
730  static u8 b43_radio_2057_rcal(struct b43_wldev *dev)
731  {
732         struct b43_phy *phy = &dev->phy;
733 @@ -603,15 +699,25 @@ static u8 b43_radio_2057_rcal(struct b43
734                 b43_radio_maskset(dev, 0x1ca, ~0x2, 0x1);
735         }
736  
737 +       /* Enable */
738         b43_radio_set(dev, R2057_RCAL_CONFIG, 0x1);
739         udelay(10);
740 -       b43_radio_set(dev, R2057_RCAL_CONFIG, 0x3);
741 -       if (!b43_radio_wait_value(dev, R2057_RCCAL_N1_1, 1, 1, 100, 1000000)) {
742 +
743 +       /* Start */
744 +       b43_radio_set(dev, R2057_RCAL_CONFIG, 0x2);
745 +       usleep_range(100, 200);
746 +
747 +       /* Stop */
748 +       b43_radio_mask(dev, R2057_RCAL_CONFIG, ~0x2);
749 +
750 +       /* Wait and check for result */
751 +       if (!b43_radio_wait_value(dev, R2057_RCAL_STATUS, 1, 1, 100, 1000000)) {
752                 b43err(dev->wl, "Radio 0x2057 rcal timeout\n");
753                 return 0;
754         }
755 -       b43_radio_mask(dev, R2057_RCAL_CONFIG, ~0x2);
756         tmp = b43_radio_read(dev, R2057_RCAL_STATUS) & 0x3E;
757 +
758 +       /* Disable */
759         b43_radio_mask(dev, R2057_RCAL_CONFIG, ~0x1);
760  
761         if (phy->radio_rev == 5) {
762 @@ -627,7 +733,9 @@ static u8 b43_radio_2057_rcal(struct b43
763         return tmp & 0x3e;
764  }
765  
766 -/* http://bcm-v4.sipsolutions.net/PHY/radio2057_rccal */
767 +/* Calibrate the internal RC oscillator?
768 + * http://bcm-v4.sipsolutions.net/PHY/radio2057_rccal
769 + */
770  static u16 b43_radio_2057_rccal(struct b43_wldev *dev)
771  {
772         struct b43_phy *phy = &dev->phy;
773 @@ -635,49 +743,76 @@ static u16 b43_radio_2057_rccal(struct b
774                         phy->radio_rev == 6);
775         u16 tmp;
776  
777 +       /* Setup cal */
778         if (special) {
779                 b43_radio_write(dev, R2057_RCCAL_MASTER, 0x61);
780                 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xC0);
781         } else {
782 -               b43_radio_write(dev, 0x1AE, 0x61);
783 +               b43_radio_write(dev, R2057v7_RCCAL_MASTER, 0x61);
784                 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xE1);
785         }
786         b43_radio_write(dev, R2057_RCCAL_X1, 0x6E);
787 +
788 +       /* Start, wait, stop */
789         b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x55);
790 -       if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 1, 1, 500,
791 +       if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 2, 2, 500,
792                                   5000000))
793                 b43dbg(dev->wl, "Radio 0x2057 rccal timeout\n");
794 +       usleep_range(35, 70);
795         b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x15);
796 +       usleep_range(70, 140);
797 +
798 +       /* Setup cal */
799         if (special) {
800                 b43_radio_write(dev, R2057_RCCAL_MASTER, 0x69);
801                 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xB0);
802         } else {
803 -               b43_radio_write(dev, 0x1AE, 0x69);
804 +               b43_radio_write(dev, R2057v7_RCCAL_MASTER, 0x69);
805                 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xD5);
806         }
807         b43_radio_write(dev, R2057_RCCAL_X1, 0x6E);
808 +
809 +       /* Start, wait, stop */
810 +       usleep_range(35, 70);
811         b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x55);
812 -       if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 1, 1, 500,
813 +       usleep_range(70, 140);
814 +       if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 2, 2, 500,
815                                   5000000))
816                 b43dbg(dev->wl, "Radio 0x2057 rccal timeout\n");
817 +       usleep_range(35, 70);
818         b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x15);
819 +       usleep_range(70, 140);
820 +
821 +       /* Setup cal */
822         if (special) {
823                 b43_radio_write(dev, R2057_RCCAL_MASTER, 0x73);
824                 b43_radio_write(dev, R2057_RCCAL_X1, 0x28);
825                 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xB0);
826         } else {
827 -               b43_radio_write(dev, 0x1AE, 0x73);
828 +               b43_radio_write(dev, R2057v7_RCCAL_MASTER, 0x73);
829                 b43_radio_write(dev, R2057_RCCAL_X1, 0x6E);
830                 b43_radio_write(dev, R2057_RCCAL_TRC0, 0x99);
831         }
832 +
833 +       /* Start, wait, stop */
834 +       usleep_range(35, 70);
835         b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x55);
836 -       if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 1, 1, 500,
837 +       usleep_range(70, 140);
838 +       if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 2, 2, 500,
839                                   5000000)) {
840                 b43err(dev->wl, "Radio 0x2057 rcal timeout\n");
841                 return 0;
842         }
843         tmp = b43_radio_read(dev, R2057_RCCAL_DONE_OSCCAP);
844 +       usleep_range(35, 70);
845         b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x15);
846 +       usleep_range(70, 140);
847 +
848 +       if (special)
849 +               b43_radio_mask(dev, R2057_RCCAL_MASTER, ~0x1);
850 +       else
851 +               b43_radio_mask(dev, R2057v7_RCCAL_MASTER, ~0x1);
852 +
853         return tmp;
854  }
855  
856 @@ -700,13 +835,11 @@ static void b43_radio_2057_init_post(str
857         b43_radio_mask(dev, R2057_RFPLL_MISC_CAL_RESETN, ~0x78);
858         b43_radio_mask(dev, R2057_XTAL_CONFIG2, ~0x80);
859  
860 -       if (dev->phy.n->init_por) {
861 +       if (dev->phy.do_full_init) {
862                 b43_radio_2057_rcal(dev);
863                 b43_radio_2057_rccal(dev);
864         }
865         b43_radio_mask(dev, R2057_RFPLL_MASTER, ~0x8);
866 -
867 -       dev->phy.n->init_por = false;
868  }
869  
870  /* http://bcm-v4.sipsolutions.net/802.11/Radio/2057/Init */
871 @@ -800,6 +933,7 @@ static void b43_chantab_radio_2056_uploa
872  static void b43_radio_2056_setup(struct b43_wldev *dev,
873                                 const struct b43_nphy_channeltab_entry_rev3 *e)
874  {
875 +       struct b43_phy *phy = &dev->phy;
876         struct ssb_sprom *sprom = dev->dev->bus_sprom;
877         enum ieee80211_band band = b43_current_band(dev->wl);
878         u16 offset;
879 @@ -897,7 +1031,7 @@ static void b43_radio_2056_setup(struct
880                                         offset | B2056_TX_MIXG_BOOST_TUNE,
881                                         mixg_boost);
882                         } else {
883 -                               bias = dev->phy.is_40mhz ? 0x40 : 0x20;
884 +                               bias = b43_is_40mhz(dev) ? 0x40 : 0x20;
885                                 b43_radio_write(dev,
886                                         offset | B2056_TX_INTPAG_IMAIN_STAT,
887                                         bias);
888 @@ -911,7 +1045,7 @@ static void b43_radio_2056_setup(struct
889                         b43_radio_write(dev, offset | B2056_TX_PA_SPARE1, 0xee);
890                 }
891         } else if (dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ) {
892 -               u16 freq = dev->phy.channel_freq;
893 +               u16 freq = phy->chandef->chan->center_freq;
894                 if (freq < 5100) {
895                         paa_boost = 0xA;
896                         pada_boost = 0x77;
897 @@ -1028,7 +1162,7 @@ static void b43_radio_init2056_post(stru
898         b43_radio_mask(dev, B2056_SYN_COM_RESET, ~0x2);
899         b43_radio_mask(dev, B2056_SYN_PLL_MAST2, ~0xFC);
900         b43_radio_mask(dev, B2056_SYN_RCCAL_CTRL0, ~0x1);
901 -       if (dev->phy.n->init_por)
902 +       if (dev->phy.do_full_init)
903                 b43_radio_2056_rcal(dev);
904  }
905  
906 @@ -1041,8 +1175,6 @@ static void b43_radio_init2056(struct b4
907         b43_radio_init2056_pre(dev);
908         b2056_upload_inittabs(dev, 0, 0);
909         b43_radio_init2056_post(dev);
910 -
911 -       dev->phy.n->init_por = false;
912  }
913  
914  /**************************************************
915 @@ -1214,8 +1346,7 @@ static u16 b43_nphy_gen_load_samples(str
916         u16 bw, len, rot, angle;
917         struct b43_c32 *samples;
918  
919 -
920 -       bw = (dev->phy.is_40mhz) ? 40 : 20;
921 +       bw = b43_is_40mhz(dev) ? 40 : 20;
922         len = bw << 3;
923  
924         if (test) {
925 @@ -1224,7 +1355,7 @@ static u16 b43_nphy_gen_load_samples(str
926                 else
927                         bw = 80;
928  
929 -               if (dev->phy.is_40mhz)
930 +               if (b43_is_40mhz(dev))
931                         bw <<= 1;
932  
933                 len = bw << 1;
934 @@ -1252,7 +1383,8 @@ static u16 b43_nphy_gen_load_samples(str
935  
936  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RunSamples */
937  static void b43_nphy_run_samples(struct b43_wldev *dev, u16 samps, u16 loops,
938 -                                       u16 wait, bool iqmode, bool dac_test)
939 +                                u16 wait, bool iqmode, bool dac_test,
940 +                                bool modify_bbmult)
941  {
942         struct b43_phy_n *nphy = dev->phy.n;
943         int i;
944 @@ -1266,12 +1398,10 @@ static void b43_nphy_run_samples(struct
945                 nphy->bb_mult_save = (tmp & 0xFFFF) | 0x80000000;
946         }
947  
948 -       /* TODO: add modify_bbmult argument */
949 -       if (!dev->phy.is_40mhz)
950 -               tmp = 0x6464;
951 -       else
952 -               tmp = 0x4747;
953 -       b43_ntab_write(dev, B43_NTAB16(15, 87), tmp);
954 +       if (modify_bbmult) {
955 +               tmp = !b43_is_40mhz(dev) ? 0x6464 : 0x4747;
956 +               b43_ntab_write(dev, B43_NTAB16(15, 87), tmp);
957 +       }
958  
959         b43_phy_write(dev, B43_NPHY_SAMP_DEPCNT, (samps - 1));
960  
961 @@ -1289,10 +1419,8 @@ static void b43_nphy_run_samples(struct
962                 b43_phy_mask(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x7FFF);
963                 b43_phy_set(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8000);
964         } else {
965 -               if (dac_test)
966 -                       b43_phy_write(dev, B43_NPHY_SAMP_CMD, 5);
967 -               else
968 -                       b43_phy_write(dev, B43_NPHY_SAMP_CMD, 1);
969 +               tmp = dac_test ? 5 : 1;
970 +               b43_phy_write(dev, B43_NPHY_SAMP_CMD, tmp);
971         }
972         for (i = 0; i < 100; i++) {
973                 if (!(b43_phy_read(dev, B43_NPHY_RFSEQST) & 1)) {
974 @@ -1679,6 +1807,7 @@ static int b43_nphy_poll_rssi(struct b43
975  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */
976  static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
977  {
978 +       struct b43_phy *phy = &dev->phy;
979         struct b43_phy_n *nphy = dev->phy.n;
980  
981         u16 saved_regs_phy_rfctl[2];
982 @@ -1901,9 +2030,9 @@ static void b43_nphy_rev3_rssi_cal(struc
983  
984         /* Remember for which channel we store configuration */
985         if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
986 -               nphy->rssical_chanspec_2G.center_freq = dev->phy.channel_freq;
987 +               nphy->rssical_chanspec_2G.center_freq = phy->chandef->chan->center_freq;
988         else
989 -               nphy->rssical_chanspec_5G.center_freq = dev->phy.channel_freq;
990 +               nphy->rssical_chanspec_5G.center_freq = phy->chandef->chan->center_freq;
991  
992         /* End of calibration, restore configuration */
993         b43_nphy_classifier(dev, 7, class);
994 @@ -2196,7 +2325,7 @@ static void b43_nphy_gain_ctl_workaround
995         b43_phy_write(dev, B43_NPHY_C1_NBCLIPTHRES, 0x84);
996         b43_phy_write(dev, B43_NPHY_C2_NBCLIPTHRES, 0x84);
997  
998 -       if (!dev->phy.is_40mhz) {
999 +       if (!b43_is_40mhz(dev)) {
1000                 /* Set dwell lengths */
1001                 b43_phy_write(dev, B43_NPHY_CLIP1_NBDWELL_LEN, 0x002B);
1002                 b43_phy_write(dev, B43_NPHY_CLIP2_NBDWELL_LEN, 0x002B);
1003 @@ -2210,7 +2339,7 @@ static void b43_nphy_gain_ctl_workaround
1004         b43_phy_maskset(dev, B43_NPHY_C2_CLIPWBTHRES,
1005                         ~B43_NPHY_C2_CLIPWBTHRES_CLIP2, 21);
1006  
1007 -       if (!dev->phy.is_40mhz) {
1008 +       if (!b43_is_40mhz(dev)) {
1009                 b43_phy_maskset(dev, B43_NPHY_C1_CGAINI,
1010                         ~B43_NPHY_C1_CGAINI_GAINBKOFF, 0x1);
1011                 b43_phy_maskset(dev, B43_NPHY_C2_CGAINI,
1012 @@ -2225,12 +2354,12 @@ static void b43_nphy_gain_ctl_workaround
1013  
1014         if (nphy->gain_boost) {
1015                 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ &&
1016 -                       dev->phy.is_40mhz)
1017 +                   b43_is_40mhz(dev))
1018                         code = 4;
1019                 else
1020                         code = 5;
1021         } else {
1022 -               code = dev->phy.is_40mhz ? 6 : 7;
1023 +               code = b43_is_40mhz(dev) ? 6 : 7;
1024         }
1025  
1026         /* Set HPVGA2 index */
1027 @@ -2302,7 +2431,7 @@ static void b43_nphy_gain_ctl_workaround
1028  static u16 b43_nphy_read_lpf_ctl(struct b43_wldev *dev, u16 offset)
1029  {
1030         if (!offset)
1031 -               offset = (dev->phy.is_40mhz) ? 0x159 : 0x154;
1032 +               offset = b43_is_40mhz(dev) ? 0x159 : 0x154;
1033         return b43_ntab_read(dev, B43_NTAB16(7, offset)) & 0x7;
1034  }
1035  
1036 @@ -2375,13 +2504,13 @@ static void b43_nphy_workarounds_rev7plu
1037         lpf_40 = b43_nphy_read_lpf_ctl(dev, 0x159);
1038         lpf_11b = b43_nphy_read_lpf_ctl(dev, 0x152);
1039         if (b43_nphy_ipa(dev)) {
1040 -               if ((phy->radio_rev == 5 && phy->is_40mhz) ||
1041 +               if ((phy->radio_rev == 5 && b43_is_40mhz(dev)) ||
1042                     phy->radio_rev == 7 || phy->radio_rev == 8) {
1043                         bcap_val = b43_radio_read(dev, 0x16b);
1044                         scap_val = b43_radio_read(dev, 0x16a);
1045                         scap_val_11b = scap_val;
1046                         bcap_val_11b = bcap_val;
1047 -                       if (phy->radio_rev == 5 && phy->is_40mhz) {
1048 +                       if (phy->radio_rev == 5 && b43_is_40mhz(dev)) {
1049                                 scap_val_11n_20 = scap_val;
1050                                 bcap_val_11n_20 = bcap_val;
1051                                 scap_val_11n_40 = bcap_val_11n_40 = 0xc;
1052 @@ -2523,7 +2652,7 @@ static void b43_nphy_workarounds_rev7plu
1053                                         }
1054                                 }
1055                         } else if (phy->radio_rev == 7 || phy->radio_rev == 8) {
1056 -                               if (!phy->is_40mhz) {
1057 +                               if (!b43_is_40mhz(dev)) {
1058                                         b43_radio_write(dev, 0x5F, 0x14);
1059                                         b43_radio_write(dev, 0xE8, 0x12);
1060                                 } else {
1061 @@ -2532,7 +2661,7 @@ static void b43_nphy_workarounds_rev7plu
1062                                 }
1063                         }
1064                 } else {
1065 -                       u16 freq = phy->channel_freq;
1066 +                       u16 freq = phy->chandef->chan->center_freq;
1067                         if ((freq >= 5180 && freq <= 5230) ||
1068                             (freq >= 5745 && freq <= 5805)) {
1069                                 b43_radio_write(dev, 0x7D, 0xFF);
1070 @@ -2596,7 +2725,7 @@ static void b43_nphy_workarounds_rev7plu
1071         b43_ntab_write(dev, B43_NTAB16(7, 0x123), 0x77);
1072         b43_ntab_write(dev, B43_NTAB16(7, 0x12A), 0x77);
1073  
1074 -       if (!phy->is_40mhz) {
1075 +       if (!b43_is_40mhz(dev)) {
1076                 b43_ntab_write(dev, B43_NTAB32(16, 0x03), 0x18D);
1077                 b43_ntab_write(dev, B43_NTAB32(16, 0x7F), 0x18D);
1078         } else {
1079 @@ -2695,7 +2824,7 @@ static void b43_nphy_workarounds_rev3plu
1080  
1081         b43_phy_maskset(dev, B43_NPHY_SGILTRNOFFSET, 0xF0FF, 0x0700);
1082  
1083 -       if (!dev->phy.is_40mhz) {
1084 +       if (!b43_is_40mhz(dev)) {
1085                 b43_ntab_write(dev, B43_NTAB32(16, 3), 0x18D);
1086                 b43_ntab_write(dev, B43_NTAB32(16, 127), 0x18D);
1087         } else {
1088 @@ -2950,12 +3079,13 @@ static void b43_nphy_workarounds(struct
1089   * http://bcm-v4.sipsolutions.net/802.11/PHY/N/TXTone
1090   */
1091  static int b43_nphy_tx_tone(struct b43_wldev *dev, u32 freq, u16 max_val,
1092 -                               bool iqmode, bool dac_test)
1093 +                           bool iqmode, bool dac_test, bool modify_bbmult)
1094  {
1095         u16 samp = b43_nphy_gen_load_samples(dev, freq, max_val, dac_test);
1096         if (samp == 0)
1097                 return -1;
1098 -       b43_nphy_run_samples(dev, samp, 0xFFFF, 0, iqmode, dac_test);
1099 +       b43_nphy_run_samples(dev, samp, 0xFFFF, 0, iqmode, dac_test,
1100 +                            modify_bbmult);
1101         return 0;
1102  }
1103  
1104 @@ -3118,7 +3248,7 @@ static void b43_nphy_tx_power_ctrl(struc
1105                         b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3,
1106                                 ~B43_NPHY_BPHY_CTL3_SCALE, 0x5A);
1107  
1108 -               if (dev->phy.rev < 2 && dev->phy.is_40mhz)
1109 +               if (dev->phy.rev < 2 && b43_is_40mhz(dev))
1110                         b43_hf_write(dev, b43_hf_read(dev) | B43_HF_TSSIRPSMW);
1111         } else {
1112                 b43_ntab_write_bulk(dev, B43_NTAB16(26, 64), 84,
1113 @@ -3172,7 +3302,7 @@ static void b43_nphy_tx_power_ctrl(struc
1114                 else if (dev->phy.rev < 2)
1115                         b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3, ~0xFF, 0x40);
1116  
1117 -               if (dev->phy.rev < 2 && dev->phy.is_40mhz)
1118 +               if (dev->phy.rev < 2 && b43_is_40mhz(dev))
1119                         b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_TSSIRPSMW);
1120  
1121                 if (b43_nphy_ipa(dev)) {
1122 @@ -3188,12 +3318,13 @@ static void b43_nphy_tx_power_ctrl(struc
1123  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrFix */
1124  static void b43_nphy_tx_power_fix(struct b43_wldev *dev)
1125  {
1126 +       struct b43_phy *phy = &dev->phy;
1127         struct b43_phy_n *nphy = dev->phy.n;
1128         struct ssb_sprom *sprom = dev->dev->bus_sprom;
1129  
1130         u8 txpi[2], bbmult, i;
1131         u16 tmp, radio_gain, dac_gain;
1132 -       u16 freq = dev->phy.channel_freq;
1133 +       u16 freq = phy->chandef->chan->center_freq;
1134         u32 txgain;
1135         /* u32 gaintbl; rev3+ */
1136  
1137 @@ -3238,7 +3369,11 @@ static void b43_nphy_tx_power_fix(struct
1138         */
1139  
1140         for (i = 0; i < 2; i++) {
1141 -               txgain = *(b43_nphy_get_tx_gain_table(dev) + txpi[i]);
1142 +               const u32 *table = b43_nphy_get_tx_gain_table(dev);
1143 +
1144 +               if (!table)
1145 +                       break;
1146 +               txgain = *(table + txpi[i]);
1147  
1148                 if (dev->phy.rev >= 3)
1149                         radio_gain = (txgain >> 16) & 0x1FFFF;
1150 @@ -3392,7 +3527,7 @@ static void b43_nphy_tx_power_ctl_idle_t
1151                 b43_nphy_rf_ctl_override(dev, 0x2000, 0, 3, false);
1152  
1153         b43_nphy_stop_playback(dev);
1154 -       b43_nphy_tx_tone(dev, 0xFA0, 0, false, false);
1155 +       b43_nphy_tx_tone(dev, 4000, 0, false, false, false);
1156         udelay(20);
1157         tmp = b43_nphy_poll_rssi(dev, N_RSSI_TSSI_2G, rssi, 1);
1158         b43_nphy_stop_playback(dev);
1159 @@ -3443,21 +3578,21 @@ static void b43_nphy_tx_prepare_adjusted
1160                 delta = 0;
1161                 switch (stf_mode) {
1162                 case 0:
1163 -                       if (dev->phy.is_40mhz && dev->phy.rev >= 5) {
1164 +                       if (b43_is_40mhz(dev) && dev->phy.rev >= 5) {
1165                                 idx = 68;
1166                         } else {
1167                                 delta = 1;
1168 -                               idx = dev->phy.is_40mhz ? 52 : 4;
1169 +                               idx = b43_is_40mhz(dev) ? 52 : 4;
1170                         }
1171                         break;
1172                 case 1:
1173 -                       idx = dev->phy.is_40mhz ? 76 : 28;
1174 +                       idx = b43_is_40mhz(dev) ? 76 : 28;
1175                         break;
1176                 case 2:
1177 -                       idx = dev->phy.is_40mhz ? 84 : 36;
1178 +                       idx = b43_is_40mhz(dev) ? 84 : 36;
1179                         break;
1180                 case 3:
1181 -                       idx = dev->phy.is_40mhz ? 92 : 44;
1182 +                       idx = b43_is_40mhz(dev) ? 92 : 44;
1183                         break;
1184                 }
1185  
1186 @@ -3478,6 +3613,7 @@ static void b43_nphy_tx_prepare_adjusted
1187  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlSetup */
1188  static void b43_nphy_tx_power_ctl_setup(struct b43_wldev *dev)
1189  {
1190 +       struct b43_phy *phy = &dev->phy;
1191         struct b43_phy_n *nphy = dev->phy.n;
1192         struct ssb_sprom *sprom = dev->dev->bus_sprom;
1193  
1194 @@ -3487,7 +3623,7 @@ static void b43_nphy_tx_power_ctl_setup(
1195         s32 num, den, pwr;
1196         u32 regval[64];
1197  
1198 -       u16 freq = dev->phy.channel_freq;
1199 +       u16 freq = phy->chandef->chan->center_freq;
1200         u16 tmp;
1201         u16 r; /* routing */
1202         u8 i, c;
1203 @@ -3651,6 +3787,9 @@ static void b43_nphy_tx_gain_table_uploa
1204         int i;
1205  
1206         table = b43_nphy_get_tx_gain_table(dev);
1207 +       if (!table)
1208 +               return;
1209 +
1210         b43_ntab_write_bulk(dev, B43_NTAB32(26, 192), 128, table);
1211         b43_ntab_write_bulk(dev, B43_NTAB32(27, 192), 128, table);
1212  
1213 @@ -3709,21 +3848,28 @@ static void b43_nphy_pa_override(struct
1214         }
1215  }
1216  
1217 -/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxLpFbw */
1218 -static void b43_nphy_tx_lp_fbw(struct b43_wldev *dev)
1219 +/*
1220 + * TX low-pass filter bandwidth setup
1221 + * http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxLpFbw
1222 + */
1223 +static void b43_nphy_tx_lpf_bw(struct b43_wldev *dev)
1224  {
1225         u16 tmp;
1226  
1227 -       if (dev->phy.rev >= 3) {
1228 -               if (b43_nphy_ipa(dev)) {
1229 -                       tmp = 4;
1230 -                       b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S2,
1231 -                             (((((tmp << 3) | tmp) << 3) | tmp) << 3) | tmp);
1232 -               }
1233 +       if (dev->phy.rev < 3 || dev->phy.rev >= 7)
1234 +               return;
1235  
1236 -               tmp = 1;
1237 +       if (b43_nphy_ipa(dev))
1238 +               tmp = b43_is_40mhz(dev) ? 5 : 4;
1239 +       else
1240 +               tmp = b43_is_40mhz(dev) ? 3 : 1;
1241 +       b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S2,
1242 +                     (tmp << 9) | (tmp << 6) | (tmp << 3) | tmp);
1243 +
1244 +       if (b43_nphy_ipa(dev)) {
1245 +               tmp = b43_is_40mhz(dev) ? 4 : 1;
1246                 b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S2,
1247 -                             (((((tmp << 3) | tmp) << 3) | tmp) << 3) | tmp);
1248 +                             (tmp << 9) | (tmp << 6) | (tmp << 3) | tmp);
1249         }
1250  }
1251  
1252 @@ -3996,7 +4142,7 @@ static void b43_nphy_spur_workaround(str
1253  
1254         if (nphy->gband_spurwar_en) {
1255                 /* TODO: N PHY Adjust Analog Pfbw (7) */
1256 -               if (channel == 11 && dev->phy.is_40mhz)
1257 +               if (channel == 11 && b43_is_40mhz(dev))
1258                         ; /* TODO: N PHY Adjust Min Noise Var(2, tone, noise)*/
1259                 else
1260                         ; /* TODO: N PHY Adjust Min Noise Var(0, NULL, NULL)*/
1261 @@ -4290,7 +4436,7 @@ static void b43_nphy_int_pa_set_tx_dig_f
1262                         b43_phy_write(dev, B43_PHY_N(offset[i] + j),
1263                                         tbl_tx_filter_coef_rev4[i][j]);
1264  
1265 -       if (dev->phy.is_40mhz) {
1266 +       if (b43_is_40mhz(dev)) {
1267                 for (j = 0; j < 15; j++)
1268                         b43_phy_write(dev, B43_PHY_N(offset[0] + j),
1269                                         tbl_tx_filter_coef_rev4[3][j]);
1270 @@ -4349,6 +4495,9 @@ static struct nphy_txgains b43_nphy_get_
1271  
1272                 for (i = 0; i < 2; ++i) {
1273                         table = b43_nphy_get_tx_gain_table(dev);
1274 +                       if (!table)
1275 +                               break;
1276 +
1277                         if (dev->phy.rev >= 3) {
1278                                 target.ipa[i] = (table[index[i]] >> 16) & 0xF;
1279                                 target.pad[i] = (table[index[i]] >> 20) & 0xF;
1280 @@ -4504,8 +4653,9 @@ static void b43_nphy_save_cal(struct b43
1281                 txcal_radio_regs[2] = b43_radio_read(dev, 0x8D);
1282                 txcal_radio_regs[3] = b43_radio_read(dev, 0xBC);
1283         }
1284 -       iqcal_chanspec->center_freq = dev->phy.channel_freq;
1285 -       iqcal_chanspec->channel_type = dev->phy.channel_type;
1286 +       iqcal_chanspec->center_freq = dev->phy.chandef->chan->center_freq;
1287 +       iqcal_chanspec->channel_type =
1288 +                               cfg80211_get_chandef_type(dev->phy.chandef);
1289         b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 8, table);
1290  
1291         if (nphy->hang_avoid)
1292 @@ -4585,6 +4735,7 @@ static int b43_nphy_cal_tx_iq_lo(struct
1293                                 struct nphy_txgains target,
1294                                 bool full, bool mphase)
1295  {
1296 +       struct b43_phy *phy = &dev->phy;
1297         struct b43_phy_n *nphy = dev->phy.n;
1298         int i;
1299         int error = 0;
1300 @@ -4625,7 +4776,7 @@ static int b43_nphy_cal_tx_iq_lo(struct
1301                 (dev->phy.rev == 5 && nphy->ipa2g_on &&
1302                 b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ);
1303         if (phy6or5x) {
1304 -               if (dev->phy.is_40mhz) {
1305 +               if (b43_is_40mhz(dev)) {
1306                         b43_ntab_write_bulk(dev, B43_NTAB16(15, 0), 18,
1307                                         tbl_tx_iqlo_cal_loft_ladder_40);
1308                         b43_ntab_write_bulk(dev, B43_NTAB16(15, 32), 18,
1309 @@ -4640,16 +4791,16 @@ static int b43_nphy_cal_tx_iq_lo(struct
1310  
1311         b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8AA9);
1312  
1313 -       if (!dev->phy.is_40mhz)
1314 +       if (!b43_is_40mhz(dev))
1315                 freq = 2500;
1316         else
1317                 freq = 5000;
1318  
1319         if (nphy->mphase_cal_phase_id > 2)
1320 -               b43_nphy_run_samples(dev, (dev->phy.is_40mhz ? 40 : 20) * 8,
1321 -                                       0xFFFF, 0, true, false);
1322 +               b43_nphy_run_samples(dev, (b43_is_40mhz(dev) ? 40 : 20) * 8,
1323 +                                    0xFFFF, 0, true, false, false);
1324         else
1325 -               error = b43_nphy_tx_tone(dev, freq, 250, true, false);
1326 +               error = b43_nphy_tx_tone(dev, freq, 250, true, false, false);
1327  
1328         if (error == 0) {
1329                 if (nphy->mphase_cal_phase_id > 2) {
1330 @@ -4777,9 +4928,9 @@ static int b43_nphy_cal_tx_iq_lo(struct
1331                                                 nphy->txiqlocal_bestc);
1332                         nphy->txiqlocal_coeffsvalid = true;
1333                         nphy->txiqlocal_chanspec.center_freq =
1334 -                                                       dev->phy.channel_freq;
1335 +                                               phy->chandef->chan->center_freq;
1336                         nphy->txiqlocal_chanspec.channel_type =
1337 -                                                       dev->phy.channel_type;
1338 +                                       cfg80211_get_chandef_type(phy->chandef);
1339                 } else {
1340                         length = 11;
1341                         if (dev->phy.rev < 3)
1342 @@ -4815,8 +4966,8 @@ static void b43_nphy_reapply_tx_cal_coef
1343         bool equal = true;
1344  
1345         if (!nphy->txiqlocal_coeffsvalid ||
1346 -           nphy->txiqlocal_chanspec.center_freq != dev->phy.channel_freq ||
1347 -           nphy->txiqlocal_chanspec.channel_type != dev->phy.channel_type)
1348 +           nphy->txiqlocal_chanspec.center_freq != dev->phy.chandef->chan->center_freq ||
1349 +           nphy->txiqlocal_chanspec.channel_type != cfg80211_get_chandef_type(dev->phy.chandef))
1350                 return;
1351  
1352         b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer);
1353 @@ -4972,11 +5123,11 @@ static int b43_nphy_rev2_cal_rx_iq(struc
1354                         if (playtone) {
1355                                 ret = b43_nphy_tx_tone(dev, 4000,
1356                                                 (nphy->rxcalparams & 0xFFFF),
1357 -                                               false, false);
1358 +                                               false, false, true);
1359                                 playtone = false;
1360                         } else {
1361 -                               b43_nphy_run_samples(dev, 160, 0xFFFF, 0,
1362 -                                                       false, false);
1363 +                               b43_nphy_run_samples(dev, 160, 0xFFFF, 0, false,
1364 +                                                    false, true);
1365                         }
1366  
1367                         if (ret == 0) {
1368 @@ -5348,7 +5499,7 @@ static int b43_phy_initn(struct b43_wlde
1369         b43_phy_write(dev, B43_NPHY_TXMACDELAY, 0x0320);
1370         if (phy->rev >= 3 && phy->rev <= 6)
1371                 b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x0032);
1372 -       b43_nphy_tx_lp_fbw(dev);
1373 +       b43_nphy_tx_lpf_bw(dev);
1374         if (phy->rev >= 3)
1375                 b43_nphy_spur_workaround(dev);
1376  
1377 @@ -5434,14 +5585,14 @@ static void b43_nphy_channel_setup(struc
1378         if (dev->phy.rev < 3)
1379                 b43_nphy_adjust_lna_gain_table(dev);
1380  
1381 -       b43_nphy_tx_lp_fbw(dev);
1382 +       b43_nphy_tx_lpf_bw(dev);
1383  
1384         if (dev->phy.rev >= 3 &&
1385             dev->phy.n->spur_avoid != B43_SPUR_AVOID_DISABLE) {
1386                 bool avoid = false;
1387                 if (dev->phy.n->spur_avoid == B43_SPUR_AVOID_FORCE) {
1388                         avoid = true;
1389 -               } else if (!b43_channel_type_is_40mhz(phy->channel_type)) {
1390 +               } else if (!b43_is_40mhz(dev)) {
1391                         if ((ch >= 5 && ch <= 8) || ch == 13 || ch == 14)
1392                                 avoid = true;
1393                 } else { /* 40MHz */
1394 @@ -5488,10 +5639,17 @@ static int b43_nphy_set_channel(struct b
1395  
1396         const struct b43_nphy_channeltab_entry_rev2 *tabent_r2 = NULL;
1397         const struct b43_nphy_channeltab_entry_rev3 *tabent_r3 = NULL;
1398 +       const struct b43_nphy_chantabent_rev7 *tabent_r7 = NULL;
1399 +       const struct b43_nphy_chantabent_rev7_2g *tabent_r7_2g = NULL;
1400  
1401         u8 tmp;
1402  
1403 -       if (dev->phy.rev >= 3) {
1404 +       if (phy->rev >= 7) {
1405 +               r2057_get_chantabent_rev7(dev, channel->center_freq,
1406 +                                         &tabent_r7, &tabent_r7_2g);
1407 +               if (!tabent_r7 && !tabent_r7_2g)
1408 +                       return -ESRCH;
1409 +       } else if (phy->rev >= 3) {
1410                 tabent_r3 = b43_nphy_get_chantabent_rev3(dev,
1411                                                         channel->center_freq);
1412                 if (!tabent_r3)
1413 @@ -5506,20 +5664,36 @@ static int b43_nphy_set_channel(struct b
1414         /* Channel is set later in common code, but we need to set it on our
1415            own to let this function's subcalls work properly. */
1416         phy->channel = channel->hw_value;
1417 -       phy->channel_freq = channel->center_freq;
1418  
1419 +#if 0
1420         if (b43_channel_type_is_40mhz(phy->channel_type) !=
1421                 b43_channel_type_is_40mhz(channel_type))
1422                 ; /* TODO: BMAC BW Set (channel_type) */
1423 +#endif
1424  
1425 -       if (channel_type == NL80211_CHAN_HT40PLUS)
1426 -               b43_phy_set(dev, B43_NPHY_RXCTL,
1427 -                               B43_NPHY_RXCTL_BSELU20);
1428 -       else if (channel_type == NL80211_CHAN_HT40MINUS)
1429 -               b43_phy_mask(dev, B43_NPHY_RXCTL,
1430 -                               ~B43_NPHY_RXCTL_BSELU20);
1431 +       if (channel_type == NL80211_CHAN_HT40PLUS) {
1432 +               b43_phy_set(dev, B43_NPHY_RXCTL, B43_NPHY_RXCTL_BSELU20);
1433 +               if (phy->rev >= 7)
1434 +                       b43_phy_set(dev, 0x310, 0x8000);
1435 +       } else if (channel_type == NL80211_CHAN_HT40MINUS) {
1436 +               b43_phy_mask(dev, B43_NPHY_RXCTL, ~B43_NPHY_RXCTL_BSELU20);
1437 +               if (phy->rev >= 7)
1438 +                       b43_phy_mask(dev, 0x310, (u16)~0x8000);
1439 +       }
1440  
1441 -       if (dev->phy.rev >= 3) {
1442 +       if (phy->rev >= 7) {
1443 +               const struct b43_phy_n_sfo_cfg *phy_regs = tabent_r7 ?
1444 +                       &(tabent_r7->phy_regs) : &(tabent_r7_2g->phy_regs);
1445 +
1446 +               if (phy->radio_rev <= 4 || phy->radio_rev == 6) {
1447 +                       tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 2 : 0;
1448 +                       b43_radio_maskset(dev, R2057_TIA_CONFIG_CORE0, ~2, tmp);
1449 +                       b43_radio_maskset(dev, R2057_TIA_CONFIG_CORE1, ~2, tmp);
1450 +               }
1451 +
1452 +               b43_radio_2057_setup(dev, tabent_r7, tabent_r7_2g);
1453 +               b43_nphy_channel_setup(dev, phy_regs, channel);
1454 +       } else if (phy->rev >= 3) {
1455                 tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 4 : 0;
1456                 b43_radio_maskset(dev, 0x08, 0xFFFB, tmp);
1457                 b43_radio_2056_setup(dev, tabent_r3);
1458 @@ -5561,7 +5735,6 @@ static void b43_nphy_op_prepare_structs(
1459         nphy->hang_avoid = (phy->rev == 3 || phy->rev == 4);
1460         nphy->spur_avoid = (phy->rev >= 3) ?
1461                                 B43_SPUR_AVOID_AUTO : B43_SPUR_AVOID_DISABLE;
1462 -       nphy->init_por = true;
1463         nphy->gain_boost = true; /* this way we follow wl, assume it is true */
1464         nphy->txrx_chain = 2; /* sth different than 0 and 1 for now */
1465         nphy->phyrxchain = 3; /* to avoid b43_nphy_set_rx_core_state like wl */
1466 @@ -5602,8 +5775,6 @@ static void b43_nphy_op_prepare_structs(
1467                 nphy->ipa2g_on = sprom->fem.ghz2.extpa_gain == 2;
1468                 nphy->ipa5g_on = sprom->fem.ghz5.extpa_gain == 2;
1469         }
1470 -
1471 -       nphy->init_por = true;
1472  }
1473  
1474  static void b43_nphy_op_free(struct b43_wldev *dev)
1475 @@ -5714,10 +5885,12 @@ static void b43_nphy_op_software_rfkill(
1476                 }
1477         } else {
1478                 if (dev->phy.rev >= 7) {
1479 -                       b43_radio_2057_init(dev);
1480 +                       if (!dev->phy.radio_on)
1481 +                               b43_radio_2057_init(dev);
1482                         b43_switch_channel(dev, dev->phy.channel);
1483                 } else if (dev->phy.rev >= 3) {
1484 -                       b43_radio_init2056(dev);
1485 +                       if (!dev->phy.radio_on)
1486 +                               b43_radio_init2056(dev);
1487                         b43_switch_channel(dev, dev->phy.channel);
1488                 } else {
1489                         b43_radio_init2055(dev);
1490 --- a/drivers/net/wireless/b43/phy_n.h
1491 +++ b/drivers/net/wireless/b43/phy_n.h
1492 @@ -931,7 +931,6 @@ struct b43_phy_n {
1493         u16 papd_epsilon_offset[2];
1494         s32 preamble_override;
1495         u32 bb_mult_save;
1496 -       bool init_por;
1497  
1498         bool gain_boost;
1499         bool elna_gain_config;
1500 --- a/drivers/net/wireless/b43/tables_nphy.c
1501 +++ b/drivers/net/wireless/b43/tables_nphy.c
1502 @@ -2146,7 +2146,196 @@ static const u16 b43_ntab_antswctl_r3[4]
1503         }
1504  };
1505  
1506 -/* TX gain tables */
1507 +/* static tables, PHY revision >= 7 */
1508 +
1509 +/* Copied from brcmsmac (5.75.11) */
1510 +static const u32 b43_ntab_tmap_r7[] = {
1511 +       0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
1512 +       0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
1513 +       0xf1111110, 0x11111111, 0x11f11111, 0x00000111,
1514 +       0x11000000, 0x1111f111, 0x11111111, 0x111111f1,
1515 +       0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x000aa888,
1516 +       0x88880000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
1517 +       0xa1111110, 0x11111111, 0x11c11111, 0x00000111,
1518 +       0x11000000, 0x1111a111, 0x11111111, 0x111111a1,
1519 +       0xa2222220, 0x22222222, 0x22c22222, 0x00000222,
1520 +       0x22000000, 0x2222a222, 0x22222222, 0x222222a2,
1521 +       0xf1111110, 0x11111111, 0x11f11111, 0x00011111,
1522 +       0x11110000, 0x1111f111, 0x11111111, 0x111111f1,
1523 +       0xa8aa88a0, 0xa88888a8, 0xa8a8a88a, 0x00088aaa,
1524 +       0xaaaa0000, 0xa8a8aa88, 0xa88aaaaa, 0xaaaa8a8a,
1525 +       0xaaa8aaa0, 0x8aaa8aaa, 0xaa8a8a8a, 0x000aaa88,
1526 +       0x8aaa0000, 0xaaa8a888, 0x8aa88a8a, 0x8a88a888,
1527 +       0x08080a00, 0x0a08080a, 0x080a0a08, 0x00080808,
1528 +       0x080a0000, 0x080a0808, 0x080a0808, 0x0a0a0a08,
1529 +       0xa0a0a0a0, 0x80a0a080, 0x8080a0a0, 0x00008080,
1530 +       0x80a00000, 0x80a080a0, 0xa080a0a0, 0x8080a0a0,
1531 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
1532 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
1533 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
1534 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
1535 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
1536 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
1537 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
1538 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
1539 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
1540 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
1541 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
1542 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
1543 +       0x99999000, 0x9b9b99bb, 0x9bb99999, 0x9999b9b9,
1544 +       0x9b99bb90, 0x9bbbbb9b, 0x9b9b9bb9, 0x00000999,
1545 +       0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
1546 +       0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00aaa888,
1547 +       0x22000000, 0x2222b222, 0x22222222, 0x222222b2,
1548 +       0xb2222220, 0x22222222, 0x22d22222, 0x00000222,
1549 +       0x11000000, 0x1111a111, 0x11111111, 0x111111a1,
1550 +       0xa1111110, 0x11111111, 0x11c11111, 0x00000111,
1551 +       0x33000000, 0x3333b333, 0x33333333, 0x333333b3,
1552 +       0xb3333330, 0x33333333, 0x33d33333, 0x00000333,
1553 +       0x22000000, 0x2222a222, 0x22222222, 0x222222a2,
1554 +       0xa2222220, 0x22222222, 0x22c22222, 0x00000222,
1555 +       0x99b99b00, 0x9b9b99bb, 0x9bb99999, 0x9999b9b9,
1556 +       0x9b99bb99, 0x9bbbbb9b, 0x9b9b9bb9, 0x00000999,
1557 +       0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
1558 +       0x8a88aa88, 0x8aaaaa8a, 0x8a8a8aa8, 0x08aaa888,
1559 +       0x22222200, 0x2222f222, 0x22222222, 0x222222f2,
1560 +       0x22222222, 0x22222222, 0x22f22222, 0x00000222,
1561 +       0x11000000, 0x1111f111, 0x11111111, 0x11111111,
1562 +       0xf1111111, 0x11111111, 0x11f11111, 0x01111111,
1563 +       0xbb9bb900, 0xb9b9bb99, 0xb99bbbbb, 0xbbbb9b9b,
1564 +       0xb9bb99bb, 0xb99999b9, 0xb9b9b99b, 0x00000bbb,
1565 +       0xaa000000, 0xa8a8aa88, 0xa88aaaaa, 0xaaaa8a8a,
1566 +       0xa8aa88aa, 0xa88888a8, 0xa8a8a88a, 0x0a888aaa,
1567 +       0xaa000000, 0xa8a8aa88, 0xa88aaaaa, 0xaaaa8a8a,
1568 +       0xa8aa88a0, 0xa88888a8, 0xa8a8a88a, 0x00000aaa,
1569 +       0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
1570 +       0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
1571 +       0xbbbbbb00, 0x999bbbbb, 0x9bb99b9b, 0xb9b9b9bb,
1572 +       0xb9b99bbb, 0xb9b9b9bb, 0xb9bb9b99, 0x00000999,
1573 +       0x8a000000, 0xaa88a888, 0xa88888aa, 0xa88a8a88,
1574 +       0xa88aa88a, 0x88a8aaaa, 0xa8aa8aaa, 0x0888a88a,
1575 +       0x0b0b0b00, 0x090b0b0b, 0x0b090b0b, 0x0909090b,
1576 +       0x09090b0b, 0x09090b0b, 0x09090b09, 0x00000909,
1577 +       0x0a000000, 0x0a080808, 0x080a080a, 0x080a0a08,
1578 +       0x080a080a, 0x0808080a, 0x0a0a0a08, 0x0808080a,
1579 +       0xb0b0b000, 0x9090b0b0, 0x90b09090, 0xb0b0b090,
1580 +       0xb0b090b0, 0x90b0b0b0, 0xb0b09090, 0x00000090,
1581 +       0x80000000, 0xa080a080, 0xa08080a0, 0xa0808080,
1582 +       0xa080a080, 0x80a0a0a0, 0xa0a080a0, 0x00a0a0a0,
1583 +       0x22000000, 0x2222f222, 0x22222222, 0x222222f2,
1584 +       0xf2222220, 0x22222222, 0x22f22222, 0x00000222,
1585 +       0x11000000, 0x1111f111, 0x11111111, 0x111111f1,
1586 +       0xf1111110, 0x11111111, 0x11f11111, 0x00000111,
1587 +       0x33000000, 0x3333f333, 0x33333333, 0x333333f3,
1588 +       0xf3333330, 0x33333333, 0x33f33333, 0x00000333,
1589 +       0x22000000, 0x2222f222, 0x22222222, 0x222222f2,
1590 +       0xf2222220, 0x22222222, 0x22f22222, 0x00000222,
1591 +       0x99000000, 0x9b9b99bb, 0x9bb99999, 0x9999b9b9,
1592 +       0x9b99bb90, 0x9bbbbb9b, 0x9b9b9bb9, 0x00000999,
1593 +       0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
1594 +       0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
1595 +       0x88888000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
1596 +       0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
1597 +       0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
1598 +       0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00aaa888,
1599 +       0x88a88a00, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
1600 +       0x8a88aa88, 0x8aaaaa8a, 0x8a8a8aa8, 0x000aa888,
1601 +       0x88880000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
1602 +       0x8a88aa88, 0x8aaaaa8a, 0x8a8a8aa8, 0x08aaa888,
1603 +       0x11000000, 0x1111a111, 0x11111111, 0x111111a1,
1604 +       0xa1111110, 0x11111111, 0x11c11111, 0x00000111,
1605 +       0x11000000, 0x1111a111, 0x11111111, 0x111111a1,
1606 +       0xa1111110, 0x11111111, 0x11c11111, 0x00000111,
1607 +       0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
1608 +       0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
1609 +       0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
1610 +       0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
1611 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
1612 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
1613 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
1614 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
1615 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
1616 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
1617 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
1618 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
1619 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
1620 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
1621 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
1622 +       0x00000000, 0x00000000, 0x00000000, 0x00000000,
1623 +};
1624 +
1625 +/* Extracted from MMIO dump of 6.30.223.141 */
1626 +static const u32 b43_ntab_noisevar_r7[] = {
1627 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1628 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1629 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1630 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1631 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1632 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1633 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1634 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1635 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1636 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1637 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1638 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1639 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1640 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1641 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1642 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1643 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1644 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1645 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1646 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1647 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1648 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1649 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1650 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1651 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1652 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1653 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1654 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1655 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1656 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1657 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1658 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1659 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1660 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1661 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1662 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1663 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1664 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1665 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1666 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1667 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1668 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1669 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1670 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1671 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1672 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1673 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1674 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1675 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1676 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1677 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1678 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1679 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1680 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1681 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1682 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1683 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1684 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1685 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1686 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1687 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1688 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1689 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1690 +       0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
1691 +};
1692 +
1693 +/**************************************************
1694 + * TX gain tables
1695 + **************************************************/
1696 +
1697  static const u32 b43_ntab_tx_gain_rev0_1_2[] = {
1698         0x03cc2b44, 0x03cc2b42, 0x03cc2a44, 0x03cc2a42,
1699         0x03cc2944, 0x03c82b44, 0x03c82b42, 0x03c82a44,
1700 @@ -2182,7 +2371,9 @@ static const u32 b43_ntab_tx_gain_rev0_1
1701         0x03801442, 0x03801344, 0x03801342, 0x00002b00,
1702  };
1703  
1704 -static const u32 b43_ntab_tx_gain_rev3plus_2ghz[] = {
1705 +/* EPA 2 GHz */
1706 +
1707 +static const u32 b43_ntab_tx_gain_epa_rev3_2g[] = {
1708         0x1f410044, 0x1f410042, 0x1f410040, 0x1f41003e,
1709         0x1f41003c, 0x1f41003b, 0x1f410039, 0x1f410037,
1710         0x1e410044, 0x1e410042, 0x1e410040, 0x1e41003e,
1711 @@ -2217,7 +2408,9 @@ static const u32 b43_ntab_tx_gain_rev3pl
1712         0x1041003c, 0x1041003b, 0x10410039, 0x10410037,
1713  };
1714  
1715 -static const u32 b43_ntab_tx_gain_rev3_5ghz[] = {
1716 +/* EPA 5 GHz */
1717 +
1718 +static const u32 b43_ntab_tx_gain_epa_rev3_5g[] = {
1719         0xcff70044, 0xcff70042, 0xcff70040, 0xcff7003e,
1720         0xcff7003c, 0xcff7003b, 0xcff70039, 0xcff70037,
1721         0xcef70044, 0xcef70042, 0xcef70040, 0xcef7003e,
1722 @@ -2252,7 +2445,7 @@ static const u32 b43_ntab_tx_gain_rev3_5
1723         0xc0f7003c, 0xc0f7003b, 0xc0f70039, 0xc0f70037,
1724  };
1725  
1726 -static const u32 b43_ntab_tx_gain_rev4_5ghz[] = {
1727 +static const u32 b43_ntab_tx_gain_epa_rev4_5g[] = {
1728         0x2ff20044, 0x2ff20042, 0x2ff20040, 0x2ff2003e,
1729         0x2ff2003c, 0x2ff2003b, 0x2ff20039, 0x2ff20037,
1730         0x2ef20044, 0x2ef20042, 0x2ef20040, 0x2ef2003e,
1731 @@ -2287,7 +2480,7 @@ static const u32 b43_ntab_tx_gain_rev4_5
1732         0x20d2003a, 0x20d20038, 0x20d20036, 0x20d20034,
1733  };
1734  
1735 -static const u32 b43_ntab_tx_gain_rev5plus_5ghz[] = {
1736 +static const u32 b43_ntab_tx_gain_epa_rev5_5g[] = {
1737         0x0f62004a, 0x0f620048, 0x0f620046, 0x0f620044,
1738         0x0f620042, 0x0f620040, 0x0f62003e, 0x0f62003c,
1739         0x0e620044, 0x0e620042, 0x0e620040, 0x0e62003e,
1740 @@ -2322,7 +2515,9 @@ static const u32 b43_ntab_tx_gain_rev5pl
1741         0x0062003b, 0x00620039, 0x00620037, 0x00620035,
1742  };
1743  
1744 -static const u32 txpwrctrl_tx_gain_ipa[] = {
1745 +/* IPA 2 GHz */
1746 +
1747 +static const u32 b43_ntab_tx_gain_ipa_rev3_2g[] = {
1748         0x5ff7002d, 0x5ff7002b, 0x5ff7002a, 0x5ff70029,
1749         0x5ff70028, 0x5ff70027, 0x5ff70026, 0x5ff70025,
1750         0x5ef7002d, 0x5ef7002b, 0x5ef7002a, 0x5ef70029,
1751 @@ -2357,7 +2552,7 @@ static const u32 txpwrctrl_tx_gain_ipa[]
1752         0x50f70028, 0x50f70027, 0x50f70026, 0x50f70025,
1753  };
1754  
1755 -static const u32 txpwrctrl_tx_gain_ipa_rev5[] = {
1756 +static const u32 b43_ntab_tx_gain_ipa_rev5_2g[] = {
1757         0x1ff7002d, 0x1ff7002b, 0x1ff7002a, 0x1ff70029,
1758         0x1ff70028, 0x1ff70027, 0x1ff70026, 0x1ff70025,
1759         0x1ef7002d, 0x1ef7002b, 0x1ef7002a, 0x1ef70029,
1760 @@ -2392,7 +2587,7 @@ static const u32 txpwrctrl_tx_gain_ipa_r
1761         0x10f70028, 0x10f70027, 0x10f70026, 0x10f70025,
1762  };
1763  
1764 -static const u32 txpwrctrl_tx_gain_ipa_rev6[] = {
1765 +static const u32 b43_ntab_tx_gain_ipa_rev6_2g[] = {
1766         0x0ff7002d, 0x0ff7002b, 0x0ff7002a, 0x0ff70029,
1767         0x0ff70028, 0x0ff70027, 0x0ff70026, 0x0ff70025,
1768         0x0ef7002d, 0x0ef7002b, 0x0ef7002a, 0x0ef70029,
1769 @@ -2427,7 +2622,45 @@ static const u32 txpwrctrl_tx_gain_ipa_r
1770         0x00f70028, 0x00f70027, 0x00f70026, 0x00f70025,
1771  };
1772  
1773 -static const u32 txpwrctrl_tx_gain_ipa_5g[] = {
1774 +/* Extracted from MMIO dump of 6.30.223.141 */
1775 +static const u32 b43_ntab_tx_gain_ipa_2057_rev9_2g[] = {
1776 +       0x60ff0031, 0x60e7002c, 0x60cf002a, 0x60c70029,
1777 +       0x60b70029, 0x60a70029, 0x609f002a, 0x6097002b,
1778 +       0x6087002e, 0x60770031, 0x606f0032, 0x60670034,
1779 +       0x60670031, 0x605f0033, 0x605f0031, 0x60570033,
1780 +       0x60570030, 0x6057002d, 0x6057002b, 0x604f002d,
1781 +       0x604f002b, 0x604f0029, 0x604f0026, 0x60470029,
1782 +       0x60470027, 0x603f0029, 0x603f0027, 0x603f0025,
1783 +       0x60370029, 0x60370027, 0x60370024, 0x602f002a,
1784 +       0x602f0028, 0x602f0026, 0x602f0024, 0x6027002a,
1785 +       0x60270028, 0x60270026, 0x60270024, 0x60270022,
1786 +       0x601f002b, 0x601f0029, 0x601f0027, 0x601f0024,
1787 +       0x601f0022, 0x601f0020, 0x601f001f, 0x601f001d,
1788 +       0x60170029, 0x60170027, 0x60170025, 0x60170023,
1789 +       0x60170021, 0x6017001f, 0x6017001d, 0x6017001c,
1790 +       0x6017001a, 0x60170018, 0x60170018, 0x60170016,
1791 +       0x60170015, 0x600f0029, 0x600f0027, 0x600f0025,
1792 +       0x600f0023, 0x600f0021, 0x600f001f, 0x600f001d,
1793 +       0x600f001c, 0x600f001a, 0x600f0019, 0x600f0018,
1794 +       0x600f0016, 0x600f0015, 0x600f0115, 0x600f0215,
1795 +       0x600f0315, 0x600f0415, 0x600f0515, 0x600f0615,
1796 +       0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
1797 +       0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
1798 +       0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
1799 +       0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
1800 +       0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
1801 +       0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
1802 +       0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
1803 +       0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
1804 +       0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
1805 +       0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
1806 +       0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
1807 +       0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
1808 +};
1809 +
1810 +/* IPA 2 5Hz */
1811 +
1812 +static const u32 b43_ntab_tx_gain_ipa_rev3_5g[] = {
1813         0x7ff70035, 0x7ff70033, 0x7ff70032, 0x7ff70031,
1814         0x7ff7002f, 0x7ff7002e, 0x7ff7002d, 0x7ff7002b,
1815         0x7ff7002a, 0x7ff70029, 0x7ff70028, 0x7ff70027,
1816 @@ -2462,6 +2695,42 @@ static const u32 txpwrctrl_tx_gain_ipa_5
1817         0x70f70021, 0x70f70020, 0x70f70020, 0x70f7001f,
1818  };
1819  
1820 +/* Extracted from MMIO dump of 6.30.223.141 */
1821 +static const u32 b43_ntab_tx_gain_ipa_2057_rev9_5g[] = {
1822 +       0x7f7f0053, 0x7f7f004b, 0x7f7f0044, 0x7f7f003f,
1823 +       0x7f7f0039, 0x7f7f0035, 0x7f7f0032, 0x7f7f0030,
1824 +       0x7f7f002d, 0x7e7f0030, 0x7e7f002d, 0x7d7f0032,
1825 +       0x7d7f002f, 0x7d7f002c, 0x7c7f0032, 0x7c7f0030,
1826 +       0x7c7f002d, 0x7b7f0030, 0x7b7f002e, 0x7b7f002b,
1827 +       0x7a7f0032, 0x7a7f0030, 0x7a7f002d, 0x7a7f002b,
1828 +       0x797f0030, 0x797f002e, 0x797f002b, 0x797f0029,
1829 +       0x787f0030, 0x787f002d, 0x787f002b, 0x777f0032,
1830 +       0x777f0030, 0x777f002d, 0x777f002b, 0x767f0031,
1831 +       0x767f002f, 0x767f002c, 0x767f002a, 0x757f0031,
1832 +       0x757f002f, 0x757f002c, 0x757f002a, 0x747f0030,
1833 +       0x747f002d, 0x747f002b, 0x737f0032, 0x737f002f,
1834 +       0x737f002c, 0x737f002a, 0x727f0030, 0x727f002d,
1835 +       0x727f002b, 0x727f0029, 0x717f0030, 0x717f002d,
1836 +       0x717f002b, 0x707f0031, 0x707f002f, 0x707f002c,
1837 +       0x707f002a, 0x707f0027, 0x707f0025, 0x707f0023,
1838 +       0x707f0021, 0x707f001f, 0x707f001d, 0x707f001c,
1839 +       0x707f001a, 0x707f0019, 0x707f0017, 0x707f0016,
1840 +       0x707f0015, 0x707f0014, 0x707f0012, 0x707f0012,
1841 +       0x707f0011, 0x707f0010, 0x707f000f, 0x707f000e,
1842 +       0x707f000d, 0x707f000d, 0x707f000c, 0x707f000b,
1843 +       0x707f000a, 0x707f000a, 0x707f0009, 0x707f0008,
1844 +       0x707f0008, 0x707f0008, 0x707f0008, 0x707f0007,
1845 +       0x707f0007, 0x707f0006, 0x707f0006, 0x707f0006,
1846 +       0x707f0005, 0x707f0005, 0x707f0005, 0x707f0004,
1847 +       0x707f0004, 0x707f0004, 0x707f0003, 0x707f0003,
1848 +       0x707f0003, 0x707f0003, 0x707f0003, 0x707f0003,
1849 +       0x707f0003, 0x707f0003, 0x707f0003, 0x707f0003,
1850 +       0x707f0002, 0x707f0002, 0x707f0002, 0x707f0002,
1851 +       0x707f0002, 0x707f0002, 0x707f0002, 0x707f0002,
1852 +       0x707f0002, 0x707f0001, 0x707f0001, 0x707f0001,
1853 +       0x707f0001, 0x707f0001, 0x707f0001, 0x707f0001,
1854 +};
1855 +
1856  const s8 b43_ntab_papd_pga_gain_delta_ipa_2g[] = {
1857         -114, -108, -98, -91, -84, -78, -70, -62,
1858         -54, -46, -39, -31, -23, -15, -8, 0
1859 @@ -3031,31 +3300,8 @@ void b43_ntab_write_bulk(struct b43_wlde
1860                 b43_ntab_write_bulk(dev, offset, ARRAY_SIZE(data), data); \
1861         } while (0)
1862  
1863 -static void b43_nphy_tables_init_rev3(struct b43_wldev *dev)
1864 +static void b43_nphy_tables_init_shared_lut(struct b43_wldev *dev)
1865  {
1866 -       struct ssb_sprom *sprom = dev->dev->bus_sprom;
1867 -       u8 antswlut;
1868 -
1869 -       if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
1870 -               antswlut = sprom->fem.ghz5.antswlut;
1871 -       else
1872 -               antswlut = sprom->fem.ghz2.antswlut;
1873 -
1874 -       /* Static tables */
1875 -       ntab_upload(dev, B43_NTAB_FRAMESTRUCT_R3, b43_ntab_framestruct_r3);
1876 -       ntab_upload(dev, B43_NTAB_PILOT_R3, b43_ntab_pilot_r3);
1877 -       ntab_upload(dev, B43_NTAB_TMAP_R3, b43_ntab_tmap_r3);
1878 -       ntab_upload(dev, B43_NTAB_INTLEVEL_R3, b43_ntab_intlevel_r3);
1879 -       ntab_upload(dev, B43_NTAB_TDTRN_R3, b43_ntab_tdtrn_r3);
1880 -       ntab_upload(dev, B43_NTAB_NOISEVAR_R3, b43_ntab_noisevar_r3);
1881 -       ntab_upload(dev, B43_NTAB_MCS_R3, b43_ntab_mcs_r3);
1882 -       ntab_upload(dev, B43_NTAB_TDI20A0_R3, b43_ntab_tdi20a0_r3);
1883 -       ntab_upload(dev, B43_NTAB_TDI20A1_R3, b43_ntab_tdi20a1_r3);
1884 -       ntab_upload(dev, B43_NTAB_TDI40A0_R3, b43_ntab_tdi40a0_r3);
1885 -       ntab_upload(dev, B43_NTAB_TDI40A1_R3, b43_ntab_tdi40a1_r3);
1886 -       ntab_upload(dev, B43_NTAB_PILOTLT_R3, b43_ntab_pilotlt_r3);
1887 -       ntab_upload(dev, B43_NTAB_CHANEST_R3, b43_ntab_channelest_r3);
1888 -       ntab_upload(dev, B43_NTAB_FRAMELT_R3, b43_ntab_framelookup_r3);
1889         ntab_upload(dev, B43_NTAB_C0_ESTPLT_R3, b43_ntab_estimatepowerlt0_r3);
1890         ntab_upload(dev, B43_NTAB_C1_ESTPLT_R3, b43_ntab_estimatepowerlt1_r3);
1891         ntab_upload(dev, B43_NTAB_C0_ADJPLT_R3, b43_ntab_adjustpower0_r3);
1892 @@ -3066,6 +3312,107 @@ static void b43_nphy_tables_init_rev3(st
1893         ntab_upload(dev, B43_NTAB_C1_IQLT_R3, b43_ntab_iqlt1_r3);
1894         ntab_upload(dev, B43_NTAB_C0_LOFEEDTH_R3, b43_ntab_loftlt0_r3);
1895         ntab_upload(dev, B43_NTAB_C1_LOFEEDTH_R3, b43_ntab_loftlt1_r3);
1896 +}
1897 +
1898 +static void b43_nphy_tables_init_rev7_volatile(struct b43_wldev *dev)
1899 +{
1900 +       struct ssb_sprom *sprom = dev->dev->bus_sprom;
1901 +       u8 antswlut;
1902 +       int core, offset, i;
1903 +
1904 +       const int antswlut0_offsets[] = { 0, 4, 8, }; /* Offsets for values */
1905 +       const u8 antswlut0_values[][3] = {
1906 +               { 0x2, 0x12, 0x8 }, /* Core 0 */
1907 +               { 0x2, 0x18, 0x2 }, /* Core 1 */
1908 +       };
1909 +
1910 +       if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
1911 +               antswlut = sprom->fem.ghz5.antswlut;
1912 +       else
1913 +               antswlut = sprom->fem.ghz2.antswlut;
1914 +
1915 +       switch (antswlut) {
1916 +       case 0:
1917 +               for (core = 0; core < 2; core++) {
1918 +                       for (i = 0; i < ARRAY_SIZE(antswlut0_values[0]); i++) {
1919 +                               offset = core ? 0x20 : 0x00;
1920 +                               offset += antswlut0_offsets[i];
1921 +                               b43_ntab_write(dev, B43_NTAB8(9, offset),
1922 +                                              antswlut0_values[core][i]);
1923 +                       }
1924 +               }
1925 +               break;
1926 +       default:
1927 +               b43err(dev->wl, "Unsupported antswlut: %d\n", antswlut);
1928 +               break;
1929 +       }
1930 +}
1931 +
1932 +static void b43_nphy_tables_init_rev16(struct b43_wldev *dev)
1933 +{
1934 +       /* Static tables */
1935 +       if (dev->phy.do_full_init) {
1936 +               ntab_upload(dev, B43_NTAB_NOISEVAR_R7, b43_ntab_noisevar_r7);
1937 +               b43_nphy_tables_init_shared_lut(dev);
1938 +       }
1939 +
1940 +       /* Volatile tables */
1941 +       b43_nphy_tables_init_rev7_volatile(dev);
1942 +}
1943 +
1944 +static void b43_nphy_tables_init_rev7(struct b43_wldev *dev)
1945 +{
1946 +       /* Static tables */
1947 +       if (dev->phy.do_full_init) {
1948 +               ntab_upload(dev, B43_NTAB_FRAMESTRUCT_R3, b43_ntab_framestruct_r3);
1949 +               ntab_upload(dev, B43_NTAB_PILOT_R3, b43_ntab_pilot_r3);
1950 +               ntab_upload(dev, B43_NTAB_TMAP_R7, b43_ntab_tmap_r7);
1951 +               ntab_upload(dev, B43_NTAB_INTLEVEL_R3, b43_ntab_intlevel_r3);
1952 +               ntab_upload(dev, B43_NTAB_TDTRN_R3, b43_ntab_tdtrn_r3);
1953 +               ntab_upload(dev, B43_NTAB_NOISEVAR_R7, b43_ntab_noisevar_r7);
1954 +               ntab_upload(dev, B43_NTAB_MCS_R3, b43_ntab_mcs_r3);
1955 +               ntab_upload(dev, B43_NTAB_TDI20A0_R3, b43_ntab_tdi20a0_r3);
1956 +               ntab_upload(dev, B43_NTAB_TDI20A1_R3, b43_ntab_tdi20a1_r3);
1957 +               ntab_upload(dev, B43_NTAB_TDI40A0_R3, b43_ntab_tdi40a0_r3);
1958 +               ntab_upload(dev, B43_NTAB_TDI40A1_R3, b43_ntab_tdi40a1_r3);
1959 +               ntab_upload(dev, B43_NTAB_PILOTLT_R3, b43_ntab_pilotlt_r3);
1960 +               ntab_upload(dev, B43_NTAB_CHANEST_R3, b43_ntab_channelest_r3);
1961 +               ntab_upload(dev, B43_NTAB_FRAMELT_R3, b43_ntab_framelookup_r3);
1962 +               b43_nphy_tables_init_shared_lut(dev);
1963 +       }
1964 +
1965 +       /* Volatile tables */
1966 +       b43_nphy_tables_init_rev7_volatile(dev);
1967 +}
1968 +
1969 +static void b43_nphy_tables_init_rev3(struct b43_wldev *dev)
1970 +{
1971 +       struct ssb_sprom *sprom = dev->dev->bus_sprom;
1972 +       u8 antswlut;
1973 +
1974 +       if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
1975 +               antswlut = sprom->fem.ghz5.antswlut;
1976 +       else
1977 +               antswlut = sprom->fem.ghz2.antswlut;
1978 +
1979 +       /* Static tables */
1980 +       if (dev->phy.do_full_init) {
1981 +               ntab_upload(dev, B43_NTAB_FRAMESTRUCT_R3, b43_ntab_framestruct_r3);
1982 +               ntab_upload(dev, B43_NTAB_PILOT_R3, b43_ntab_pilot_r3);
1983 +               ntab_upload(dev, B43_NTAB_TMAP_R3, b43_ntab_tmap_r3);
1984 +               ntab_upload(dev, B43_NTAB_INTLEVEL_R3, b43_ntab_intlevel_r3);
1985 +               ntab_upload(dev, B43_NTAB_TDTRN_R3, b43_ntab_tdtrn_r3);
1986 +               ntab_upload(dev, B43_NTAB_NOISEVAR_R3, b43_ntab_noisevar_r3);
1987 +               ntab_upload(dev, B43_NTAB_MCS_R3, b43_ntab_mcs_r3);
1988 +               ntab_upload(dev, B43_NTAB_TDI20A0_R3, b43_ntab_tdi20a0_r3);
1989 +               ntab_upload(dev, B43_NTAB_TDI20A1_R3, b43_ntab_tdi20a1_r3);
1990 +               ntab_upload(dev, B43_NTAB_TDI40A0_R3, b43_ntab_tdi40a0_r3);
1991 +               ntab_upload(dev, B43_NTAB_TDI40A1_R3, b43_ntab_tdi40a1_r3);
1992 +               ntab_upload(dev, B43_NTAB_PILOTLT_R3, b43_ntab_pilotlt_r3);
1993 +               ntab_upload(dev, B43_NTAB_CHANEST_R3, b43_ntab_channelest_r3);
1994 +               ntab_upload(dev, B43_NTAB_FRAMELT_R3, b43_ntab_framelookup_r3);
1995 +               b43_nphy_tables_init_shared_lut(dev);
1996 +       }
1997  
1998         /* Volatile tables */
1999         if (antswlut < ARRAY_SIZE(b43_ntab_antswctl_r3))
2000 @@ -3078,20 +3425,22 @@ static void b43_nphy_tables_init_rev3(st
2001  static void b43_nphy_tables_init_rev0(struct b43_wldev *dev)
2002  {
2003         /* Static tables */
2004 -       ntab_upload(dev, B43_NTAB_FRAMESTRUCT, b43_ntab_framestruct);
2005 -       ntab_upload(dev, B43_NTAB_FRAMELT, b43_ntab_framelookup);
2006 -       ntab_upload(dev, B43_NTAB_TMAP, b43_ntab_tmap);
2007 -       ntab_upload(dev, B43_NTAB_TDTRN, b43_ntab_tdtrn);
2008 -       ntab_upload(dev, B43_NTAB_INTLEVEL, b43_ntab_intlevel);
2009 -       ntab_upload(dev, B43_NTAB_PILOT, b43_ntab_pilot);
2010 -       ntab_upload(dev, B43_NTAB_TDI20A0, b43_ntab_tdi20a0);
2011 -       ntab_upload(dev, B43_NTAB_TDI20A1, b43_ntab_tdi20a1);
2012 -       ntab_upload(dev, B43_NTAB_TDI40A0, b43_ntab_tdi40a0);
2013 -       ntab_upload(dev, B43_NTAB_TDI40A1, b43_ntab_tdi40a1);
2014 -       ntab_upload(dev, B43_NTAB_CHANEST, b43_ntab_channelest);
2015 -       ntab_upload(dev, B43_NTAB_MCS, b43_ntab_mcs);
2016 -       ntab_upload(dev, B43_NTAB_NOISEVAR10, b43_ntab_noisevar10);
2017 -       ntab_upload(dev, B43_NTAB_NOISEVAR11, b43_ntab_noisevar11);
2018 +       if (dev->phy.do_full_init) {
2019 +               ntab_upload(dev, B43_NTAB_FRAMESTRUCT, b43_ntab_framestruct);
2020 +               ntab_upload(dev, B43_NTAB_FRAMELT, b43_ntab_framelookup);
2021 +               ntab_upload(dev, B43_NTAB_TMAP, b43_ntab_tmap);
2022 +               ntab_upload(dev, B43_NTAB_TDTRN, b43_ntab_tdtrn);
2023 +               ntab_upload(dev, B43_NTAB_INTLEVEL, b43_ntab_intlevel);
2024 +               ntab_upload(dev, B43_NTAB_PILOT, b43_ntab_pilot);
2025 +               ntab_upload(dev, B43_NTAB_TDI20A0, b43_ntab_tdi20a0);
2026 +               ntab_upload(dev, B43_NTAB_TDI20A1, b43_ntab_tdi20a1);
2027 +               ntab_upload(dev, B43_NTAB_TDI40A0, b43_ntab_tdi40a0);
2028 +               ntab_upload(dev, B43_NTAB_TDI40A1, b43_ntab_tdi40a1);
2029 +               ntab_upload(dev, B43_NTAB_CHANEST, b43_ntab_channelest);
2030 +               ntab_upload(dev, B43_NTAB_MCS, b43_ntab_mcs);
2031 +               ntab_upload(dev, B43_NTAB_NOISEVAR10, b43_ntab_noisevar10);
2032 +               ntab_upload(dev, B43_NTAB_NOISEVAR11, b43_ntab_noisevar11);
2033 +       }
2034  
2035         /* Volatile tables */
2036         ntab_upload(dev, B43_NTAB_BDI, b43_ntab_bdi);
2037 @@ -3111,7 +3460,11 @@ static void b43_nphy_tables_init_rev0(st
2038  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/InitTables */
2039  void b43_nphy_tables_init(struct b43_wldev *dev)
2040  {
2041 -       if (dev->phy.rev >= 3)
2042 +       if (dev->phy.rev >= 16)
2043 +               b43_nphy_tables_init_rev16(dev);
2044 +       else if (dev->phy.rev >= 7)
2045 +               b43_nphy_tables_init_rev7(dev);
2046 +       else if (dev->phy.rev >= 3)
2047                 b43_nphy_tables_init_rev3(dev);
2048         else
2049                 b43_nphy_tables_init_rev0(dev);
2050 @@ -3120,23 +3473,45 @@ void b43_nphy_tables_init(struct b43_wld
2051  /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetIpaGainTbl */
2052  static const u32 *b43_nphy_get_ipa_gain_table(struct b43_wldev *dev)
2053  {
2054 +       struct b43_phy *phy = &dev->phy;
2055 +
2056         if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
2057 -               if (dev->phy.rev >= 6) {
2058 -                       if (dev->dev->chip_id == 47162)
2059 -                               return txpwrctrl_tx_gain_ipa_rev5;
2060 -                       return txpwrctrl_tx_gain_ipa_rev6;
2061 -               } else if (dev->phy.rev >= 5) {
2062 -                       return txpwrctrl_tx_gain_ipa_rev5;
2063 -               } else {
2064 -                       return txpwrctrl_tx_gain_ipa;
2065 +               switch (phy->rev) {
2066 +               case 16:
2067 +                       if (phy->radio_rev == 9)
2068 +                               return b43_ntab_tx_gain_ipa_2057_rev9_2g;
2069 +               case 6:
2070 +                       if (dev->dev->chip_id == BCMA_CHIP_ID_BCM47162)
2071 +                               return b43_ntab_tx_gain_ipa_rev5_2g;
2072 +                       return b43_ntab_tx_gain_ipa_rev6_2g;
2073 +               case 5:
2074 +                       return b43_ntab_tx_gain_ipa_rev5_2g;
2075 +               case 4:
2076 +               case 3:
2077 +                       return b43_ntab_tx_gain_ipa_rev3_2g;
2078 +               default:
2079 +                       b43err(dev->wl,
2080 +                              "No 2GHz IPA gain table available for this device\n");
2081 +                       return NULL;
2082                 }
2083         } else {
2084 -               return txpwrctrl_tx_gain_ipa_5g;
2085 +               switch (phy->rev) {
2086 +               case 16:
2087 +                       if (phy->radio_rev == 9)
2088 +                               return b43_ntab_tx_gain_ipa_2057_rev9_5g;
2089 +               case 3 ... 6:
2090 +                       return b43_ntab_tx_gain_ipa_rev3_5g;
2091 +               default:
2092 +                       b43err(dev->wl,
2093 +                              "No 5GHz IPA gain table available for this device\n");
2094 +                       return NULL;
2095 +               }
2096         }
2097  }
2098  
2099  const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev)
2100  {
2101 +       struct b43_phy *phy = &dev->phy;
2102         enum ieee80211_band band = b43_current_band(dev->wl);
2103         struct ssb_sprom *sprom = dev->dev->bus_sprom;
2104  
2105 @@ -3148,19 +3523,36 @@ const u32 *b43_nphy_get_tx_gain_table(st
2106             (dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ)) {
2107                 return b43_nphy_get_ipa_gain_table(dev);
2108         } else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
2109 -               if (dev->phy.rev == 3)
2110 -                       return b43_ntab_tx_gain_rev3_5ghz;
2111 -               if (dev->phy.rev == 4)
2112 +               switch (phy->rev) {
2113 +               case 6:
2114 +               case 5:
2115 +                       return b43_ntab_tx_gain_epa_rev5_5g;
2116 +               case 4:
2117                         return sprom->fem.ghz5.extpa_gain == 3 ?
2118 -                               b43_ntab_tx_gain_rev4_5ghz :
2119 -                               b43_ntab_tx_gain_rev4_5ghz; /* FIXME */
2120 -               else
2121 -                       return b43_ntab_tx_gain_rev5plus_5ghz;
2122 +                               b43_ntab_tx_gain_epa_rev4_5g :
2123 +                               b43_ntab_tx_gain_epa_rev4_5g; /* FIXME */
2124 +               case 3:
2125 +                       return b43_ntab_tx_gain_epa_rev3_5g;
2126 +               default:
2127 +                       b43err(dev->wl,
2128 +                              "No 5GHz EPA gain table available for this device\n");
2129 +                       return NULL;
2130 +               }
2131         } else {
2132 -               if (dev->phy.rev >= 5 && sprom->fem.ghz5.extpa_gain == 3)
2133 -                       return b43_ntab_tx_gain_rev3plus_2ghz; /* FIXME */
2134 -               else
2135 -                       return b43_ntab_tx_gain_rev3plus_2ghz;
2136 +               switch (phy->rev) {
2137 +               case 6:
2138 +               case 5:
2139 +                       if (sprom->fem.ghz5.extpa_gain == 3)
2140 +                               return b43_ntab_tx_gain_epa_rev3_2g; /* FIXME */
2141 +                       /* fall through */
2142 +               case 4:
2143 +               case 3:
2144 +                       return b43_ntab_tx_gain_epa_rev3_2g;
2145 +               default:
2146 +                       b43err(dev->wl,
2147 +                              "No 2GHz EPA gain table available for this device\n");
2148 +                       return NULL;
2149 +               }
2150         }
2151  }
2152  
2153 @@ -3187,7 +3579,7 @@ struct nphy_gain_ctl_workaround_entry *b
2154         /* Some workarounds to the workarounds... */
2155         if (ghz5 && dev->phy.rev >= 6) {
2156                 if (dev->phy.radio_rev == 11 &&
2157 -                   !b43_channel_type_is_40mhz(dev->phy.channel_type))
2158 +                   !b43_is_40mhz(dev))
2159                         e->cliplo_gain = 0x2d;
2160         } else if (!ghz5 && dev->phy.rev >= 5) {
2161                 static const int gain_data[] = {0x0062, 0x0064, 0x006a, 0x106a,
2162 --- a/drivers/net/wireless/b43/Kconfig
2163 +++ b/drivers/net/wireless/b43/Kconfig
2164 @@ -37,7 +37,7 @@ config B43_SSB
2165  choice
2166         prompt "Supported bus types"
2167         depends on B43
2168 -       default B43_BCMA_AND_SSB
2169 +       default B43_BUSES_BCMA_AND_SSB
2170  
2171  config B43_BUSES_BCMA_AND_SSB
2172         bool "BCMA and SSB"
2173 @@ -123,6 +123,15 @@ config B43_PIO
2174         select SSB_BLOCKIO
2175         default y
2176  
2177 +config B43_PHY_G
2178 +       bool "Support for G-PHY (802.11g) devices"
2179 +       depends on B43 && B43_SSB
2180 +       default y
2181 +       ---help---
2182 +         This PHY type can be found in the following chipsets:
2183 +         PCI: BCM4306, BCM4311, BCM4318
2184 +         SoC: BCM4712, BCM5352E
2185 +
2186  config B43_PHY_N
2187         bool "Support for 802.11n (N-PHY) devices"
2188         depends on B43
2189 --- a/drivers/net/wireless/b43/phy_ht.c
2190 +++ b/drivers/net/wireless/b43/phy_ht.c
2191 @@ -596,7 +596,7 @@ static void b43_phy_ht_tx_power_ctl_setu
2192         u8 target[3];
2193         s16 a1[3], b0[3], b1[3];
2194  
2195 -       u16 freq = dev->phy.channel_freq;
2196 +       u16 freq = dev->phy.chandef->chan->center_freq;
2197         int i, c;
2198  
2199         if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
2200 --- a/drivers/net/wireless/b43/phy_a.h
2201 +++ b/drivers/net/wireless/b43/phy_a.h
2202 @@ -123,8 +123,4 @@ struct b43_phy_a {
2203   */
2204  void b43_phy_inita(struct b43_wldev *dev);
2205  
2206 -
2207 -struct b43_phy_operations;
2208 -extern const struct b43_phy_operations b43_phyops_a;
2209 -
2210  #endif /* LINUX_B43_PHY_A_H_ */
2211 --- a/drivers/net/wireless/b43/Makefile
2212 +++ b/drivers/net/wireless/b43/Makefile
2213 @@ -1,13 +1,11 @@
2214  b43-y                          += main.o
2215  b43-y                          += bus.o
2216 -b43-y                          += tables.o
2217 +b43-$(CPTCFG_B43_PHY_G)                += phy_a.o phy_g.o tables.o lo.o wa.o
2218  b43-$(CPTCFG_B43_PHY_N)                += tables_nphy.o
2219  b43-$(CPTCFG_B43_PHY_N)                += radio_2055.o
2220  b43-$(CPTCFG_B43_PHY_N)                += radio_2056.o
2221  b43-$(CPTCFG_B43_PHY_N)                += radio_2057.o
2222  b43-y                          += phy_common.o
2223 -b43-y                          += phy_g.o
2224 -b43-y                          += phy_a.o
2225  b43-$(CPTCFG_B43_PHY_N)                += phy_n.o
2226  b43-$(CPTCFG_B43_PHY_LP)       += phy_lp.o
2227  b43-$(CPTCFG_B43_PHY_LP)       += tables_lpphy.o
2228 @@ -17,8 +15,6 @@ b43-$(CPTCFG_B43_PHY_HT)      += radio_2059.o
2229  b43-$(CPTCFG_B43_PHY_LCN)      += phy_lcn.o tables_phy_lcn.o
2230  b43-y                          += sysfs.o
2231  b43-y                          += xmit.o
2232 -b43-y                          += lo.o
2233 -b43-y                          += wa.o
2234  b43-y                          += dma.o
2235  b43-y                          += pio.o
2236  b43-y                          += rfkill.o
2237 --- a/drivers/net/wireless/b43/phy_a.c
2238 +++ b/drivers/net/wireless/b43/phy_a.c
2239 @@ -573,7 +573,7 @@ static void b43_aphy_op_pwork_60sec(stru
2240  {//TODO
2241  }
2242  
2243 -const struct b43_phy_operations b43_phyops_a = {
2244 +static const struct b43_phy_operations b43_phyops_a = {
2245         .allocate               = b43_aphy_op_allocate,
2246         .free                   = b43_aphy_op_free,
2247         .prepare_structs        = b43_aphy_op_prepare_structs,
2248 --- a/drivers/net/wireless/b43/radio_2057.c
2249 +++ b/drivers/net/wireless/b43/radio_2057.c
2250 @@ -26,7 +26,7 @@
2251  #include "radio_2057.h"
2252  #include "phy_common.h"
2253  
2254 -static u16 r2057_rev4_init[42][2] = {
2255 +static u16 r2057_rev4_init[][2] = {
2256         { 0x0E, 0x20 }, { 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 },
2257         { 0x35, 0x26 }, { 0x3C, 0xff }, { 0x3D, 0xff }, { 0x3E, 0xff },
2258         { 0x3F, 0xff }, { 0x62, 0x33 }, { 0x8A, 0xf0 }, { 0x8B, 0x10 },
2259 @@ -40,7 +40,7 @@ static u16 r2057_rev4_init[42][2] = {
2260         { 0x1AB, 0x00 }, { 0x1AC, 0x00 },
2261  };
2262  
2263 -static u16 r2057_rev5_init[44][2] = {
2264 +static u16 r2057_rev5_init[][2] = {
2265         { 0x00, 0x00 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x23, 0x6 },
2266         { 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 },
2267         { 0x59, 0x88 }, { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f },
2268 @@ -54,7 +54,7 @@ static u16 r2057_rev5_init[44][2] = {
2269         { 0x1AC, 0x00 }, { 0x1B7, 0x0c }, { 0x1C1, 0x01 }, { 0x1C2, 0x80 },
2270  };
2271  
2272 -static u16 r2057_rev5a_init[45][2] = {
2273 +static u16 r2057_rev5a_init[][2] = {
2274         { 0x00, 0x15 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x23, 0x6 },
2275         { 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 },
2276         { 0x59, 0x88 }, { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f },
2277 @@ -69,7 +69,7 @@ static u16 r2057_rev5a_init[45][2] = {
2278         { 0x1C2, 0x80 },
2279  };
2280  
2281 -static u16 r2057_rev7_init[54][2] = {
2282 +static u16 r2057_rev7_init[][2] = {
2283         { 0x00, 0x00 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x31, 0x00 },
2284         { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 }, { 0x59, 0x88 },
2285         { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f }, { 0x64, 0x13 },
2286 @@ -86,7 +86,8 @@ static u16 r2057_rev7_init[54][2] = {
2287         { 0x1B7, 0x05 }, { 0x1C2, 0xa0 },
2288  };
2289  
2290 -static u16 r2057_rev8_init[54][2] = {
2291 +/* TODO: Which devices should use it?
2292 +static u16 r2057_rev8_init[][2] = {
2293         { 0x00, 0x08 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x31, 0x00 },
2294         { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 }, { 0x59, 0x88 },
2295         { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f }, { 0x64, 0x0f },
2296 @@ -102,6 +103,47 @@ static u16 r2057_rev8_init[54][2] = {
2297         { 0x1A6, 0x00 }, { 0x1AA, 0x00 }, { 0x1AB, 0x00 }, { 0x1AC, 0x00 },
2298         { 0x1B7, 0x05 }, { 0x1C2, 0xa0 },
2299  };
2300 +*/
2301 +
2302 +#define RADIOREGS7(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \
2303 +                  r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, \
2304 +                  r20, r21, r22, r23, r24, r25, r26, r27) \
2305 +       .radio_vcocal_countval0                 = r00,  \
2306 +       .radio_vcocal_countval1                 = r01,  \
2307 +       .radio_rfpll_refmaster_sparextalsize    = r02,  \
2308 +       .radio_rfpll_loopfilter_r1              = r03,  \
2309 +       .radio_rfpll_loopfilter_c2              = r04,  \
2310 +       .radio_rfpll_loopfilter_c1              = r05,  \
2311 +       .radio_cp_kpd_idac                      = r06,  \
2312 +       .radio_rfpll_mmd0                       = r07,  \
2313 +       .radio_rfpll_mmd1                       = r08,  \
2314 +       .radio_vcobuf_tune                      = r09,  \
2315 +       .radio_logen_mx2g_tune                  = r10,  \
2316 +       .radio_logen_mx5g_tune                  = r11,  \
2317 +       .radio_logen_indbuf2g_tune              = r12,  \
2318 +       .radio_logen_indbuf5g_tune              = r13,  \
2319 +       .radio_txmix2g_tune_boost_pu_core0      = r14,  \
2320 +       .radio_pad2g_tune_pus_core0             = r15,  \
2321 +       .radio_pga_boost_tune_core0             = r16,  \
2322 +       .radio_txmix5g_boost_tune_core0         = r17,  \
2323 +       .radio_pad5g_tune_misc_pus_core0        = r18,  \
2324 +       .radio_lna2g_tune_core0                 = r19,  \
2325 +       .radio_lna5g_tune_core0                 = r20,  \
2326 +       .radio_txmix2g_tune_boost_pu_core1      = r21,  \
2327 +       .radio_pad2g_tune_pus_core1             = r22,  \
2328 +       .radio_pga_boost_tune_core1             = r23,  \
2329 +       .radio_txmix5g_boost_tune_core1         = r24,  \
2330 +       .radio_pad5g_tune_misc_pus_core1        = r25,  \
2331 +       .radio_lna2g_tune_core1                 = r26,  \
2332 +       .radio_lna5g_tune_core1                 = r27
2333 +
2334 +#define PHYREGS(r0, r1, r2, r3, r4, r5)        \
2335 +       .phy_regs.phy_bw1a      = r0,   \
2336 +       .phy_regs.phy_bw2       = r1,   \
2337 +       .phy_regs.phy_bw3       = r2,   \
2338 +       .phy_regs.phy_bw4       = r3,   \
2339 +       .phy_regs.phy_bw5       = r4,   \
2340 +       .phy_regs.phy_bw6       = r5
2341  
2342  void r2057_upload_inittabs(struct b43_wldev *dev)
2343  {
2344 @@ -109,33 +151,69 @@ void r2057_upload_inittabs(struct b43_wl
2345         u16 *table = NULL;
2346         u16 size, i;
2347  
2348 -       if (phy->rev == 7) {
2349 +       switch (phy->rev) {
2350 +       case 7:
2351                 table = r2057_rev4_init[0];
2352                 size = ARRAY_SIZE(r2057_rev4_init);
2353 -       } else if (phy->rev == 8 || phy->rev == 9) {
2354 +               break;
2355 +       case 8:
2356                 if (phy->radio_rev == 5) {
2357 -                       if (phy->radio_rev == 8) {
2358 -                               table = r2057_rev5_init[0];
2359 -                               size = ARRAY_SIZE(r2057_rev5_init);
2360 -                       } else {
2361 -                               table = r2057_rev5a_init[0];
2362 -                               size = ARRAY_SIZE(r2057_rev5a_init);
2363 -                       }
2364 +                       table = r2057_rev5_init[0];
2365 +                       size = ARRAY_SIZE(r2057_rev5_init);
2366                 } else if (phy->radio_rev == 7) {
2367                         table = r2057_rev7_init[0];
2368                         size = ARRAY_SIZE(r2057_rev7_init);
2369 -               } else if (phy->radio_rev == 9) {
2370 -                       table = r2057_rev8_init[0];
2371 -                       size = ARRAY_SIZE(r2057_rev8_init);
2372                 }
2373 +               break;
2374 +       case 9:
2375 +               if (phy->radio_rev == 5) {
2376 +                       table = r2057_rev5a_init[0];
2377 +                       size = ARRAY_SIZE(r2057_rev5a_init);
2378 +               }
2379 +               break;
2380         }
2381  
2382 +       B43_WARN_ON(!table);
2383 +
2384         if (table) {
2385 -               for (i = 0; i < 10; i++) {
2386 -                       pr_info("radio_write 0x%X ", *table);
2387 -                       table++;
2388 -                       pr_info("0x%X\n", *table);
2389 -                       table++;
2390 +               for (i = 0; i < size; i++, table += 2)
2391 +                       b43_radio_write(dev, table[0], table[1]);
2392 +       }
2393 +}
2394 +
2395 +void r2057_get_chantabent_rev7(struct b43_wldev *dev, u16 freq,
2396 +                              const struct b43_nphy_chantabent_rev7 **tabent_r7,
2397 +                              const struct b43_nphy_chantabent_rev7_2g **tabent_r7_2g)
2398 +{
2399 +       struct b43_phy *phy = &dev->phy;
2400 +       const struct b43_nphy_chantabent_rev7 *e_r7 = NULL;
2401 +       const struct b43_nphy_chantabent_rev7_2g *e_r7_2g = NULL;
2402 +       unsigned int len, i;
2403 +
2404 +       *tabent_r7 = NULL;
2405 +       *tabent_r7_2g = NULL;
2406 +
2407 +       /* TODO */
2408 +       switch (phy->rev) {
2409 +       default:
2410 +               break;
2411 +       }
2412 +
2413 +       if (e_r7) {
2414 +               for (i = 0; i < len; i++, e_r7++) {
2415 +                       if (e_r7->freq == freq) {
2416 +                               *tabent_r7 = e_r7;
2417 +                               return;
2418 +                       }
2419 +               }
2420 +       } else if (e_r7_2g) {
2421 +               for (i = 0; i < len; i++, e_r7_2g++) {
2422 +                       if (e_r7_2g->freq == freq) {
2423 +                               *tabent_r7_2g = e_r7_2g;
2424 +                               return;
2425 +                       }
2426                 }
2427 +       } else {
2428 +               B43_WARN_ON(1);
2429         }
2430  }
2431 --- a/drivers/net/wireless/b43/radio_2057.h
2432 +++ b/drivers/net/wireless/b43/radio_2057.h
2433 @@ -425,6 +425,72 @@
2434  
2435  #define R2057_VCM_MASK                         0x7
2436  
2437 +struct b43_nphy_chantabent_rev7 {
2438 +       /* The channel frequency in MHz */
2439 +       u16 freq;
2440 +       /* Radio regs values on channelswitch */
2441 +       u8 radio_vcocal_countval0;
2442 +       u8 radio_vcocal_countval1;
2443 +       u8 radio_rfpll_refmaster_sparextalsize;
2444 +       u8 radio_rfpll_loopfilter_r1;
2445 +       u8 radio_rfpll_loopfilter_c2;
2446 +       u8 radio_rfpll_loopfilter_c1;
2447 +       u8 radio_cp_kpd_idac;
2448 +       u8 radio_rfpll_mmd0;
2449 +       u8 radio_rfpll_mmd1;
2450 +       u8 radio_vcobuf_tune;
2451 +       u8 radio_logen_mx2g_tune;
2452 +       u8 radio_logen_mx5g_tune;
2453 +       u8 radio_logen_indbuf2g_tune;
2454 +       u8 radio_logen_indbuf5g_tune;
2455 +       u8 radio_txmix2g_tune_boost_pu_core0;
2456 +       u8 radio_pad2g_tune_pus_core0;
2457 +       u8 radio_pga_boost_tune_core0;
2458 +       u8 radio_txmix5g_boost_tune_core0;
2459 +       u8 radio_pad5g_tune_misc_pus_core0;
2460 +       u8 radio_lna2g_tune_core0;
2461 +       u8 radio_lna5g_tune_core0;
2462 +       u8 radio_txmix2g_tune_boost_pu_core1;
2463 +       u8 radio_pad2g_tune_pus_core1;
2464 +       u8 radio_pga_boost_tune_core1;
2465 +       u8 radio_txmix5g_boost_tune_core1;
2466 +       u8 radio_pad5g_tune_misc_pus_core1;
2467 +       u8 radio_lna2g_tune_core1;
2468 +       u8 radio_lna5g_tune_core1;
2469 +       /* PHY res values on channelswitch */
2470 +       struct b43_phy_n_sfo_cfg phy_regs;
2471 +};
2472 +
2473 +struct b43_nphy_chantabent_rev7_2g {
2474 +       /* The channel frequency in MHz */
2475 +       u16 freq;
2476 +       /* Radio regs values on channelswitch */
2477 +       u8 radio_vcocal_countval0;
2478 +       u8 radio_vcocal_countval1;
2479 +       u8 radio_rfpll_refmaster_sparextalsize;
2480 +       u8 radio_rfpll_loopfilter_r1;
2481 +       u8 radio_rfpll_loopfilter_c2;
2482 +       u8 radio_rfpll_loopfilter_c1;
2483 +       u8 radio_cp_kpd_idac;
2484 +       u8 radio_rfpll_mmd0;
2485 +       u8 radio_rfpll_mmd1;
2486 +       u8 radio_vcobuf_tune;
2487 +       u8 radio_logen_mx2g_tune;
2488 +       u8 radio_logen_indbuf2g_tune;
2489 +       u8 radio_txmix2g_tune_boost_pu_core0;
2490 +       u8 radio_pad2g_tune_pus_core0;
2491 +       u8 radio_lna2g_tune_core0;
2492 +       u8 radio_txmix2g_tune_boost_pu_core1;
2493 +       u8 radio_pad2g_tune_pus_core1;
2494 +       u8 radio_lna2g_tune_core1;
2495 +       /* PHY regs values on channelswitch */
2496 +       struct b43_phy_n_sfo_cfg phy_regs;
2497 +};
2498 +
2499  void r2057_upload_inittabs(struct b43_wldev *dev);
2500  
2501 +void r2057_get_chantabent_rev7(struct b43_wldev *dev, u16 freq,
2502 +                              const struct b43_nphy_chantabent_rev7 **tabent_r7,
2503 +                              const struct b43_nphy_chantabent_rev7_2g **tabent_r7_2g);
2504 +
2505  #endif /* B43_RADIO_2057_H_ */
2506 --- a/drivers/net/wireless/b43/tables_nphy.h
2507 +++ b/drivers/net/wireless/b43/tables_nphy.h
2508 @@ -165,6 +165,10 @@ struct nphy_gain_ctl_workaround_entry *b
2509  #define B43_NTAB_C1_LOFEEDTH_R3                B43_NTAB16(27, 448) /* Local Oscillator Feed Through lookup 1 */
2510  #define B43_NTAB_C1_PAPD_COMP_R3       B43_NTAB16(27, 576)
2511  
2512 +/* Static N-PHY tables, PHY revision >= 7 */
2513 +#define B43_NTAB_TMAP_R7               B43_NTAB32(12,   0) /* TM AP */
2514 +#define B43_NTAB_NOISEVAR_R7           B43_NTAB32(16,   0) /* noise variance */
2515 +
2516  #define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_40_SIZE       18
2517  #define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_20_SIZE       18
2518  #define B43_NTAB_TX_IQLO_CAL_IQIMB_LADDER_40_SIZE      18