Merge branch 'for-linus2' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris...
[pandora-kernel.git] / drivers / net / wireless / b43 / phy_n.c
1 /*
2
3   Broadcom B43 wireless driver
4   IEEE 802.11n PHY support
5
6   Copyright (c) 2008 Michael Buesch <m@bues.ch>
7   Copyright (c) 2010-2011 Rafał Miłecki <zajec5@gmail.com>
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; either version 2 of the License, or
12   (at your option) any later version.
13
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18
19   You should have received a copy of the GNU General Public License
20   along with this program; see the file COPYING.  If not, write to
21   the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
22   Boston, MA 02110-1301, USA.
23
24 */
25
26 #include <linux/delay.h>
27 #include <linux/slab.h>
28 #include <linux/types.h>
29
30 #include "b43.h"
31 #include "phy_n.h"
32 #include "tables_nphy.h"
33 #include "radio_2055.h"
34 #include "radio_2056.h"
35 #include "radio_2057.h"
36 #include "main.h"
37
38 struct nphy_txgains {
39         u16 txgm[2];
40         u16 pga[2];
41         u16 pad[2];
42         u16 ipa[2];
43 };
44
45 struct nphy_iqcal_params {
46         u16 txgm;
47         u16 pga;
48         u16 pad;
49         u16 ipa;
50         u16 cal_gain;
51         u16 ncorr[5];
52 };
53
54 struct nphy_iq_est {
55         s32 iq0_prod;
56         u32 i0_pwr;
57         u32 q0_pwr;
58         s32 iq1_prod;
59         u32 i1_pwr;
60         u32 q1_pwr;
61 };
62
63 enum b43_nphy_rf_sequence {
64         B43_RFSEQ_RX2TX,
65         B43_RFSEQ_TX2RX,
66         B43_RFSEQ_RESET2RX,
67         B43_RFSEQ_UPDATE_GAINH,
68         B43_RFSEQ_UPDATE_GAINL,
69         B43_RFSEQ_UPDATE_GAINU,
70 };
71
72 enum n_intc_override {
73         N_INTC_OVERRIDE_OFF = 0,
74         N_INTC_OVERRIDE_TRSW = 1,
75         N_INTC_OVERRIDE_PA = 2,
76         N_INTC_OVERRIDE_EXT_LNA_PU = 3,
77         N_INTC_OVERRIDE_EXT_LNA_GAIN = 4,
78 };
79
80 enum n_rssi_type {
81         N_RSSI_W1 = 0,
82         N_RSSI_W2,
83         N_RSSI_NB,
84         N_RSSI_IQ,
85         N_RSSI_TSSI_2G,
86         N_RSSI_TSSI_5G,
87         N_RSSI_TBD,
88 };
89
90 enum n_rail_type {
91         N_RAIL_I = 0,
92         N_RAIL_Q = 1,
93 };
94
95 static inline bool b43_nphy_ipa(struct b43_wldev *dev)
96 {
97         enum ieee80211_band band = b43_current_band(dev->wl);
98         return ((dev->phy.n->ipa2g_on && band == IEEE80211_BAND_2GHZ) ||
99                 (dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ));
100 }
101
102 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCoreGetState */
103 static u8 b43_nphy_get_rx_core_state(struct b43_wldev *dev)
104 {
105         return (b43_phy_read(dev, B43_NPHY_RFSEQCA) & B43_NPHY_RFSEQCA_RXEN) >>
106                 B43_NPHY_RFSEQCA_RXEN_SHIFT;
107 }
108
109 /**************************************************
110  * RF (just without b43_nphy_rf_ctl_intc_override)
111  **************************************************/
112
113 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ForceRFSeq */
114 static void b43_nphy_force_rf_sequence(struct b43_wldev *dev,
115                                        enum b43_nphy_rf_sequence seq)
116 {
117         static const u16 trigger[] = {
118                 [B43_RFSEQ_RX2TX]               = B43_NPHY_RFSEQTR_RX2TX,
119                 [B43_RFSEQ_TX2RX]               = B43_NPHY_RFSEQTR_TX2RX,
120                 [B43_RFSEQ_RESET2RX]            = B43_NPHY_RFSEQTR_RST2RX,
121                 [B43_RFSEQ_UPDATE_GAINH]        = B43_NPHY_RFSEQTR_UPGH,
122                 [B43_RFSEQ_UPDATE_GAINL]        = B43_NPHY_RFSEQTR_UPGL,
123                 [B43_RFSEQ_UPDATE_GAINU]        = B43_NPHY_RFSEQTR_UPGU,
124         };
125         int i;
126         u16 seq_mode = b43_phy_read(dev, B43_NPHY_RFSEQMODE);
127
128         B43_WARN_ON(seq >= ARRAY_SIZE(trigger));
129
130         b43_phy_set(dev, B43_NPHY_RFSEQMODE,
131                     B43_NPHY_RFSEQMODE_CAOVER | B43_NPHY_RFSEQMODE_TROVER);
132         b43_phy_set(dev, B43_NPHY_RFSEQTR, trigger[seq]);
133         for (i = 0; i < 200; i++) {
134                 if (!(b43_phy_read(dev, B43_NPHY_RFSEQST) & trigger[seq]))
135                         goto ok;
136                 msleep(1);
137         }
138         b43err(dev->wl, "RF sequence status timeout\n");
139 ok:
140         b43_phy_write(dev, B43_NPHY_RFSEQMODE, seq_mode);
141 }
142
143 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverrideRev7 */
144 static void b43_nphy_rf_ctl_override_rev7(struct b43_wldev *dev, u16 field,
145                                           u16 value, u8 core, bool off,
146                                           u8 override)
147 {
148         const struct nphy_rf_control_override_rev7 *e;
149         u16 en_addrs[3][2] = {
150                 { 0x0E7, 0x0EC }, { 0x342, 0x343 }, { 0x346, 0x347 }
151         };
152         u16 en_addr;
153         u16 en_mask = field;
154         u16 val_addr;
155         u8 i;
156
157         /* Remember: we can get NULL! */
158         e = b43_nphy_get_rf_ctl_over_rev7(dev, field, override);
159
160         for (i = 0; i < 2; i++) {
161                 if (override >= ARRAY_SIZE(en_addrs)) {
162                         b43err(dev->wl, "Invalid override value %d\n", override);
163                         return;
164                 }
165                 en_addr = en_addrs[override][i];
166
167                 if (e)
168                         val_addr = (i == 0) ? e->val_addr_core0 : e->val_addr_core1;
169
170                 if (off) {
171                         b43_phy_mask(dev, en_addr, ~en_mask);
172                         if (e) /* Do it safer, better than wl */
173                                 b43_phy_mask(dev, val_addr, ~e->val_mask);
174                 } else {
175                         if (!core || (core & (1 << i))) {
176                                 b43_phy_set(dev, en_addr, en_mask);
177                                 if (e)
178                                         b43_phy_maskset(dev, val_addr, ~e->val_mask, (value << e->val_shift));
179                         }
180                 }
181         }
182 }
183
184 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverride */
185 static void b43_nphy_rf_ctl_override(struct b43_wldev *dev, u16 field,
186                                      u16 value, u8 core, bool off)
187 {
188         int i;
189         u8 index = fls(field);
190         u8 addr, en_addr, val_addr;
191         /* we expect only one bit set */
192         B43_WARN_ON(field & (~(1 << (index - 1))));
193
194         if (dev->phy.rev >= 3) {
195                 const struct nphy_rf_control_override_rev3 *rf_ctrl;
196                 for (i = 0; i < 2; i++) {
197                         if (index == 0 || index == 16) {
198                                 b43err(dev->wl,
199                                         "Unsupported RF Ctrl Override call\n");
200                                 return;
201                         }
202
203                         rf_ctrl = &tbl_rf_control_override_rev3[index - 1];
204                         en_addr = B43_PHY_N((i == 0) ?
205                                 rf_ctrl->en_addr0 : rf_ctrl->en_addr1);
206                         val_addr = B43_PHY_N((i == 0) ?
207                                 rf_ctrl->val_addr0 : rf_ctrl->val_addr1);
208
209                         if (off) {
210                                 b43_phy_mask(dev, en_addr, ~(field));
211                                 b43_phy_mask(dev, val_addr,
212                                                 ~(rf_ctrl->val_mask));
213                         } else {
214                                 if (core == 0 || ((1 << i) & core)) {
215                                         b43_phy_set(dev, en_addr, field);
216                                         b43_phy_maskset(dev, val_addr,
217                                                 ~(rf_ctrl->val_mask),
218                                                 (value << rf_ctrl->val_shift));
219                                 }
220                         }
221                 }
222         } else {
223                 const struct nphy_rf_control_override_rev2 *rf_ctrl;
224                 if (off) {
225                         b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, ~(field));
226                         value = 0;
227                 } else {
228                         b43_phy_set(dev, B43_NPHY_RFCTL_OVER, field);
229                 }
230
231                 for (i = 0; i < 2; i++) {
232                         if (index <= 1 || index == 16) {
233                                 b43err(dev->wl,
234                                         "Unsupported RF Ctrl Override call\n");
235                                 return;
236                         }
237
238                         if (index == 2 || index == 10 ||
239                             (index >= 13 && index <= 15)) {
240                                 core = 1;
241                         }
242
243                         rf_ctrl = &tbl_rf_control_override_rev2[index - 2];
244                         addr = B43_PHY_N((i == 0) ?
245                                 rf_ctrl->addr0 : rf_ctrl->addr1);
246
247                         if ((1 << i) & core)
248                                 b43_phy_maskset(dev, addr, ~(rf_ctrl->bmask),
249                                                 (value << rf_ctrl->shift));
250
251                         b43_phy_set(dev, B43_NPHY_RFCTL_OVER, 0x1);
252                         b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
253                                         B43_NPHY_RFCTL_CMD_START);
254                         udelay(1);
255                         b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, 0xFFFE);
256                 }
257         }
258 }
259
260 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlIntcOverride */
261 static void b43_nphy_rf_ctl_intc_override(struct b43_wldev *dev,
262                                           enum n_intc_override intc_override,
263                                           u16 value, u8 core)
264 {
265         u8 i, j;
266         u16 reg, tmp, val;
267
268         B43_WARN_ON(dev->phy.rev < 3);
269
270         for (i = 0; i < 2; i++) {
271                 if ((core == 1 && i == 1) || (core == 2 && !i))
272                         continue;
273
274                 reg = (i == 0) ?
275                         B43_NPHY_RFCTL_INTC1 : B43_NPHY_RFCTL_INTC2;
276                 b43_phy_set(dev, reg, 0x400);
277
278                 switch (intc_override) {
279                 case N_INTC_OVERRIDE_OFF:
280                         b43_phy_write(dev, reg, 0);
281                         b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
282                         break;
283                 case N_INTC_OVERRIDE_TRSW:
284                         if (!i) {
285                                 b43_phy_maskset(dev, B43_NPHY_RFCTL_INTC1,
286                                                 0xFC3F, (value << 6));
287                                 b43_phy_maskset(dev, B43_NPHY_TXF_40CO_B1S1,
288                                                 0xFFFE, 1);
289                                 b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
290                                                 B43_NPHY_RFCTL_CMD_START);
291                                 for (j = 0; j < 100; j++) {
292                                         if (!(b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_START)) {
293                                                 j = 0;
294                                                 break;
295                                         }
296                                         udelay(10);
297                                 }
298                                 if (j)
299                                         b43err(dev->wl,
300                                                 "intc override timeout\n");
301                                 b43_phy_mask(dev, B43_NPHY_TXF_40CO_B1S1,
302                                                 0xFFFE);
303                         } else {
304                                 b43_phy_maskset(dev, B43_NPHY_RFCTL_INTC2,
305                                                 0xFC3F, (value << 6));
306                                 b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER,
307                                                 0xFFFE, 1);
308                                 b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
309                                                 B43_NPHY_RFCTL_CMD_RXTX);
310                                 for (j = 0; j < 100; j++) {
311                                         if (!(b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_RXTX)) {
312                                                 j = 0;
313                                                 break;
314                                         }
315                                         udelay(10);
316                                 }
317                                 if (j)
318                                         b43err(dev->wl,
319                                                 "intc override timeout\n");
320                                 b43_phy_mask(dev, B43_NPHY_RFCTL_OVER,
321                                                 0xFFFE);
322                         }
323                         break;
324                 case N_INTC_OVERRIDE_PA:
325                         if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
326                                 tmp = 0x0020;
327                                 val = value << 5;
328                         } else {
329                                 tmp = 0x0010;
330                                 val = value << 4;
331                         }
332                         b43_phy_maskset(dev, reg, ~tmp, val);
333                         break;
334                 case N_INTC_OVERRIDE_EXT_LNA_PU:
335                         if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
336                                 tmp = 0x0001;
337                                 val = value;
338                         } else {
339                                 tmp = 0x0004;
340                                 val = value << 2;
341                         }
342                         b43_phy_maskset(dev, reg, ~tmp, val);
343                         break;
344                 case N_INTC_OVERRIDE_EXT_LNA_GAIN:
345                         if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
346                                 tmp = 0x0002;
347                                 val = value << 1;
348                         } else {
349                                 tmp = 0x0008;
350                                 val = value << 3;
351                         }
352                         b43_phy_maskset(dev, reg, ~tmp, val);
353                         break;
354                 }
355         }
356 }
357
358 /**************************************************
359  * Various PHY ops
360  **************************************************/
361
362 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/clip-detection */
363 static void b43_nphy_write_clip_detection(struct b43_wldev *dev,
364                                           const u16 *clip_st)
365 {
366         b43_phy_write(dev, B43_NPHY_C1_CLIP1THRES, clip_st[0]);
367         b43_phy_write(dev, B43_NPHY_C2_CLIP1THRES, clip_st[1]);
368 }
369
370 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/clip-detection */
371 static void b43_nphy_read_clip_detection(struct b43_wldev *dev, u16 *clip_st)
372 {
373         clip_st[0] = b43_phy_read(dev, B43_NPHY_C1_CLIP1THRES);
374         clip_st[1] = b43_phy_read(dev, B43_NPHY_C2_CLIP1THRES);
375 }
376
377 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/classifier */
378 static u16 b43_nphy_classifier(struct b43_wldev *dev, u16 mask, u16 val)
379 {
380         u16 tmp;
381
382         if (dev->dev->core_rev == 16)
383                 b43_mac_suspend(dev);
384
385         tmp = b43_phy_read(dev, B43_NPHY_CLASSCTL);
386         tmp &= (B43_NPHY_CLASSCTL_CCKEN | B43_NPHY_CLASSCTL_OFDMEN |
387                 B43_NPHY_CLASSCTL_WAITEDEN);
388         tmp &= ~mask;
389         tmp |= (val & mask);
390         b43_phy_maskset(dev, B43_NPHY_CLASSCTL, 0xFFF8, tmp);
391
392         if (dev->dev->core_rev == 16)
393                 b43_mac_enable(dev);
394
395         return tmp;
396 }
397
398 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CCA */
399 static void b43_nphy_reset_cca(struct b43_wldev *dev)
400 {
401         u16 bbcfg;
402
403         b43_phy_force_clock(dev, 1);
404         bbcfg = b43_phy_read(dev, B43_NPHY_BBCFG);
405         b43_phy_write(dev, B43_NPHY_BBCFG, bbcfg | B43_NPHY_BBCFG_RSTCCA);
406         udelay(1);
407         b43_phy_write(dev, B43_NPHY_BBCFG, bbcfg & ~B43_NPHY_BBCFG_RSTCCA);
408         b43_phy_force_clock(dev, 0);
409         b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
410 }
411
412 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/carriersearch */
413 static void b43_nphy_stay_in_carrier_search(struct b43_wldev *dev, bool enable)
414 {
415         struct b43_phy *phy = &dev->phy;
416         struct b43_phy_n *nphy = phy->n;
417
418         if (enable) {
419                 static const u16 clip[] = { 0xFFFF, 0xFFFF };
420                 if (nphy->deaf_count++ == 0) {
421                         nphy->classifier_state = b43_nphy_classifier(dev, 0, 0);
422                         b43_nphy_classifier(dev, 0x7, 0);
423                         b43_nphy_read_clip_detection(dev, nphy->clip_state);
424                         b43_nphy_write_clip_detection(dev, clip);
425                 }
426                 b43_nphy_reset_cca(dev);
427         } else {
428                 if (--nphy->deaf_count == 0) {
429                         b43_nphy_classifier(dev, 0x7, nphy->classifier_state);
430                         b43_nphy_write_clip_detection(dev, nphy->clip_state);
431                 }
432         }
433 }
434
435 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/AdjustLnaGainTbl */
436 static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev)
437 {
438         struct b43_phy_n *nphy = dev->phy.n;
439
440         u8 i;
441         s16 tmp;
442         u16 data[4];
443         s16 gain[2];
444         u16 minmax[2];
445         static const u16 lna_gain[4] = { -2, 10, 19, 25 };
446
447         if (nphy->hang_avoid)
448                 b43_nphy_stay_in_carrier_search(dev, 1);
449
450         if (nphy->gain_boost) {
451                 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
452                         gain[0] = 6;
453                         gain[1] = 6;
454                 } else {
455                         tmp = 40370 - 315 * dev->phy.channel;
456                         gain[0] = ((tmp >> 13) + ((tmp >> 12) & 1));
457                         tmp = 23242 - 224 * dev->phy.channel;
458                         gain[1] = ((tmp >> 13) + ((tmp >> 12) & 1));
459                 }
460         } else {
461                 gain[0] = 0;
462                 gain[1] = 0;
463         }
464
465         for (i = 0; i < 2; i++) {
466                 if (nphy->elna_gain_config) {
467                         data[0] = 19 + gain[i];
468                         data[1] = 25 + gain[i];
469                         data[2] = 25 + gain[i];
470                         data[3] = 25 + gain[i];
471                 } else {
472                         data[0] = lna_gain[0] + gain[i];
473                         data[1] = lna_gain[1] + gain[i];
474                         data[2] = lna_gain[2] + gain[i];
475                         data[3] = lna_gain[3] + gain[i];
476                 }
477                 b43_ntab_write_bulk(dev, B43_NTAB16(i, 8), 4, data);
478
479                 minmax[i] = 23 + gain[i];
480         }
481
482         b43_phy_maskset(dev, B43_NPHY_C1_MINMAX_GAIN, ~B43_NPHY_C1_MINGAIN,
483                                 minmax[0] << B43_NPHY_C1_MINGAIN_SHIFT);
484         b43_phy_maskset(dev, B43_NPHY_C2_MINMAX_GAIN, ~B43_NPHY_C2_MINGAIN,
485                                 minmax[1] << B43_NPHY_C2_MINGAIN_SHIFT);
486
487         if (nphy->hang_avoid)
488                 b43_nphy_stay_in_carrier_search(dev, 0);
489 }
490
491 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetRfSeq */
492 static void b43_nphy_set_rf_sequence(struct b43_wldev *dev, u8 cmd,
493                                         u8 *events, u8 *delays, u8 length)
494 {
495         struct b43_phy_n *nphy = dev->phy.n;
496         u8 i;
497         u8 end = (dev->phy.rev >= 3) ? 0x1F : 0x0F;
498         u16 offset1 = cmd << 4;
499         u16 offset2 = offset1 + 0x80;
500
501         if (nphy->hang_avoid)
502                 b43_nphy_stay_in_carrier_search(dev, true);
503
504         b43_ntab_write_bulk(dev, B43_NTAB8(7, offset1), length, events);
505         b43_ntab_write_bulk(dev, B43_NTAB8(7, offset2), length, delays);
506
507         for (i = length; i < 16; i++) {
508                 b43_ntab_write(dev, B43_NTAB8(7, offset1 + i), end);
509                 b43_ntab_write(dev, B43_NTAB8(7, offset2 + i), 1);
510         }
511
512         if (nphy->hang_avoid)
513                 b43_nphy_stay_in_carrier_search(dev, false);
514 }
515
516 /**************************************************
517  * Radio 0x2057
518  **************************************************/
519
520 /* http://bcm-v4.sipsolutions.net/PHY/radio2057_rcal */
521 static u8 b43_radio_2057_rcal(struct b43_wldev *dev)
522 {
523         struct b43_phy *phy = &dev->phy;
524         u16 tmp;
525
526         if (phy->radio_rev == 5) {
527                 b43_phy_mask(dev, 0x342, ~0x2);
528                 udelay(10);
529                 b43_radio_set(dev, R2057_IQTEST_SEL_PU, 0x1);
530                 b43_radio_maskset(dev, 0x1ca, ~0x2, 0x1);
531         }
532
533         b43_radio_set(dev, R2057_RCAL_CONFIG, 0x1);
534         udelay(10);
535         b43_radio_set(dev, R2057_RCAL_CONFIG, 0x3);
536         if (!b43_radio_wait_value(dev, R2057_RCCAL_N1_1, 1, 1, 100, 1000000)) {
537                 b43err(dev->wl, "Radio 0x2057 rcal timeout\n");
538                 return 0;
539         }
540         b43_radio_mask(dev, R2057_RCAL_CONFIG, ~0x2);
541         tmp = b43_radio_read(dev, R2057_RCAL_STATUS) & 0x3E;
542         b43_radio_mask(dev, R2057_RCAL_CONFIG, ~0x1);
543
544         if (phy->radio_rev == 5) {
545                 b43_radio_mask(dev, R2057_IPA2G_CASCONV_CORE0, ~0x1);
546                 b43_radio_mask(dev, 0x1ca, ~0x2);
547         }
548         if (phy->radio_rev <= 4 || phy->radio_rev == 6) {
549                 b43_radio_maskset(dev, R2057_TEMPSENSE_CONFIG, ~0x3C, tmp);
550                 b43_radio_maskset(dev, R2057_BANDGAP_RCAL_TRIM, ~0xF0,
551                                   tmp << 2);
552         }
553
554         return tmp & 0x3e;
555 }
556
557 /* http://bcm-v4.sipsolutions.net/PHY/radio2057_rccal */
558 static u16 b43_radio_2057_rccal(struct b43_wldev *dev)
559 {
560         struct b43_phy *phy = &dev->phy;
561         bool special = (phy->radio_rev == 3 || phy->radio_rev == 4 ||
562                         phy->radio_rev == 6);
563         u16 tmp;
564
565         if (special) {
566                 b43_radio_write(dev, R2057_RCCAL_MASTER, 0x61);
567                 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xC0);
568         } else {
569                 b43_radio_write(dev, 0x1AE, 0x61);
570                 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xE1);
571         }
572         b43_radio_write(dev, R2057_RCCAL_X1, 0x6E);
573         b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x55);
574         if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 1, 1, 500,
575                                   5000000))
576                 b43dbg(dev->wl, "Radio 0x2057 rccal timeout\n");
577         b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x15);
578         if (special) {
579                 b43_radio_write(dev, R2057_RCCAL_MASTER, 0x69);
580                 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xB0);
581         } else {
582                 b43_radio_write(dev, 0x1AE, 0x69);
583                 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xD5);
584         }
585         b43_radio_write(dev, R2057_RCCAL_X1, 0x6E);
586         b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x55);
587         if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 1, 1, 500,
588                                   5000000))
589                 b43dbg(dev->wl, "Radio 0x2057 rccal timeout\n");
590         b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x15);
591         if (special) {
592                 b43_radio_write(dev, R2057_RCCAL_MASTER, 0x73);
593                 b43_radio_write(dev, R2057_RCCAL_X1, 0x28);
594                 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xB0);
595         } else {
596                 b43_radio_write(dev, 0x1AE, 0x73);
597                 b43_radio_write(dev, R2057_RCCAL_X1, 0x6E);
598                 b43_radio_write(dev, R2057_RCCAL_TRC0, 0x99);
599         }
600         b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x55);
601         if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 1, 1, 500,
602                                   5000000)) {
603                 b43err(dev->wl, "Radio 0x2057 rcal timeout\n");
604                 return 0;
605         }
606         tmp = b43_radio_read(dev, R2057_RCCAL_DONE_OSCCAP);
607         b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x15);
608         return tmp;
609 }
610
611 static void b43_radio_2057_init_pre(struct b43_wldev *dev)
612 {
613         b43_phy_mask(dev, B43_NPHY_RFCTL_CMD, ~B43_NPHY_RFCTL_CMD_CHIP0PU);
614         /* Maybe wl meant to reset and set (order?) RFCTL_CMD_OEPORFORCE? */
615         b43_phy_mask(dev, B43_NPHY_RFCTL_CMD, B43_NPHY_RFCTL_CMD_OEPORFORCE);
616         b43_phy_set(dev, B43_NPHY_RFCTL_CMD, ~B43_NPHY_RFCTL_CMD_OEPORFORCE);
617         b43_phy_set(dev, B43_NPHY_RFCTL_CMD, B43_NPHY_RFCTL_CMD_CHIP0PU);
618 }
619
620 static void b43_radio_2057_init_post(struct b43_wldev *dev)
621 {
622         b43_radio_set(dev, R2057_XTALPUOVR_PINCTRL, 0x1);
623
624         b43_radio_set(dev, R2057_RFPLL_MISC_CAL_RESETN, 0x78);
625         b43_radio_set(dev, R2057_XTAL_CONFIG2, 0x80);
626         mdelay(2);
627         b43_radio_mask(dev, R2057_RFPLL_MISC_CAL_RESETN, ~0x78);
628         b43_radio_mask(dev, R2057_XTAL_CONFIG2, ~0x80);
629
630         if (dev->phy.n->init_por) {
631                 b43_radio_2057_rcal(dev);
632                 b43_radio_2057_rccal(dev);
633         }
634         b43_radio_mask(dev, R2057_RFPLL_MASTER, ~0x8);
635
636         dev->phy.n->init_por = false;
637 }
638
639 /* http://bcm-v4.sipsolutions.net/802.11/Radio/2057/Init */
640 static void b43_radio_2057_init(struct b43_wldev *dev)
641 {
642         b43_radio_2057_init_pre(dev);
643         r2057_upload_inittabs(dev);
644         b43_radio_2057_init_post(dev);
645 }
646
647 /**************************************************
648  * Radio 0x2056
649  **************************************************/
650
651 static void b43_chantab_radio_2056_upload(struct b43_wldev *dev,
652                                 const struct b43_nphy_channeltab_entry_rev3 *e)
653 {
654         b43_radio_write(dev, B2056_SYN_PLL_VCOCAL1, e->radio_syn_pll_vcocal1);
655         b43_radio_write(dev, B2056_SYN_PLL_VCOCAL2, e->radio_syn_pll_vcocal2);
656         b43_radio_write(dev, B2056_SYN_PLL_REFDIV, e->radio_syn_pll_refdiv);
657         b43_radio_write(dev, B2056_SYN_PLL_MMD2, e->radio_syn_pll_mmd2);
658         b43_radio_write(dev, B2056_SYN_PLL_MMD1, e->radio_syn_pll_mmd1);
659         b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER1,
660                                         e->radio_syn_pll_loopfilter1);
661         b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER2,
662                                         e->radio_syn_pll_loopfilter2);
663         b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER3,
664                                         e->radio_syn_pll_loopfilter3);
665         b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER4,
666                                         e->radio_syn_pll_loopfilter4);
667         b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER5,
668                                         e->radio_syn_pll_loopfilter5);
669         b43_radio_write(dev, B2056_SYN_RESERVED_ADDR27,
670                                         e->radio_syn_reserved_addr27);
671         b43_radio_write(dev, B2056_SYN_RESERVED_ADDR28,
672                                         e->radio_syn_reserved_addr28);
673         b43_radio_write(dev, B2056_SYN_RESERVED_ADDR29,
674                                         e->radio_syn_reserved_addr29);
675         b43_radio_write(dev, B2056_SYN_LOGEN_VCOBUF1,
676                                         e->radio_syn_logen_vcobuf1);
677         b43_radio_write(dev, B2056_SYN_LOGEN_MIXER2, e->radio_syn_logen_mixer2);
678         b43_radio_write(dev, B2056_SYN_LOGEN_BUF3, e->radio_syn_logen_buf3);
679         b43_radio_write(dev, B2056_SYN_LOGEN_BUF4, e->radio_syn_logen_buf4);
680
681         b43_radio_write(dev, B2056_RX0 | B2056_RX_LNAA_TUNE,
682                                         e->radio_rx0_lnaa_tune);
683         b43_radio_write(dev, B2056_RX0 | B2056_RX_LNAG_TUNE,
684                                         e->radio_rx0_lnag_tune);
685
686         b43_radio_write(dev, B2056_TX0 | B2056_TX_INTPAA_BOOST_TUNE,
687                                         e->radio_tx0_intpaa_boost_tune);
688         b43_radio_write(dev, B2056_TX0 | B2056_TX_INTPAG_BOOST_TUNE,
689                                         e->radio_tx0_intpag_boost_tune);
690         b43_radio_write(dev, B2056_TX0 | B2056_TX_PADA_BOOST_TUNE,
691                                         e->radio_tx0_pada_boost_tune);
692         b43_radio_write(dev, B2056_TX0 | B2056_TX_PADG_BOOST_TUNE,
693                                         e->radio_tx0_padg_boost_tune);
694         b43_radio_write(dev, B2056_TX0 | B2056_TX_PGAA_BOOST_TUNE,
695                                         e->radio_tx0_pgaa_boost_tune);
696         b43_radio_write(dev, B2056_TX0 | B2056_TX_PGAG_BOOST_TUNE,
697                                         e->radio_tx0_pgag_boost_tune);
698         b43_radio_write(dev, B2056_TX0 | B2056_TX_MIXA_BOOST_TUNE,
699                                         e->radio_tx0_mixa_boost_tune);
700         b43_radio_write(dev, B2056_TX0 | B2056_TX_MIXG_BOOST_TUNE,
701                                         e->radio_tx0_mixg_boost_tune);
702
703         b43_radio_write(dev, B2056_RX1 | B2056_RX_LNAA_TUNE,
704                                         e->radio_rx1_lnaa_tune);
705         b43_radio_write(dev, B2056_RX1 | B2056_RX_LNAG_TUNE,
706                                         e->radio_rx1_lnag_tune);
707
708         b43_radio_write(dev, B2056_TX1 | B2056_TX_INTPAA_BOOST_TUNE,
709                                         e->radio_tx1_intpaa_boost_tune);
710         b43_radio_write(dev, B2056_TX1 | B2056_TX_INTPAG_BOOST_TUNE,
711                                         e->radio_tx1_intpag_boost_tune);
712         b43_radio_write(dev, B2056_TX1 | B2056_TX_PADA_BOOST_TUNE,
713                                         e->radio_tx1_pada_boost_tune);
714         b43_radio_write(dev, B2056_TX1 | B2056_TX_PADG_BOOST_TUNE,
715                                         e->radio_tx1_padg_boost_tune);
716         b43_radio_write(dev, B2056_TX1 | B2056_TX_PGAA_BOOST_TUNE,
717                                         e->radio_tx1_pgaa_boost_tune);
718         b43_radio_write(dev, B2056_TX1 | B2056_TX_PGAG_BOOST_TUNE,
719                                         e->radio_tx1_pgag_boost_tune);
720         b43_radio_write(dev, B2056_TX1 | B2056_TX_MIXA_BOOST_TUNE,
721                                         e->radio_tx1_mixa_boost_tune);
722         b43_radio_write(dev, B2056_TX1 | B2056_TX_MIXG_BOOST_TUNE,
723                                         e->radio_tx1_mixg_boost_tune);
724 }
725
726 /* http://bcm-v4.sipsolutions.net/802.11/PHY/Radio/2056Setup */
727 static void b43_radio_2056_setup(struct b43_wldev *dev,
728                                 const struct b43_nphy_channeltab_entry_rev3 *e)
729 {
730         struct ssb_sprom *sprom = dev->dev->bus_sprom;
731         enum ieee80211_band band = b43_current_band(dev->wl);
732         u16 offset;
733         u8 i;
734         u16 bias, cbias;
735         u16 pag_boost, padg_boost, pgag_boost, mixg_boost;
736         u16 paa_boost, pada_boost, pgaa_boost, mixa_boost;
737
738         B43_WARN_ON(dev->phy.rev < 3);
739
740         b43_chantab_radio_2056_upload(dev, e);
741         b2056_upload_syn_pll_cp2(dev, band == IEEE80211_BAND_5GHZ);
742
743         if (sprom->boardflags2_lo & B43_BFL2_GPLL_WAR &&
744             b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
745                 b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER1, 0x1F);
746                 b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER2, 0x1F);
747                 if (dev->dev->chip_id == 0x4716) {
748                         b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER4, 0x14);
749                         b43_radio_write(dev, B2056_SYN_PLL_CP2, 0);
750                 } else {
751                         b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER4, 0x0B);
752                         b43_radio_write(dev, B2056_SYN_PLL_CP2, 0x14);
753                 }
754         }
755         if (sprom->boardflags2_lo & B43_BFL2_APLL_WAR &&
756             b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
757                 b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER1, 0x1F);
758                 b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER2, 0x1F);
759                 b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER4, 0x05);
760                 b43_radio_write(dev, B2056_SYN_PLL_CP2, 0x0C);
761         }
762
763         if (dev->phy.n->ipa2g_on && band == IEEE80211_BAND_2GHZ) {
764                 for (i = 0; i < 2; i++) {
765                         offset = i ? B2056_TX1 : B2056_TX0;
766                         if (dev->phy.rev >= 5) {
767                                 b43_radio_write(dev,
768                                         offset | B2056_TX_PADG_IDAC, 0xcc);
769
770                                 if (dev->dev->chip_id == 0x4716) {
771                                         bias = 0x40;
772                                         cbias = 0x45;
773                                         pag_boost = 0x5;
774                                         pgag_boost = 0x33;
775                                         mixg_boost = 0x55;
776                                 } else {
777                                         bias = 0x25;
778                                         cbias = 0x20;
779                                         pag_boost = 0x4;
780                                         pgag_boost = 0x03;
781                                         mixg_boost = 0x65;
782                                 }
783                                 padg_boost = 0x77;
784
785                                 b43_radio_write(dev,
786                                         offset | B2056_TX_INTPAG_IMAIN_STAT,
787                                         bias);
788                                 b43_radio_write(dev,
789                                         offset | B2056_TX_INTPAG_IAUX_STAT,
790                                         bias);
791                                 b43_radio_write(dev,
792                                         offset | B2056_TX_INTPAG_CASCBIAS,
793                                         cbias);
794                                 b43_radio_write(dev,
795                                         offset | B2056_TX_INTPAG_BOOST_TUNE,
796                                         pag_boost);
797                                 b43_radio_write(dev,
798                                         offset | B2056_TX_PGAG_BOOST_TUNE,
799                                         pgag_boost);
800                                 b43_radio_write(dev,
801                                         offset | B2056_TX_PADG_BOOST_TUNE,
802                                         padg_boost);
803                                 b43_radio_write(dev,
804                                         offset | B2056_TX_MIXG_BOOST_TUNE,
805                                         mixg_boost);
806                         } else {
807                                 bias = dev->phy.is_40mhz ? 0x40 : 0x20;
808                                 b43_radio_write(dev,
809                                         offset | B2056_TX_INTPAG_IMAIN_STAT,
810                                         bias);
811                                 b43_radio_write(dev,
812                                         offset | B2056_TX_INTPAG_IAUX_STAT,
813                                         bias);
814                                 b43_radio_write(dev,
815                                         offset | B2056_TX_INTPAG_CASCBIAS,
816                                         0x30);
817                         }
818                         b43_radio_write(dev, offset | B2056_TX_PA_SPARE1, 0xee);
819                 }
820         } else if (dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ) {
821                 u16 freq = dev->phy.channel_freq;
822                 if (freq < 5100) {
823                         paa_boost = 0xA;
824                         pada_boost = 0x77;
825                         pgaa_boost = 0xF;
826                         mixa_boost = 0xF;
827                 } else if (freq < 5340) {
828                         paa_boost = 0x8;
829                         pada_boost = 0x77;
830                         pgaa_boost = 0xFB;
831                         mixa_boost = 0xF;
832                 } else if (freq < 5650) {
833                         paa_boost = 0x0;
834                         pada_boost = 0x77;
835                         pgaa_boost = 0xB;
836                         mixa_boost = 0xF;
837                 } else {
838                         paa_boost = 0x0;
839                         pada_boost = 0x77;
840                         if (freq != 5825)
841                                 pgaa_boost = -(freq - 18) / 36 + 168;
842                         else
843                                 pgaa_boost = 6;
844                         mixa_boost = 0xF;
845                 }
846
847                 for (i = 0; i < 2; i++) {
848                         offset = i ? B2056_TX1 : B2056_TX0;
849
850                         b43_radio_write(dev,
851                                 offset | B2056_TX_INTPAA_BOOST_TUNE, paa_boost);
852                         b43_radio_write(dev,
853                                 offset | B2056_TX_PADA_BOOST_TUNE, pada_boost);
854                         b43_radio_write(dev,
855                                 offset | B2056_TX_PGAA_BOOST_TUNE, pgaa_boost);
856                         b43_radio_write(dev,
857                                 offset | B2056_TX_MIXA_BOOST_TUNE, mixa_boost);
858                         b43_radio_write(dev,
859                                 offset | B2056_TX_TXSPARE1, 0x30);
860                         b43_radio_write(dev,
861                                 offset | B2056_TX_PA_SPARE2, 0xee);
862                         b43_radio_write(dev,
863                                 offset | B2056_TX_PADA_CASCBIAS, 0x03);
864                         b43_radio_write(dev,
865                                 offset | B2056_TX_INTPAA_IAUX_STAT, 0x50);
866                         b43_radio_write(dev,
867                                 offset | B2056_TX_INTPAA_IMAIN_STAT, 0x50);
868                         b43_radio_write(dev,
869                                 offset | B2056_TX_INTPAA_CASCBIAS, 0x30);
870                 }
871         }
872
873         udelay(50);
874         /* VCO calibration */
875         b43_radio_write(dev, B2056_SYN_PLL_VCOCAL12, 0x00);
876         b43_radio_write(dev, B2056_TX_INTPAA_PA_MISC, 0x38);
877         b43_radio_write(dev, B2056_TX_INTPAA_PA_MISC, 0x18);
878         b43_radio_write(dev, B2056_TX_INTPAA_PA_MISC, 0x38);
879         b43_radio_write(dev, B2056_TX_INTPAA_PA_MISC, 0x39);
880         udelay(300);
881 }
882
883 static u8 b43_radio_2056_rcal(struct b43_wldev *dev)
884 {
885         struct b43_phy *phy = &dev->phy;
886         u16 mast2, tmp;
887
888         if (phy->rev != 3)
889                 return 0;
890
891         mast2 = b43_radio_read(dev, B2056_SYN_PLL_MAST2);
892         b43_radio_write(dev, B2056_SYN_PLL_MAST2, mast2 | 0x7);
893
894         udelay(10);
895         b43_radio_write(dev, B2056_SYN_RCAL_MASTER, 0x01);
896         udelay(10);
897         b43_radio_write(dev, B2056_SYN_RCAL_MASTER, 0x09);
898
899         if (!b43_radio_wait_value(dev, B2056_SYN_RCAL_CODE_OUT, 0x80, 0x80, 100,
900                                   1000000)) {
901                 b43err(dev->wl, "Radio recalibration timeout\n");
902                 return 0;
903         }
904
905         b43_radio_write(dev, B2056_SYN_RCAL_MASTER, 0x01);
906         tmp = b43_radio_read(dev, B2056_SYN_RCAL_CODE_OUT);
907         b43_radio_write(dev, B2056_SYN_RCAL_MASTER, 0x00);
908
909         b43_radio_write(dev, B2056_SYN_PLL_MAST2, mast2);
910
911         return tmp & 0x1f;
912 }
913
914 static void b43_radio_init2056_pre(struct b43_wldev *dev)
915 {
916         b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
917                      ~B43_NPHY_RFCTL_CMD_CHIP0PU);
918         /* Maybe wl meant to reset and set (order?) RFCTL_CMD_OEPORFORCE? */
919         b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
920                      B43_NPHY_RFCTL_CMD_OEPORFORCE);
921         b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
922                     ~B43_NPHY_RFCTL_CMD_OEPORFORCE);
923         b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
924                     B43_NPHY_RFCTL_CMD_CHIP0PU);
925 }
926
927 static void b43_radio_init2056_post(struct b43_wldev *dev)
928 {
929         b43_radio_set(dev, B2056_SYN_COM_CTRL, 0xB);
930         b43_radio_set(dev, B2056_SYN_COM_PU, 0x2);
931         b43_radio_set(dev, B2056_SYN_COM_RESET, 0x2);
932         msleep(1);
933         b43_radio_mask(dev, B2056_SYN_COM_RESET, ~0x2);
934         b43_radio_mask(dev, B2056_SYN_PLL_MAST2, ~0xFC);
935         b43_radio_mask(dev, B2056_SYN_RCCAL_CTRL0, ~0x1);
936         if (dev->phy.n->init_por)
937                 b43_radio_2056_rcal(dev);
938 }
939
940 /*
941  * Initialize a Broadcom 2056 N-radio
942  * http://bcm-v4.sipsolutions.net/802.11/Radio/2056/Init
943  */
944 static void b43_radio_init2056(struct b43_wldev *dev)
945 {
946         b43_radio_init2056_pre(dev);
947         b2056_upload_inittabs(dev, 0, 0);
948         b43_radio_init2056_post(dev);
949
950         dev->phy.n->init_por = false;
951 }
952
953 /**************************************************
954  * Radio 0x2055
955  **************************************************/
956
957 static void b43_chantab_radio_upload(struct b43_wldev *dev,
958                                 const struct b43_nphy_channeltab_entry_rev2 *e)
959 {
960         b43_radio_write(dev, B2055_PLL_REF, e->radio_pll_ref);
961         b43_radio_write(dev, B2055_RF_PLLMOD0, e->radio_rf_pllmod0);
962         b43_radio_write(dev, B2055_RF_PLLMOD1, e->radio_rf_pllmod1);
963         b43_radio_write(dev, B2055_VCO_CAPTAIL, e->radio_vco_captail);
964         b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */
965
966         b43_radio_write(dev, B2055_VCO_CAL1, e->radio_vco_cal1);
967         b43_radio_write(dev, B2055_VCO_CAL2, e->radio_vco_cal2);
968         b43_radio_write(dev, B2055_PLL_LFC1, e->radio_pll_lfc1);
969         b43_radio_write(dev, B2055_PLL_LFR1, e->radio_pll_lfr1);
970         b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */
971
972         b43_radio_write(dev, B2055_PLL_LFC2, e->radio_pll_lfc2);
973         b43_radio_write(dev, B2055_LGBUF_CENBUF, e->radio_lgbuf_cenbuf);
974         b43_radio_write(dev, B2055_LGEN_TUNE1, e->radio_lgen_tune1);
975         b43_radio_write(dev, B2055_LGEN_TUNE2, e->radio_lgen_tune2);
976         b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */
977
978         b43_radio_write(dev, B2055_C1_LGBUF_ATUNE, e->radio_c1_lgbuf_atune);
979         b43_radio_write(dev, B2055_C1_LGBUF_GTUNE, e->radio_c1_lgbuf_gtune);
980         b43_radio_write(dev, B2055_C1_RX_RFR1, e->radio_c1_rx_rfr1);
981         b43_radio_write(dev, B2055_C1_TX_PGAPADTN, e->radio_c1_tx_pgapadtn);
982         b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */
983
984         b43_radio_write(dev, B2055_C1_TX_MXBGTRIM, e->radio_c1_tx_mxbgtrim);
985         b43_radio_write(dev, B2055_C2_LGBUF_ATUNE, e->radio_c2_lgbuf_atune);
986         b43_radio_write(dev, B2055_C2_LGBUF_GTUNE, e->radio_c2_lgbuf_gtune);
987         b43_radio_write(dev, B2055_C2_RX_RFR1, e->radio_c2_rx_rfr1);
988         b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */
989
990         b43_radio_write(dev, B2055_C2_TX_PGAPADTN, e->radio_c2_tx_pgapadtn);
991         b43_radio_write(dev, B2055_C2_TX_MXBGTRIM, e->radio_c2_tx_mxbgtrim);
992 }
993
994 /* http://bcm-v4.sipsolutions.net/802.11/PHY/Radio/2055Setup */
995 static void b43_radio_2055_setup(struct b43_wldev *dev,
996                                 const struct b43_nphy_channeltab_entry_rev2 *e)
997 {
998         B43_WARN_ON(dev->phy.rev >= 3);
999
1000         b43_chantab_radio_upload(dev, e);
1001         udelay(50);
1002         b43_radio_write(dev, B2055_VCO_CAL10, 0x05);
1003         b43_radio_write(dev, B2055_VCO_CAL10, 0x45);
1004         b43_read32(dev, B43_MMIO_MACCTL); /* flush writes */
1005         b43_radio_write(dev, B2055_VCO_CAL10, 0x65);
1006         udelay(300);
1007 }
1008
1009 static void b43_radio_init2055_pre(struct b43_wldev *dev)
1010 {
1011         b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
1012                      ~B43_NPHY_RFCTL_CMD_PORFORCE);
1013         b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
1014                     B43_NPHY_RFCTL_CMD_CHIP0PU |
1015                     B43_NPHY_RFCTL_CMD_OEPORFORCE);
1016         b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
1017                     B43_NPHY_RFCTL_CMD_PORFORCE);
1018 }
1019
1020 static void b43_radio_init2055_post(struct b43_wldev *dev)
1021 {
1022         struct b43_phy_n *nphy = dev->phy.n;
1023         struct ssb_sprom *sprom = dev->dev->bus_sprom;
1024         bool workaround = false;
1025
1026         if (sprom->revision < 4)
1027                 workaround = (dev->dev->board_vendor != PCI_VENDOR_ID_BROADCOM
1028                               && dev->dev->board_type == SSB_BOARD_CB2_4321
1029                               && dev->dev->board_rev >= 0x41);
1030         else
1031                 workaround =
1032                         !(sprom->boardflags2_lo & B43_BFL2_RXBB_INT_REG_DIS);
1033
1034         b43_radio_mask(dev, B2055_MASTER1, 0xFFF3);
1035         if (workaround) {
1036                 b43_radio_mask(dev, B2055_C1_RX_BB_REG, 0x7F);
1037                 b43_radio_mask(dev, B2055_C2_RX_BB_REG, 0x7F);
1038         }
1039         b43_radio_maskset(dev, B2055_RRCCAL_NOPTSEL, 0xFFC0, 0x2C);
1040         b43_radio_write(dev, B2055_CAL_MISC, 0x3C);
1041         b43_radio_mask(dev, B2055_CAL_MISC, 0xFFBE);
1042         b43_radio_set(dev, B2055_CAL_LPOCTL, 0x80);
1043         b43_radio_set(dev, B2055_CAL_MISC, 0x1);
1044         msleep(1);
1045         b43_radio_set(dev, B2055_CAL_MISC, 0x40);
1046         if (!b43_radio_wait_value(dev, B2055_CAL_COUT2, 0x80, 0x80, 10, 2000))
1047                 b43err(dev->wl, "radio post init timeout\n");
1048         b43_radio_mask(dev, B2055_CAL_LPOCTL, 0xFF7F);
1049         b43_switch_channel(dev, dev->phy.channel);
1050         b43_radio_write(dev, B2055_C1_RX_BB_LPF, 0x9);
1051         b43_radio_write(dev, B2055_C2_RX_BB_LPF, 0x9);
1052         b43_radio_write(dev, B2055_C1_RX_BB_MIDACHP, 0x83);
1053         b43_radio_write(dev, B2055_C2_RX_BB_MIDACHP, 0x83);
1054         b43_radio_maskset(dev, B2055_C1_LNA_GAINBST, 0xFFF8, 0x6);
1055         b43_radio_maskset(dev, B2055_C2_LNA_GAINBST, 0xFFF8, 0x6);
1056         if (!nphy->gain_boost) {
1057                 b43_radio_set(dev, B2055_C1_RX_RFSPC1, 0x2);
1058                 b43_radio_set(dev, B2055_C2_RX_RFSPC1, 0x2);
1059         } else {
1060                 b43_radio_mask(dev, B2055_C1_RX_RFSPC1, 0xFFFD);
1061                 b43_radio_mask(dev, B2055_C2_RX_RFSPC1, 0xFFFD);
1062         }
1063         udelay(2);
1064 }
1065
1066 /*
1067  * Initialize a Broadcom 2055 N-radio
1068  * http://bcm-v4.sipsolutions.net/802.11/Radio/2055/Init
1069  */
1070 static void b43_radio_init2055(struct b43_wldev *dev)
1071 {
1072         b43_radio_init2055_pre(dev);
1073         if (b43_status(dev) < B43_STAT_INITIALIZED) {
1074                 /* Follow wl, not specs. Do not force uploading all regs */
1075                 b2055_upload_inittab(dev, 0, 0);
1076         } else {
1077                 bool ghz5 = b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ;
1078                 b2055_upload_inittab(dev, ghz5, 0);
1079         }
1080         b43_radio_init2055_post(dev);
1081 }
1082
1083 /**************************************************
1084  * Samples
1085  **************************************************/
1086
1087 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/LoadSampleTable */
1088 static int b43_nphy_load_samples(struct b43_wldev *dev,
1089                                         struct b43_c32 *samples, u16 len) {
1090         struct b43_phy_n *nphy = dev->phy.n;
1091         u16 i;
1092         u32 *data;
1093
1094         data = kzalloc(len * sizeof(u32), GFP_KERNEL);
1095         if (!data) {
1096                 b43err(dev->wl, "allocation for samples loading failed\n");
1097                 return -ENOMEM;
1098         }
1099         if (nphy->hang_avoid)
1100                 b43_nphy_stay_in_carrier_search(dev, 1);
1101
1102         for (i = 0; i < len; i++) {
1103                 data[i] = (samples[i].i & 0x3FF << 10);
1104                 data[i] |= samples[i].q & 0x3FF;
1105         }
1106         b43_ntab_write_bulk(dev, B43_NTAB32(17, 0), len, data);
1107
1108         kfree(data);
1109         if (nphy->hang_avoid)
1110                 b43_nphy_stay_in_carrier_search(dev, 0);
1111         return 0;
1112 }
1113
1114 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GenLoadSamples */
1115 static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max,
1116                                         bool test)
1117 {
1118         int i;
1119         u16 bw, len, rot, angle;
1120         struct b43_c32 *samples;
1121
1122
1123         bw = (dev->phy.is_40mhz) ? 40 : 20;
1124         len = bw << 3;
1125
1126         if (test) {
1127                 if (b43_phy_read(dev, B43_NPHY_BBCFG) & B43_NPHY_BBCFG_RSTRX)
1128                         bw = 82;
1129                 else
1130                         bw = 80;
1131
1132                 if (dev->phy.is_40mhz)
1133                         bw <<= 1;
1134
1135                 len = bw << 1;
1136         }
1137
1138         samples = kcalloc(len, sizeof(struct b43_c32), GFP_KERNEL);
1139         if (!samples) {
1140                 b43err(dev->wl, "allocation for samples generation failed\n");
1141                 return 0;
1142         }
1143         rot = (((freq * 36) / bw) << 16) / 100;
1144         angle = 0;
1145
1146         for (i = 0; i < len; i++) {
1147                 samples[i] = b43_cordic(angle);
1148                 angle += rot;
1149                 samples[i].q = CORDIC_CONVERT(samples[i].q * max);
1150                 samples[i].i = CORDIC_CONVERT(samples[i].i * max);
1151         }
1152
1153         i = b43_nphy_load_samples(dev, samples, len);
1154         kfree(samples);
1155         return (i < 0) ? 0 : len;
1156 }
1157
1158 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RunSamples */
1159 static void b43_nphy_run_samples(struct b43_wldev *dev, u16 samps, u16 loops,
1160                                         u16 wait, bool iqmode, bool dac_test)
1161 {
1162         struct b43_phy_n *nphy = dev->phy.n;
1163         int i;
1164         u16 seq_mode;
1165         u32 tmp;
1166
1167         if (nphy->hang_avoid)
1168                 b43_nphy_stay_in_carrier_search(dev, true);
1169
1170         if ((nphy->bb_mult_save & 0x80000000) == 0) {
1171                 tmp = b43_ntab_read(dev, B43_NTAB16(15, 87));
1172                 nphy->bb_mult_save = (tmp & 0xFFFF) | 0x80000000;
1173         }
1174
1175         if (!dev->phy.is_40mhz)
1176                 tmp = 0x6464;
1177         else
1178                 tmp = 0x4747;
1179         b43_ntab_write(dev, B43_NTAB16(15, 87), tmp);
1180
1181         if (nphy->hang_avoid)
1182                 b43_nphy_stay_in_carrier_search(dev, false);
1183
1184         b43_phy_write(dev, B43_NPHY_SAMP_DEPCNT, (samps - 1));
1185
1186         if (loops != 0xFFFF)
1187                 b43_phy_write(dev, B43_NPHY_SAMP_LOOPCNT, (loops - 1));
1188         else
1189                 b43_phy_write(dev, B43_NPHY_SAMP_LOOPCNT, loops);
1190
1191         b43_phy_write(dev, B43_NPHY_SAMP_WAITCNT, wait);
1192
1193         seq_mode = b43_phy_read(dev, B43_NPHY_RFSEQMODE);
1194
1195         b43_phy_set(dev, B43_NPHY_RFSEQMODE, B43_NPHY_RFSEQMODE_CAOVER);
1196         if (iqmode) {
1197                 b43_phy_mask(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x7FFF);
1198                 b43_phy_set(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8000);
1199         } else {
1200                 if (dac_test)
1201                         b43_phy_write(dev, B43_NPHY_SAMP_CMD, 5);
1202                 else
1203                         b43_phy_write(dev, B43_NPHY_SAMP_CMD, 1);
1204         }
1205         for (i = 0; i < 100; i++) {
1206                 if (!(b43_phy_read(dev, B43_NPHY_RFSEQST) & 1)) {
1207                         i = 0;
1208                         break;
1209                 }
1210                 udelay(10);
1211         }
1212         if (i)
1213                 b43err(dev->wl, "run samples timeout\n");
1214
1215         b43_phy_write(dev, B43_NPHY_RFSEQMODE, seq_mode);
1216 }
1217
1218 /**************************************************
1219  * RSSI
1220  **************************************************/
1221
1222 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ScaleOffsetRssi */
1223 static void b43_nphy_scale_offset_rssi(struct b43_wldev *dev, u16 scale,
1224                                         s8 offset, u8 core,
1225                                         enum n_rail_type rail,
1226                                         enum n_rssi_type rssi_type)
1227 {
1228         u16 tmp;
1229         bool core1or5 = (core == 1) || (core == 5);
1230         bool core2or5 = (core == 2) || (core == 5);
1231
1232         offset = clamp_val(offset, -32, 31);
1233         tmp = ((scale & 0x3F) << 8) | (offset & 0x3F);
1234
1235         switch (rssi_type) {
1236         case N_RSSI_NB:
1237                 if (core1or5 && rail == N_RAIL_I)
1238                         b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Z, tmp);
1239                 if (core1or5 && rail == N_RAIL_Q)
1240                         b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Z, tmp);
1241                 if (core2or5 && rail == N_RAIL_I)
1242                         b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Z, tmp);
1243                 if (core2or5 && rail == N_RAIL_Q)
1244                         b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Z, tmp);
1245                 break;
1246         case N_RSSI_W1:
1247                 if (core1or5 && rail == N_RAIL_I)
1248                         b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_X, tmp);
1249                 if (core1or5 && rail == N_RAIL_Q)
1250                         b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_X, tmp);
1251                 if (core2or5 && rail == N_RAIL_I)
1252                         b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_X, tmp);
1253                 if (core2or5 && rail == N_RAIL_Q)
1254                         b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_X, tmp);
1255                 break;
1256         case N_RSSI_W2:
1257                 if (core1or5 && rail == N_RAIL_I)
1258                         b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Y, tmp);
1259                 if (core1or5 && rail == N_RAIL_Q)
1260                         b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Y, tmp);
1261                 if (core2or5 && rail == N_RAIL_I)
1262                         b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Y, tmp);
1263                 if (core2or5 && rail == N_RAIL_Q)
1264                         b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Y, tmp);
1265                 break;
1266         case N_RSSI_TBD:
1267                 if (core1or5 && rail == N_RAIL_I)
1268                         b43_phy_write(dev, B43_NPHY_RSSIMC_0I_TBD, tmp);
1269                 if (core1or5 && rail == N_RAIL_Q)
1270                         b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_TBD, tmp);
1271                 if (core2or5 && rail == N_RAIL_I)
1272                         b43_phy_write(dev, B43_NPHY_RSSIMC_1I_TBD, tmp);
1273                 if (core2or5 && rail == N_RAIL_Q)
1274                         b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TBD, tmp);
1275                 break;
1276         case N_RSSI_IQ:
1277                 if (core1or5 && rail == N_RAIL_I)
1278                         b43_phy_write(dev, B43_NPHY_RSSIMC_0I_PWRDET, tmp);
1279                 if (core1or5 && rail == N_RAIL_Q)
1280                         b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_PWRDET, tmp);
1281                 if (core2or5 && rail == N_RAIL_I)
1282                         b43_phy_write(dev, B43_NPHY_RSSIMC_1I_PWRDET, tmp);
1283                 if (core2or5 && rail == N_RAIL_Q)
1284                         b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_PWRDET, tmp);
1285                 break;
1286         case N_RSSI_TSSI_2G:
1287                 if (core1or5)
1288                         b43_phy_write(dev, B43_NPHY_RSSIMC_0I_TSSI, tmp);
1289                 if (core2or5)
1290                         b43_phy_write(dev, B43_NPHY_RSSIMC_1I_TSSI, tmp);
1291                 break;
1292         case N_RSSI_TSSI_5G:
1293                 if (core1or5)
1294                         b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_TSSI, tmp);
1295                 if (core2or5)
1296                         b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TSSI, tmp);
1297                 break;
1298         }
1299 }
1300
1301 static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code,
1302                                       enum n_rssi_type rssi_type)
1303 {
1304         u8 i;
1305         u16 reg, val;
1306
1307         if (code == 0) {
1308                 b43_phy_mask(dev, B43_NPHY_AFECTL_OVER1, 0xFDFF);
1309                 b43_phy_mask(dev, B43_NPHY_AFECTL_OVER, 0xFDFF);
1310                 b43_phy_mask(dev, B43_NPHY_AFECTL_C1, 0xFCFF);
1311                 b43_phy_mask(dev, B43_NPHY_AFECTL_C2, 0xFCFF);
1312                 b43_phy_mask(dev, B43_NPHY_TXF_40CO_B1S0, 0xFFDF);
1313                 b43_phy_mask(dev, B43_NPHY_TXF_40CO_B32S1, 0xFFDF);
1314                 b43_phy_mask(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0xFFC3);
1315                 b43_phy_mask(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0xFFC3);
1316         } else {
1317                 for (i = 0; i < 2; i++) {
1318                         if ((code == 1 && i == 1) || (code == 2 && !i))
1319                                 continue;
1320
1321                         reg = (i == 0) ?
1322                                 B43_NPHY_AFECTL_OVER1 : B43_NPHY_AFECTL_OVER;
1323                         b43_phy_maskset(dev, reg, 0xFDFF, 0x0200);
1324
1325                         if (rssi_type == N_RSSI_W1 ||
1326                             rssi_type == N_RSSI_W2 ||
1327                             rssi_type == N_RSSI_NB) {
1328                                 reg = (i == 0) ?
1329                                         B43_NPHY_AFECTL_C1 :
1330                                         B43_NPHY_AFECTL_C2;
1331                                 b43_phy_maskset(dev, reg, 0xFCFF, 0);
1332
1333                                 reg = (i == 0) ?
1334                                         B43_NPHY_RFCTL_LUT_TRSW_UP1 :
1335                                         B43_NPHY_RFCTL_LUT_TRSW_UP2;
1336                                 b43_phy_maskset(dev, reg, 0xFFC3, 0);
1337
1338                                 if (rssi_type == N_RSSI_W1)
1339                                         val = (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ? 4 : 8;
1340                                 else if (rssi_type == N_RSSI_W2)
1341                                         val = 16;
1342                                 else
1343                                         val = 32;
1344                                 b43_phy_set(dev, reg, val);
1345
1346                                 reg = (i == 0) ?
1347                                         B43_NPHY_TXF_40CO_B1S0 :
1348                                         B43_NPHY_TXF_40CO_B32S1;
1349                                 b43_phy_set(dev, reg, 0x0020);
1350                         } else {
1351                                 if (rssi_type == N_RSSI_TBD)
1352                                         val = 0x0100;
1353                                 else if (rssi_type == N_RSSI_IQ)
1354                                         val = 0x0200;
1355                                 else
1356                                         val = 0x0300;
1357
1358                                 reg = (i == 0) ?
1359                                         B43_NPHY_AFECTL_C1 :
1360                                         B43_NPHY_AFECTL_C2;
1361
1362                                 b43_phy_maskset(dev, reg, 0xFCFF, val);
1363                                 b43_phy_maskset(dev, reg, 0xF3FF, val << 2);
1364
1365                                 if (rssi_type != N_RSSI_IQ &&
1366                                     rssi_type != N_RSSI_TBD) {
1367                                         enum ieee80211_band band =
1368                                                 b43_current_band(dev->wl);
1369
1370                                         if (b43_nphy_ipa(dev))
1371                                                 val = (band == IEEE80211_BAND_5GHZ) ? 0xC : 0xE;
1372                                         else
1373                                                 val = 0x11;
1374                                         reg = (i == 0) ? 0x2000 : 0x3000;
1375                                         reg |= B2055_PADDRV;
1376                                         b43_radio_write(dev, reg, val);
1377
1378                                         reg = (i == 0) ?
1379                                                 B43_NPHY_AFECTL_OVER1 :
1380                                                 B43_NPHY_AFECTL_OVER;
1381                                         b43_phy_set(dev, reg, 0x0200);
1382                                 }
1383                         }
1384                 }
1385         }
1386 }
1387
1388 static void b43_nphy_rev2_rssi_select(struct b43_wldev *dev, u8 code,
1389                                       enum n_rssi_type rssi_type)
1390 {
1391         u16 val;
1392         bool rssi_w1_w2_nb = false;
1393
1394         switch (rssi_type) {
1395         case N_RSSI_W1:
1396         case N_RSSI_W2:
1397         case N_RSSI_NB:
1398                 val = 0;
1399                 rssi_w1_w2_nb = true;
1400                 break;
1401         case N_RSSI_TBD:
1402                 val = 1;
1403                 break;
1404         case N_RSSI_IQ:
1405                 val = 2;
1406                 break;
1407         default:
1408                 val = 3;
1409         }
1410
1411         val = (val << 12) | (val << 14);
1412         b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, val);
1413         b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, val);
1414
1415         if (rssi_w1_w2_nb) {
1416                 b43_phy_maskset(dev, B43_NPHY_RFCTL_RSSIO1, 0xFFCF,
1417                                 (rssi_type + 1) << 4);
1418                 b43_phy_maskset(dev, B43_NPHY_RFCTL_RSSIO2, 0xFFCF,
1419                                 (rssi_type + 1) << 4);
1420         }
1421
1422         if (code == 0) {
1423                 b43_phy_mask(dev, B43_NPHY_AFECTL_OVER, ~0x3000);
1424                 if (rssi_w1_w2_nb) {
1425                         b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
1426                                 ~(B43_NPHY_RFCTL_CMD_RXEN |
1427                                   B43_NPHY_RFCTL_CMD_CORESEL));
1428                         b43_phy_mask(dev, B43_NPHY_RFCTL_OVER,
1429                                 ~(0x1 << 12 |
1430                                   0x1 << 5 |
1431                                   0x1 << 1 |
1432                                   0x1));
1433                         b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
1434                                 ~B43_NPHY_RFCTL_CMD_START);
1435                         udelay(20);
1436                         b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, ~0x1);
1437                 }
1438         } else {
1439                 b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x3000);
1440                 if (rssi_w1_w2_nb) {
1441                         b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD,
1442                                 ~(B43_NPHY_RFCTL_CMD_RXEN |
1443                                   B43_NPHY_RFCTL_CMD_CORESEL),
1444                                 (B43_NPHY_RFCTL_CMD_RXEN |
1445                                  code << B43_NPHY_RFCTL_CMD_CORESEL_SHIFT));
1446                         b43_phy_set(dev, B43_NPHY_RFCTL_OVER,
1447                                 (0x1 << 12 |
1448                                   0x1 << 5 |
1449                                   0x1 << 1 |
1450                                   0x1));
1451                         b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
1452                                 B43_NPHY_RFCTL_CMD_START);
1453                         udelay(20);
1454                         b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, ~0x1);
1455                 }
1456         }
1457 }
1458
1459 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSISel */
1460 static void b43_nphy_rssi_select(struct b43_wldev *dev, u8 code,
1461                                  enum n_rssi_type type)
1462 {
1463         if (dev->phy.rev >= 3)
1464                 b43_nphy_rev3_rssi_select(dev, code, type);
1465         else
1466                 b43_nphy_rev2_rssi_select(dev, code, type);
1467 }
1468
1469 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetRssi2055Vcm */
1470 static void b43_nphy_set_rssi_2055_vcm(struct b43_wldev *dev,
1471                                        enum n_rssi_type rssi_type, u8 *buf)
1472 {
1473         int i;
1474         for (i = 0; i < 2; i++) {
1475                 if (rssi_type == N_RSSI_NB) {
1476                         if (i == 0) {
1477                                 b43_radio_maskset(dev, B2055_C1_B0NB_RSSIVCM,
1478                                                   0xFC, buf[0]);
1479                                 b43_radio_maskset(dev, B2055_C1_RX_BB_RSSICTL5,
1480                                                   0xFC, buf[1]);
1481                         } else {
1482                                 b43_radio_maskset(dev, B2055_C2_B0NB_RSSIVCM,
1483                                                   0xFC, buf[2 * i]);
1484                                 b43_radio_maskset(dev, B2055_C2_RX_BB_RSSICTL5,
1485                                                   0xFC, buf[2 * i + 1]);
1486                         }
1487                 } else {
1488                         if (i == 0)
1489                                 b43_radio_maskset(dev, B2055_C1_RX_BB_RSSICTL5,
1490                                                   0xF3, buf[0] << 2);
1491                         else
1492                                 b43_radio_maskset(dev, B2055_C2_RX_BB_RSSICTL5,
1493                                                   0xF3, buf[2 * i + 1] << 2);
1494                 }
1495         }
1496 }
1497
1498 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/PollRssi */
1499 static int b43_nphy_poll_rssi(struct b43_wldev *dev, enum n_rssi_type rssi_type,
1500                               s32 *buf, u8 nsamp)
1501 {
1502         int i;
1503         int out;
1504         u16 save_regs_phy[9];
1505         u16 s[2];
1506
1507         if (dev->phy.rev >= 3) {
1508                 save_regs_phy[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
1509                 save_regs_phy[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
1510                 save_regs_phy[2] = b43_phy_read(dev,
1511                                                 B43_NPHY_RFCTL_LUT_TRSW_UP1);
1512                 save_regs_phy[3] = b43_phy_read(dev,
1513                                                 B43_NPHY_RFCTL_LUT_TRSW_UP2);
1514                 save_regs_phy[4] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER1);
1515                 save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
1516                 save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S0);
1517                 save_regs_phy[7] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B32S1);
1518                 save_regs_phy[8] = 0;
1519         } else {
1520                 save_regs_phy[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
1521                 save_regs_phy[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
1522                 save_regs_phy[2] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
1523                 save_regs_phy[3] = b43_phy_read(dev, B43_NPHY_RFCTL_CMD);
1524                 save_regs_phy[4] = b43_phy_read(dev, B43_NPHY_RFCTL_OVER);
1525                 save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO1);
1526                 save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO2);
1527                 save_regs_phy[7] = 0;
1528                 save_regs_phy[8] = 0;
1529         }
1530
1531         b43_nphy_rssi_select(dev, 5, rssi_type);
1532
1533         if (dev->phy.rev < 2) {
1534                 save_regs_phy[8] = b43_phy_read(dev, B43_NPHY_GPIO_SEL);
1535                 b43_phy_write(dev, B43_NPHY_GPIO_SEL, 5);
1536         }
1537
1538         for (i = 0; i < 4; i++)
1539                 buf[i] = 0;
1540
1541         for (i = 0; i < nsamp; i++) {
1542                 if (dev->phy.rev < 2) {
1543                         s[0] = b43_phy_read(dev, B43_NPHY_GPIO_LOOUT);
1544                         s[1] = b43_phy_read(dev, B43_NPHY_GPIO_HIOUT);
1545                 } else {
1546                         s[0] = b43_phy_read(dev, B43_NPHY_RSSI1);
1547                         s[1] = b43_phy_read(dev, B43_NPHY_RSSI2);
1548                 }
1549
1550                 buf[0] += ((s8)((s[0] & 0x3F) << 2)) >> 2;
1551                 buf[1] += ((s8)(((s[0] >> 8) & 0x3F) << 2)) >> 2;
1552                 buf[2] += ((s8)((s[1] & 0x3F) << 2)) >> 2;
1553                 buf[3] += ((s8)(((s[1] >> 8) & 0x3F) << 2)) >> 2;
1554         }
1555         out = (buf[0] & 0xFF) << 24 | (buf[1] & 0xFF) << 16 |
1556                 (buf[2] & 0xFF) << 8 | (buf[3] & 0xFF);
1557
1558         if (dev->phy.rev < 2)
1559                 b43_phy_write(dev, B43_NPHY_GPIO_SEL, save_regs_phy[8]);
1560
1561         if (dev->phy.rev >= 3) {
1562                 b43_phy_write(dev, B43_NPHY_AFECTL_C1, save_regs_phy[0]);
1563                 b43_phy_write(dev, B43_NPHY_AFECTL_C2, save_regs_phy[1]);
1564                 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1,
1565                                 save_regs_phy[2]);
1566                 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2,
1567                                 save_regs_phy[3]);
1568                 b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, save_regs_phy[4]);
1569                 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[5]);
1570                 b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S0, save_regs_phy[6]);
1571                 b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S1, save_regs_phy[7]);
1572         } else {
1573                 b43_phy_write(dev, B43_NPHY_AFECTL_C1, save_regs_phy[0]);
1574                 b43_phy_write(dev, B43_NPHY_AFECTL_C2, save_regs_phy[1]);
1575                 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[2]);
1576                 b43_phy_write(dev, B43_NPHY_RFCTL_CMD, save_regs_phy[3]);
1577                 b43_phy_write(dev, B43_NPHY_RFCTL_OVER, save_regs_phy[4]);
1578                 b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO1, save_regs_phy[5]);
1579                 b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO2, save_regs_phy[6]);
1580         }
1581
1582         return out;
1583 }
1584
1585 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */
1586 static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
1587 {
1588         struct b43_phy_n *nphy = dev->phy.n;
1589
1590         u16 saved_regs_phy_rfctl[2];
1591         u16 saved_regs_phy[13];
1592         u16 regs_to_store[] = {
1593                 B43_NPHY_AFECTL_OVER1, B43_NPHY_AFECTL_OVER,
1594                 B43_NPHY_AFECTL_C1, B43_NPHY_AFECTL_C2,
1595                 B43_NPHY_TXF_40CO_B1S1, B43_NPHY_RFCTL_OVER,
1596                 B43_NPHY_TXF_40CO_B1S0, B43_NPHY_TXF_40CO_B32S1,
1597                 B43_NPHY_RFCTL_CMD,
1598                 B43_NPHY_RFCTL_LUT_TRSW_UP1, B43_NPHY_RFCTL_LUT_TRSW_UP2,
1599                 B43_NPHY_RFCTL_RSSIO1, B43_NPHY_RFCTL_RSSIO2
1600         };
1601
1602         u16 class;
1603
1604         u16 clip_state[2];
1605         u16 clip_off[2] = { 0xFFFF, 0xFFFF };
1606
1607         u8 vcm_final = 0;
1608         s32 offset[4];
1609         s32 results[8][4] = { };
1610         s32 results_min[4] = { };
1611         s32 poll_results[4] = { };
1612
1613         u16 *rssical_radio_regs = NULL;
1614         u16 *rssical_phy_regs = NULL;
1615
1616         u16 r; /* routing */
1617         u8 rx_core_state;
1618         int core, i, j, vcm;
1619
1620         class = b43_nphy_classifier(dev, 0, 0);
1621         b43_nphy_classifier(dev, 7, 4);
1622         b43_nphy_read_clip_detection(dev, clip_state);
1623         b43_nphy_write_clip_detection(dev, clip_off);
1624
1625         saved_regs_phy_rfctl[0] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
1626         saved_regs_phy_rfctl[1] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
1627         for (i = 0; i < ARRAY_SIZE(regs_to_store); i++)
1628                 saved_regs_phy[i] = b43_phy_read(dev, regs_to_store[i]);
1629
1630         b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_OFF, 0, 7);
1631         b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_TRSW, 1, 7);
1632         b43_nphy_rf_ctl_override(dev, 0x1, 0, 0, false);
1633         b43_nphy_rf_ctl_override(dev, 0x2, 1, 0, false);
1634         b43_nphy_rf_ctl_override(dev, 0x80, 1, 0, false);
1635         b43_nphy_rf_ctl_override(dev, 0x40, 1, 0, false);
1636
1637         if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
1638                 b43_nphy_rf_ctl_override(dev, 0x20, 0, 0, false);
1639                 b43_nphy_rf_ctl_override(dev, 0x10, 1, 0, false);
1640         } else {
1641                 b43_nphy_rf_ctl_override(dev, 0x10, 0, 0, false);
1642                 b43_nphy_rf_ctl_override(dev, 0x20, 1, 0, false);
1643         }
1644
1645         rx_core_state = b43_nphy_get_rx_core_state(dev);
1646         for (core = 0; core < 2; core++) {
1647                 if (!(rx_core_state & (1 << core)))
1648                         continue;
1649                 r = core ? B2056_RX1 : B2056_RX0;
1650                 b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, N_RAIL_I,
1651                                            N_RSSI_NB);
1652                 b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, N_RAIL_Q,
1653                                            N_RSSI_NB);
1654
1655                 /* Grab RSSI results for every possible VCM */
1656                 for (vcm = 0; vcm < 8; vcm++) {
1657                         b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC, 0xE3,
1658                                         vcm << 2);
1659                         b43_nphy_poll_rssi(dev, N_RSSI_NB, results[vcm], 8);
1660                 }
1661
1662                 /* Find out which VCM got the best results */
1663                 for (i = 0; i < 4; i += 2) {
1664                         s32 currd;
1665                         s32 mind = 0x100000;
1666                         s32 minpoll = 249;
1667                         u8 minvcm = 0;
1668                         if (2 * core != i)
1669                                 continue;
1670                         for (vcm = 0; vcm < 8; vcm++) {
1671                                 currd = results[vcm][i] * results[vcm][i] +
1672                                         results[vcm][i + 1] * results[vcm][i];
1673                                 if (currd < mind) {
1674                                         mind = currd;
1675                                         minvcm = vcm;
1676                                 }
1677                                 if (results[vcm][i] < minpoll)
1678                                         minpoll = results[vcm][i];
1679                         }
1680                         vcm_final = minvcm;
1681                         results_min[i] = minpoll;
1682                 }
1683
1684                 /* Select the best VCM */
1685                 b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC, 0xE3,
1686                                   vcm_final << 2);
1687
1688                 for (i = 0; i < 4; i++) {
1689                         if (core != i / 2)
1690                                 continue;
1691                         offset[i] = -results[vcm_final][i];
1692                         if (offset[i] < 0)
1693                                 offset[i] = -((abs(offset[i]) + 4) / 8);
1694                         else
1695                                 offset[i] = (offset[i] + 4) / 8;
1696                         if (results_min[i] == 248)
1697                                 offset[i] = -32;
1698                         b43_nphy_scale_offset_rssi(dev, 0, offset[i],
1699                                                    (i / 2 == 0) ? 1 : 2,
1700                                                    (i % 2 == 0) ? N_RAIL_I : N_RAIL_Q,
1701                                                    N_RSSI_NB);
1702                 }
1703         }
1704
1705         for (core = 0; core < 2; core++) {
1706                 if (!(rx_core_state & (1 << core)))
1707                         continue;
1708                 for (i = 0; i < 2; i++) {
1709                         b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1,
1710                                                    N_RAIL_I, i);
1711                         b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1,
1712                                                    N_RAIL_Q, i);
1713                         b43_nphy_poll_rssi(dev, i, poll_results, 8);
1714                         for (j = 0; j < 4; j++) {
1715                                 if (j / 2 == core) {
1716                                         offset[j] = 232 - poll_results[j];
1717                                         if (offset[j] < 0)
1718                                                 offset[j] = -(abs(offset[j] + 4) / 8);
1719                                         else
1720                                                 offset[j] = (offset[j] + 4) / 8;
1721                                         b43_nphy_scale_offset_rssi(dev, 0,
1722                                                 offset[2 * core], core + 1, j % 2, i);
1723                                 }
1724                         }
1725                 }
1726         }
1727
1728         b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, saved_regs_phy_rfctl[0]);
1729         b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, saved_regs_phy_rfctl[1]);
1730
1731         b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
1732
1733         b43_phy_set(dev, B43_NPHY_TXF_40CO_B1S1, 0x1);
1734         b43_phy_set(dev, B43_NPHY_RFCTL_CMD, B43_NPHY_RFCTL_CMD_START);
1735         b43_phy_mask(dev, B43_NPHY_TXF_40CO_B1S1, ~0x1);
1736
1737         b43_phy_set(dev, B43_NPHY_RFCTL_OVER, 0x1);
1738         b43_phy_set(dev, B43_NPHY_RFCTL_CMD, B43_NPHY_RFCTL_CMD_RXTX);
1739         b43_phy_mask(dev, B43_NPHY_TXF_40CO_B1S1, ~0x1);
1740
1741         for (i = 0; i < ARRAY_SIZE(regs_to_store); i++)
1742                 b43_phy_write(dev, regs_to_store[i], saved_regs_phy[i]);
1743
1744         /* Store for future configuration */
1745         if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
1746                 rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_2G;
1747                 rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_2G;
1748         } else {
1749                 rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_5G;
1750                 rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G;
1751         }
1752         if (dev->phy.rev >= 7) {
1753         } else {
1754                 rssical_radio_regs[0] = b43_radio_read(dev, B2056_RX0 |
1755                                                        B2056_RX_RSSI_MISC);
1756                 rssical_radio_regs[1] = b43_radio_read(dev, B2056_RX1 |
1757                                                        B2056_RX_RSSI_MISC);
1758         }
1759         rssical_phy_regs[0] = b43_phy_read(dev, B43_NPHY_RSSIMC_0I_RSSI_Z);
1760         rssical_phy_regs[1] = b43_phy_read(dev, B43_NPHY_RSSIMC_0Q_RSSI_Z);
1761         rssical_phy_regs[2] = b43_phy_read(dev, B43_NPHY_RSSIMC_1I_RSSI_Z);
1762         rssical_phy_regs[3] = b43_phy_read(dev, B43_NPHY_RSSIMC_1Q_RSSI_Z);
1763         rssical_phy_regs[4] = b43_phy_read(dev, B43_NPHY_RSSIMC_0I_RSSI_X);
1764         rssical_phy_regs[5] = b43_phy_read(dev, B43_NPHY_RSSIMC_0Q_RSSI_X);
1765         rssical_phy_regs[6] = b43_phy_read(dev, B43_NPHY_RSSIMC_1I_RSSI_X);
1766         rssical_phy_regs[7] = b43_phy_read(dev, B43_NPHY_RSSIMC_1Q_RSSI_X);
1767         rssical_phy_regs[8] = b43_phy_read(dev, B43_NPHY_RSSIMC_0I_RSSI_Y);
1768         rssical_phy_regs[9] = b43_phy_read(dev, B43_NPHY_RSSIMC_0Q_RSSI_Y);
1769         rssical_phy_regs[10] = b43_phy_read(dev, B43_NPHY_RSSIMC_1I_RSSI_Y);
1770         rssical_phy_regs[11] = b43_phy_read(dev, B43_NPHY_RSSIMC_1Q_RSSI_Y);
1771
1772         /* Remember for which channel we store configuration */
1773         if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
1774                 nphy->rssical_chanspec_2G.center_freq = dev->phy.channel_freq;
1775         else
1776                 nphy->rssical_chanspec_5G.center_freq = dev->phy.channel_freq;
1777
1778         /* End of calibration, restore configuration */
1779         b43_nphy_classifier(dev, 7, class);
1780         b43_nphy_write_clip_detection(dev, clip_state);
1781 }
1782
1783 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal */
1784 static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, enum n_rssi_type type)
1785 {
1786         int i, j, vcm;
1787         u8 state[4];
1788         u8 code, val;
1789         u16 class, override;
1790         u8 regs_save_radio[2];
1791         u16 regs_save_phy[2];
1792
1793         s32 offset[4];
1794         u8 core;
1795         u8 rail;
1796
1797         u16 clip_state[2];
1798         u16 clip_off[2] = { 0xFFFF, 0xFFFF };
1799         s32 results_min[4] = { };
1800         u8 vcm_final[4] = { };
1801         s32 results[4][4] = { };
1802         s32 miniq[4][2] = { };
1803
1804         if (type == N_RSSI_NB) {
1805                 code = 0;
1806                 val = 6;
1807         } else if (type == N_RSSI_W1 || type == N_RSSI_W2) {
1808                 code = 25;
1809                 val = 4;
1810         } else {
1811                 B43_WARN_ON(1);
1812                 return;
1813         }
1814
1815         class = b43_nphy_classifier(dev, 0, 0);
1816         b43_nphy_classifier(dev, 7, 4);
1817         b43_nphy_read_clip_detection(dev, clip_state);
1818         b43_nphy_write_clip_detection(dev, clip_off);
1819
1820         if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
1821                 override = 0x140;
1822         else
1823                 override = 0x110;
1824
1825         regs_save_phy[0] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
1826         regs_save_radio[0] = b43_radio_read(dev, B2055_C1_PD_RXTX);
1827         b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, override);
1828         b43_radio_write(dev, B2055_C1_PD_RXTX, val);
1829
1830         regs_save_phy[1] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
1831         regs_save_radio[1] = b43_radio_read(dev, B2055_C2_PD_RXTX);
1832         b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, override);
1833         b43_radio_write(dev, B2055_C2_PD_RXTX, val);
1834
1835         state[0] = b43_radio_read(dev, B2055_C1_PD_RSSIMISC) & 0x07;
1836         state[1] = b43_radio_read(dev, B2055_C2_PD_RSSIMISC) & 0x07;
1837         b43_radio_mask(dev, B2055_C1_PD_RSSIMISC, 0xF8);
1838         b43_radio_mask(dev, B2055_C2_PD_RSSIMISC, 0xF8);
1839         state[2] = b43_radio_read(dev, B2055_C1_SP_RSSI) & 0x07;
1840         state[3] = b43_radio_read(dev, B2055_C2_SP_RSSI) & 0x07;
1841
1842         b43_nphy_rssi_select(dev, 5, type);
1843         b43_nphy_scale_offset_rssi(dev, 0, 0, 5, N_RAIL_I, type);
1844         b43_nphy_scale_offset_rssi(dev, 0, 0, 5, N_RAIL_Q, type);
1845
1846         for (vcm = 0; vcm < 4; vcm++) {
1847                 u8 tmp[4];
1848                 for (j = 0; j < 4; j++)
1849                         tmp[j] = vcm;
1850                 if (type != N_RSSI_W2)
1851                         b43_nphy_set_rssi_2055_vcm(dev, type, tmp);
1852                 b43_nphy_poll_rssi(dev, type, results[vcm], 8);
1853                 if (type == N_RSSI_W1 || type == N_RSSI_W2)
1854                         for (j = 0; j < 2; j++)
1855                                 miniq[vcm][j] = min(results[vcm][2 * j],
1856                                                     results[vcm][2 * j + 1]);
1857         }
1858
1859         for (i = 0; i < 4; i++) {
1860                 s32 mind = 0x100000;
1861                 u8 minvcm = 0;
1862                 s32 minpoll = 249;
1863                 s32 currd;
1864                 for (vcm = 0; vcm < 4; vcm++) {
1865                         if (type == N_RSSI_NB)
1866                                 currd = abs(results[vcm][i] - code * 8);
1867                         else
1868                                 currd = abs(miniq[vcm][i / 2] - code * 8);
1869
1870                         if (currd < mind) {
1871                                 mind = currd;
1872                                 minvcm = vcm;
1873                         }
1874
1875                         if (results[vcm][i] < minpoll)
1876                                 minpoll = results[vcm][i];
1877                 }
1878                 results_min[i] = minpoll;
1879                 vcm_final[i] = minvcm;
1880         }
1881
1882         if (type != N_RSSI_W2)
1883                 b43_nphy_set_rssi_2055_vcm(dev, type, vcm_final);
1884
1885         for (i = 0; i < 4; i++) {
1886                 offset[i] = (code * 8) - results[vcm_final[i]][i];
1887
1888                 if (offset[i] < 0)
1889                         offset[i] = -((abs(offset[i]) + 4) / 8);
1890                 else
1891                         offset[i] = (offset[i] + 4) / 8;
1892
1893                 if (results_min[i] == 248)
1894                         offset[i] = code - 32;
1895
1896                 core = (i / 2) ? 2 : 1;
1897                 rail = (i % 2) ? N_RAIL_Q : N_RAIL_I;
1898
1899                 b43_nphy_scale_offset_rssi(dev, 0, offset[i], core, rail,
1900                                                 type);
1901         }
1902
1903         b43_radio_maskset(dev, B2055_C1_PD_RSSIMISC, 0xF8, state[0]);
1904         b43_radio_maskset(dev, B2055_C2_PD_RSSIMISC, 0xF8, state[1]);
1905
1906         switch (state[2]) {
1907         case 1:
1908                 b43_nphy_rssi_select(dev, 1, N_RSSI_NB);
1909                 break;
1910         case 4:
1911                 b43_nphy_rssi_select(dev, 1, N_RSSI_W1);
1912                 break;
1913         case 2:
1914                 b43_nphy_rssi_select(dev, 1, N_RSSI_W2);
1915                 break;
1916         default:
1917                 b43_nphy_rssi_select(dev, 1, N_RSSI_W2);
1918                 break;
1919         }
1920
1921         switch (state[3]) {
1922         case 1:
1923                 b43_nphy_rssi_select(dev, 2, N_RSSI_NB);
1924                 break;
1925         case 4:
1926                 b43_nphy_rssi_select(dev, 2, N_RSSI_W1);
1927                 break;
1928         default:
1929                 b43_nphy_rssi_select(dev, 2, N_RSSI_W2);
1930                 break;
1931         }
1932
1933         b43_nphy_rssi_select(dev, 0, type);
1934
1935         b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs_save_phy[0]);
1936         b43_radio_write(dev, B2055_C1_PD_RXTX, regs_save_radio[0]);
1937         b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs_save_phy[1]);
1938         b43_radio_write(dev, B2055_C2_PD_RXTX, regs_save_radio[1]);
1939
1940         b43_nphy_classifier(dev, 7, class);
1941         b43_nphy_write_clip_detection(dev, clip_state);
1942         /* Specs don't say about reset here, but it makes wl and b43 dumps
1943            identical, it really seems wl performs this */
1944         b43_nphy_reset_cca(dev);
1945 }
1946
1947 /*
1948  * RSSI Calibration
1949  * http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal
1950  */
1951 static void b43_nphy_rssi_cal(struct b43_wldev *dev)
1952 {
1953         if (dev->phy.rev >= 3) {
1954                 b43_nphy_rev3_rssi_cal(dev);
1955         } else {
1956                 b43_nphy_rev2_rssi_cal(dev, N_RSSI_NB);
1957                 b43_nphy_rev2_rssi_cal(dev, N_RSSI_W1);
1958                 b43_nphy_rev2_rssi_cal(dev, N_RSSI_W2);
1959         }
1960 }
1961
1962 /**************************************************
1963  * Workarounds
1964  **************************************************/
1965
1966 static void b43_nphy_gain_ctl_workarounds_rev3plus(struct b43_wldev *dev)
1967 {
1968         struct ssb_sprom *sprom = dev->dev->bus_sprom;
1969
1970         bool ghz5;
1971         bool ext_lna;
1972         u16 rssi_gain;
1973         struct nphy_gain_ctl_workaround_entry *e;
1974         u8 lpf_gain[6] = { 0x00, 0x06, 0x0C, 0x12, 0x12, 0x12 };
1975         u8 lpf_bits[6] = { 0, 1, 2, 3, 3, 3 };
1976
1977         /* Prepare values */
1978         ghz5 = b43_phy_read(dev, B43_NPHY_BANDCTL)
1979                 & B43_NPHY_BANDCTL_5GHZ;
1980         ext_lna = ghz5 ? sprom->boardflags_hi & B43_BFH_EXTLNA_5GHZ :
1981                 sprom->boardflags_lo & B43_BFL_EXTLNA;
1982         e = b43_nphy_get_gain_ctl_workaround_ent(dev, ghz5, ext_lna);
1983         if (ghz5 && dev->phy.rev >= 5)
1984                 rssi_gain = 0x90;
1985         else
1986                 rssi_gain = 0x50;
1987
1988         b43_phy_set(dev, B43_NPHY_RXCTL, 0x0040);
1989
1990         /* Set Clip 2 detect */
1991         b43_phy_set(dev, B43_NPHY_C1_CGAINI, B43_NPHY_C1_CGAINI_CL2DETECT);
1992         b43_phy_set(dev, B43_NPHY_C2_CGAINI, B43_NPHY_C2_CGAINI_CL2DETECT);
1993
1994         b43_radio_write(dev, B2056_RX0 | B2056_RX_BIASPOLE_LNAG1_IDAC,
1995                         0x17);
1996         b43_radio_write(dev, B2056_RX1 | B2056_RX_BIASPOLE_LNAG1_IDAC,
1997                         0x17);
1998         b43_radio_write(dev, B2056_RX0 | B2056_RX_LNAG2_IDAC, 0xF0);
1999         b43_radio_write(dev, B2056_RX1 | B2056_RX_LNAG2_IDAC, 0xF0);
2000         b43_radio_write(dev, B2056_RX0 | B2056_RX_RSSI_POLE, 0x00);
2001         b43_radio_write(dev, B2056_RX1 | B2056_RX_RSSI_POLE, 0x00);
2002         b43_radio_write(dev, B2056_RX0 | B2056_RX_RSSI_GAIN,
2003                         rssi_gain);
2004         b43_radio_write(dev, B2056_RX1 | B2056_RX_RSSI_GAIN,
2005                         rssi_gain);
2006         b43_radio_write(dev, B2056_RX0 | B2056_RX_BIASPOLE_LNAA1_IDAC,
2007                         0x17);
2008         b43_radio_write(dev, B2056_RX1 | B2056_RX_BIASPOLE_LNAA1_IDAC,
2009                         0x17);
2010         b43_radio_write(dev, B2056_RX0 | B2056_RX_LNAA2_IDAC, 0xFF);
2011         b43_radio_write(dev, B2056_RX1 | B2056_RX_LNAA2_IDAC, 0xFF);
2012
2013         b43_ntab_write_bulk(dev, B43_NTAB8(0, 8), 4, e->lna1_gain);
2014         b43_ntab_write_bulk(dev, B43_NTAB8(1, 8), 4, e->lna1_gain);
2015         b43_ntab_write_bulk(dev, B43_NTAB8(0, 16), 4, e->lna2_gain);
2016         b43_ntab_write_bulk(dev, B43_NTAB8(1, 16), 4, e->lna2_gain);
2017         b43_ntab_write_bulk(dev, B43_NTAB8(0, 32), 10, e->gain_db);
2018         b43_ntab_write_bulk(dev, B43_NTAB8(1, 32), 10, e->gain_db);
2019         b43_ntab_write_bulk(dev, B43_NTAB8(2, 32), 10, e->gain_bits);
2020         b43_ntab_write_bulk(dev, B43_NTAB8(3, 32), 10, e->gain_bits);
2021         b43_ntab_write_bulk(dev, B43_NTAB8(0, 0x40), 6, lpf_gain);
2022         b43_ntab_write_bulk(dev, B43_NTAB8(1, 0x40), 6, lpf_gain);
2023         b43_ntab_write_bulk(dev, B43_NTAB8(2, 0x40), 6, lpf_bits);
2024         b43_ntab_write_bulk(dev, B43_NTAB8(3, 0x40), 6, lpf_bits);
2025
2026         b43_phy_write(dev, B43_NPHY_REV3_C1_INITGAIN_A, e->init_gain);
2027         b43_phy_write(dev, B43_NPHY_REV3_C2_INITGAIN_A, e->init_gain);
2028
2029         b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x106), 2,
2030                                 e->rfseq_init);
2031
2032         b43_phy_write(dev, B43_NPHY_REV3_C1_CLIP_HIGAIN_A, e->cliphi_gain);
2033         b43_phy_write(dev, B43_NPHY_REV3_C2_CLIP_HIGAIN_A, e->cliphi_gain);
2034         b43_phy_write(dev, B43_NPHY_REV3_C1_CLIP_MEDGAIN_A, e->clipmd_gain);
2035         b43_phy_write(dev, B43_NPHY_REV3_C2_CLIP_MEDGAIN_A, e->clipmd_gain);
2036         b43_phy_write(dev, B43_NPHY_REV3_C1_CLIP_LOGAIN_A, e->cliplo_gain);
2037         b43_phy_write(dev, B43_NPHY_REV3_C2_CLIP_LOGAIN_A, e->cliplo_gain);
2038
2039         b43_phy_maskset(dev, B43_NPHY_CRSMINPOWER0, 0xFF00, e->crsmin);
2040         b43_phy_maskset(dev, B43_NPHY_CRSMINPOWERL0, 0xFF00, e->crsminl);
2041         b43_phy_maskset(dev, B43_NPHY_CRSMINPOWERU0, 0xFF00, e->crsminu);
2042         b43_phy_write(dev, B43_NPHY_C1_NBCLIPTHRES, e->nbclip);
2043         b43_phy_write(dev, B43_NPHY_C2_NBCLIPTHRES, e->nbclip);
2044         b43_phy_maskset(dev, B43_NPHY_C1_CLIPWBTHRES,
2045                         ~B43_NPHY_C1_CLIPWBTHRES_CLIP2, e->wlclip);
2046         b43_phy_maskset(dev, B43_NPHY_C2_CLIPWBTHRES,
2047                         ~B43_NPHY_C2_CLIPWBTHRES_CLIP2, e->wlclip);
2048         b43_phy_write(dev, B43_NPHY_CCK_SHIFTB_REF, 0x809C);
2049 }
2050
2051 static void b43_nphy_gain_ctl_workarounds_rev1_2(struct b43_wldev *dev)
2052 {
2053         struct b43_phy_n *nphy = dev->phy.n;
2054
2055         u8 i, j;
2056         u8 code;
2057         u16 tmp;
2058         u8 rfseq_events[3] = { 6, 8, 7 };
2059         u8 rfseq_delays[3] = { 10, 30, 1 };
2060
2061         /* Set Clip 2 detect */
2062         b43_phy_set(dev, B43_NPHY_C1_CGAINI, B43_NPHY_C1_CGAINI_CL2DETECT);
2063         b43_phy_set(dev, B43_NPHY_C2_CGAINI, B43_NPHY_C2_CGAINI_CL2DETECT);
2064
2065         /* Set narrowband clip threshold */
2066         b43_phy_write(dev, B43_NPHY_C1_NBCLIPTHRES, 0x84);
2067         b43_phy_write(dev, B43_NPHY_C2_NBCLIPTHRES, 0x84);
2068
2069         if (!dev->phy.is_40mhz) {
2070                 /* Set dwell lengths */
2071                 b43_phy_write(dev, B43_NPHY_CLIP1_NBDWELL_LEN, 0x002B);
2072                 b43_phy_write(dev, B43_NPHY_CLIP2_NBDWELL_LEN, 0x002B);
2073                 b43_phy_write(dev, B43_NPHY_W1CLIP1_DWELL_LEN, 0x0009);
2074                 b43_phy_write(dev, B43_NPHY_W1CLIP2_DWELL_LEN, 0x0009);
2075         }
2076
2077         /* Set wideband clip 2 threshold */
2078         b43_phy_maskset(dev, B43_NPHY_C1_CLIPWBTHRES,
2079                         ~B43_NPHY_C1_CLIPWBTHRES_CLIP2, 21);
2080         b43_phy_maskset(dev, B43_NPHY_C2_CLIPWBTHRES,
2081                         ~B43_NPHY_C2_CLIPWBTHRES_CLIP2, 21);
2082
2083         if (!dev->phy.is_40mhz) {
2084                 b43_phy_maskset(dev, B43_NPHY_C1_CGAINI,
2085                         ~B43_NPHY_C1_CGAINI_GAINBKOFF, 0x1);
2086                 b43_phy_maskset(dev, B43_NPHY_C2_CGAINI,
2087                         ~B43_NPHY_C2_CGAINI_GAINBKOFF, 0x1);
2088                 b43_phy_maskset(dev, B43_NPHY_C1_CCK_CGAINI,
2089                         ~B43_NPHY_C1_CCK_CGAINI_GAINBKOFF, 0x1);
2090                 b43_phy_maskset(dev, B43_NPHY_C2_CCK_CGAINI,
2091                         ~B43_NPHY_C2_CCK_CGAINI_GAINBKOFF, 0x1);
2092         }
2093
2094         b43_phy_write(dev, B43_NPHY_CCK_SHIFTB_REF, 0x809C);
2095
2096         if (nphy->gain_boost) {
2097                 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ &&
2098                         dev->phy.is_40mhz)
2099                         code = 4;
2100                 else
2101                         code = 5;
2102         } else {
2103                 code = dev->phy.is_40mhz ? 6 : 7;
2104         }
2105
2106         /* Set HPVGA2 index */
2107         b43_phy_maskset(dev, B43_NPHY_C1_INITGAIN, ~B43_NPHY_C1_INITGAIN_HPVGA2,
2108                         code << B43_NPHY_C1_INITGAIN_HPVGA2_SHIFT);
2109         b43_phy_maskset(dev, B43_NPHY_C2_INITGAIN, ~B43_NPHY_C2_INITGAIN_HPVGA2,
2110                         code << B43_NPHY_C2_INITGAIN_HPVGA2_SHIFT);
2111
2112         b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D06);
2113         /* specs say about 2 loops, but wl does 4 */
2114         for (i = 0; i < 4; i++)
2115                 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, (code << 8 | 0x7C));
2116
2117         b43_nphy_adjust_lna_gain_table(dev);
2118
2119         if (nphy->elna_gain_config) {
2120                 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x0808);
2121                 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0);
2122                 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1);
2123                 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1);
2124                 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1);
2125
2126                 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x0C08);
2127                 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0);
2128                 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1);
2129                 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1);
2130                 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1);
2131
2132                 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D06);
2133                 /* specs say about 2 loops, but wl does 4 */
2134                 for (i = 0; i < 4; i++)
2135                         b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
2136                                                 (code << 8 | 0x74));
2137         }
2138
2139         if (dev->phy.rev == 2) {
2140                 for (i = 0; i < 4; i++) {
2141                         b43_phy_write(dev, B43_NPHY_TABLE_ADDR,
2142                                         (0x0400 * i) + 0x0020);
2143                         for (j = 0; j < 21; j++) {
2144                                 tmp = j * (i < 2 ? 3 : 1);
2145                                 b43_phy_write(dev,
2146                                         B43_NPHY_TABLE_DATALO, tmp);
2147                         }
2148                 }
2149         }
2150
2151         b43_nphy_set_rf_sequence(dev, 5, rfseq_events, rfseq_delays, 3);
2152         b43_phy_maskset(dev, B43_NPHY_OVER_DGAIN1,
2153                 ~B43_NPHY_OVER_DGAIN_CCKDGECV & 0xFFFF,
2154                 0x5A << B43_NPHY_OVER_DGAIN_CCKDGECV_SHIFT);
2155
2156         if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
2157                 b43_phy_maskset(dev, B43_PHY_N(0xC5D), 0xFF80, 4);
2158 }
2159
2160 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */
2161 static void b43_nphy_gain_ctl_workarounds(struct b43_wldev *dev)
2162 {
2163         if (dev->phy.rev >= 7)
2164                 ; /* TODO */
2165         else if (dev->phy.rev >= 3)
2166                 b43_nphy_gain_ctl_workarounds_rev3plus(dev);
2167         else
2168                 b43_nphy_gain_ctl_workarounds_rev1_2(dev);
2169 }
2170
2171 /* http://bcm-v4.sipsolutions.net/PHY/N/Read_Lpf_Bw_Ctl */
2172 static u16 b43_nphy_read_lpf_ctl(struct b43_wldev *dev, u16 offset)
2173 {
2174         if (!offset)
2175                 offset = (dev->phy.is_40mhz) ? 0x159 : 0x154;
2176         return b43_ntab_read(dev, B43_NTAB16(7, offset)) & 0x7;
2177 }
2178
2179 static void b43_nphy_workarounds_rev7plus(struct b43_wldev *dev)
2180 {
2181         struct ssb_sprom *sprom = dev->dev->bus_sprom;
2182         struct b43_phy *phy = &dev->phy;
2183
2184         u8 rx2tx_events_ipa[9] = { 0x0, 0x1, 0x2, 0x8, 0x5, 0x6, 0xF, 0x3,
2185                                         0x1F };
2186         u8 rx2tx_delays_ipa[9] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 };
2187
2188         u16 ntab7_15e_16e[] = { 0x10f, 0x10f };
2189         u8 ntab7_138_146[] = { 0x11, 0x11 };
2190         u8 ntab7_133[] = { 0x77, 0x11, 0x11 };
2191
2192         u16 lpf_20, lpf_40, lpf_11b;
2193         u16 bcap_val, bcap_val_11b, bcap_val_11n_20, bcap_val_11n_40;
2194         u16 scap_val, scap_val_11b, scap_val_11n_20, scap_val_11n_40;
2195         bool rccal_ovrd = false;
2196
2197         u16 rx2tx_lut_20_11b, rx2tx_lut_20_11n, rx2tx_lut_40_11n;
2198         u16 bias, conv, filt;
2199
2200         u32 tmp32;
2201         u8 core;
2202
2203         if (phy->rev == 7) {
2204                 b43_phy_set(dev, B43_NPHY_FINERX2_CGC, 0x10);
2205                 b43_phy_maskset(dev, B43_NPHY_FREQGAIN0, 0xFF80, 0x0020);
2206                 b43_phy_maskset(dev, B43_NPHY_FREQGAIN0, 0x80FF, 0x2700);
2207                 b43_phy_maskset(dev, B43_NPHY_FREQGAIN1, 0xFF80, 0x002E);
2208                 b43_phy_maskset(dev, B43_NPHY_FREQGAIN1, 0x80FF, 0x3300);
2209                 b43_phy_maskset(dev, B43_NPHY_FREQGAIN2, 0xFF80, 0x0037);
2210                 b43_phy_maskset(dev, B43_NPHY_FREQGAIN2, 0x80FF, 0x3A00);
2211                 b43_phy_maskset(dev, B43_NPHY_FREQGAIN3, 0xFF80, 0x003C);
2212                 b43_phy_maskset(dev, B43_NPHY_FREQGAIN3, 0x80FF, 0x3E00);
2213                 b43_phy_maskset(dev, B43_NPHY_FREQGAIN4, 0xFF80, 0x003E);
2214                 b43_phy_maskset(dev, B43_NPHY_FREQGAIN4, 0x80FF, 0x3F00);
2215                 b43_phy_maskset(dev, B43_NPHY_FREQGAIN5, 0xFF80, 0x0040);
2216                 b43_phy_maskset(dev, B43_NPHY_FREQGAIN5, 0x80FF, 0x4000);
2217                 b43_phy_maskset(dev, B43_NPHY_FREQGAIN6, 0xFF80, 0x0040);
2218                 b43_phy_maskset(dev, B43_NPHY_FREQGAIN6, 0x80FF, 0x4000);
2219                 b43_phy_maskset(dev, B43_NPHY_FREQGAIN7, 0xFF80, 0x0040);
2220                 b43_phy_maskset(dev, B43_NPHY_FREQGAIN7, 0x80FF, 0x4000);
2221         }
2222         if (phy->rev <= 8) {
2223                 b43_phy_write(dev, B43_NPHY_FORCEFRONT0, 0x1B0);
2224                 b43_phy_write(dev, B43_NPHY_FORCEFRONT1, 0x1B0);
2225         }
2226         if (phy->rev >= 8)
2227                 b43_phy_maskset(dev, B43_NPHY_TXTAILCNT, ~0xFF, 0x72);
2228
2229         b43_ntab_write(dev, B43_NTAB16(8, 0x00), 2);
2230         b43_ntab_write(dev, B43_NTAB16(8, 0x10), 2);
2231         tmp32 = b43_ntab_read(dev, B43_NTAB32(30, 0));
2232         tmp32 &= 0xffffff;
2233         b43_ntab_write(dev, B43_NTAB32(30, 0), tmp32);
2234         b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x15e), 2, ntab7_15e_16e);
2235         b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x16e), 2, ntab7_15e_16e);
2236
2237         if (b43_nphy_ipa(dev))
2238                 b43_nphy_set_rf_sequence(dev, 0, rx2tx_events_ipa,
2239                                 rx2tx_delays_ipa, ARRAY_SIZE(rx2tx_events_ipa));
2240
2241         b43_phy_maskset(dev, B43_NPHY_EPS_OVERRIDEI_0, 0x3FFF, 0x4000);
2242         b43_phy_maskset(dev, B43_NPHY_EPS_OVERRIDEI_1, 0x3FFF, 0x4000);
2243
2244         lpf_20 = b43_nphy_read_lpf_ctl(dev, 0x154);
2245         lpf_40 = b43_nphy_read_lpf_ctl(dev, 0x159);
2246         lpf_11b = b43_nphy_read_lpf_ctl(dev, 0x152);
2247         if (b43_nphy_ipa(dev)) {
2248                 if ((phy->radio_rev == 5 && phy->is_40mhz) ||
2249                     phy->radio_rev == 7 || phy->radio_rev == 8) {
2250                         bcap_val = b43_radio_read(dev, 0x16b);
2251                         scap_val = b43_radio_read(dev, 0x16a);
2252                         scap_val_11b = scap_val;
2253                         bcap_val_11b = bcap_val;
2254                         if (phy->radio_rev == 5 && phy->is_40mhz) {
2255                                 scap_val_11n_20 = scap_val;
2256                                 bcap_val_11n_20 = bcap_val;
2257                                 scap_val_11n_40 = bcap_val_11n_40 = 0xc;
2258                                 rccal_ovrd = true;
2259                         } else { /* Rev 7/8 */
2260                                 lpf_20 = 4;
2261                                 lpf_11b = 1;
2262                                 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
2263                                         scap_val_11n_20 = 0xc;
2264                                         bcap_val_11n_20 = 0xc;
2265                                         scap_val_11n_40 = 0xa;
2266                                         bcap_val_11n_40 = 0xa;
2267                                 } else {
2268                                         scap_val_11n_20 = 0x14;
2269                                         bcap_val_11n_20 = 0x14;
2270                                         scap_val_11n_40 = 0xf;
2271                                         bcap_val_11n_40 = 0xf;
2272                                 }
2273                                 rccal_ovrd = true;
2274                         }
2275                 }
2276         } else {
2277                 if (phy->radio_rev == 5) {
2278                         lpf_20 = 1;
2279                         lpf_40 = 3;
2280                         bcap_val = b43_radio_read(dev, 0x16b);
2281                         scap_val = b43_radio_read(dev, 0x16a);
2282                         scap_val_11b = scap_val;
2283                         bcap_val_11b = bcap_val;
2284                         scap_val_11n_20 = 0x11;
2285                         scap_val_11n_40 = 0x11;
2286                         bcap_val_11n_20 = 0x13;
2287                         bcap_val_11n_40 = 0x13;
2288                         rccal_ovrd = true;
2289                 }
2290         }
2291         if (rccal_ovrd) {
2292                 rx2tx_lut_20_11b = (bcap_val_11b << 8) |
2293                                    (scap_val_11b << 3) |
2294                                    lpf_11b;
2295                 rx2tx_lut_20_11n = (bcap_val_11n_20 << 8) |
2296                                    (scap_val_11n_20 << 3) |
2297                                    lpf_20;
2298                 rx2tx_lut_40_11n = (bcap_val_11n_40 << 8) |
2299                                    (scap_val_11n_40 << 3) |
2300                                    lpf_40;
2301                 for (core = 0; core < 2; core++) {
2302                         b43_ntab_write(dev, B43_NTAB16(7, 0x152 + core * 16),
2303                                        rx2tx_lut_20_11b);
2304                         b43_ntab_write(dev, B43_NTAB16(7, 0x153 + core * 16),
2305                                        rx2tx_lut_20_11n);
2306                         b43_ntab_write(dev, B43_NTAB16(7, 0x154 + core * 16),
2307                                        rx2tx_lut_20_11n);
2308                         b43_ntab_write(dev, B43_NTAB16(7, 0x155 + core * 16),
2309                                        rx2tx_lut_40_11n);
2310                         b43_ntab_write(dev, B43_NTAB16(7, 0x156 + core * 16),
2311                                        rx2tx_lut_40_11n);
2312                         b43_ntab_write(dev, B43_NTAB16(7, 0x157 + core * 16),
2313                                        rx2tx_lut_40_11n);
2314                         b43_ntab_write(dev, B43_NTAB16(7, 0x158 + core * 16),
2315                                        rx2tx_lut_40_11n);
2316                         b43_ntab_write(dev, B43_NTAB16(7, 0x159 + core * 16),
2317                                        rx2tx_lut_40_11n);
2318                 }
2319                 b43_nphy_rf_ctl_override_rev7(dev, 16, 1, 3, false, 2);
2320         }
2321         b43_phy_write(dev, 0x32F, 0x3);
2322         if (phy->radio_rev == 4 || phy->radio_rev == 6)
2323                 b43_nphy_rf_ctl_override_rev7(dev, 4, 1, 3, false, 0);
2324
2325         if (phy->radio_rev == 3 || phy->radio_rev == 4 || phy->radio_rev == 6) {
2326                 if (sprom->revision &&
2327                     sprom->boardflags2_hi & B43_BFH2_IPALVLSHIFT_3P3) {
2328                         b43_radio_write(dev, 0x5, 0x05);
2329                         b43_radio_write(dev, 0x6, 0x30);
2330                         b43_radio_write(dev, 0x7, 0x00);
2331                         b43_radio_set(dev, 0x4f, 0x1);
2332                         b43_radio_set(dev, 0xd4, 0x1);
2333                         bias = 0x1f;
2334                         conv = 0x6f;
2335                         filt = 0xaa;
2336                 } else {
2337                         bias = 0x2b;
2338                         conv = 0x7f;
2339                         filt = 0xee;
2340                 }
2341                 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
2342                         for (core = 0; core < 2; core++) {
2343                                 if (core == 0) {
2344                                         b43_radio_write(dev, 0x5F, bias);
2345                                         b43_radio_write(dev, 0x64, conv);
2346                                         b43_radio_write(dev, 0x66, filt);
2347                                 } else {
2348                                         b43_radio_write(dev, 0xE8, bias);
2349                                         b43_radio_write(dev, 0xE9, conv);
2350                                         b43_radio_write(dev, 0xEB, filt);
2351                                 }
2352                         }
2353                 }
2354         }
2355
2356         if (b43_nphy_ipa(dev)) {
2357                 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
2358                         if (phy->radio_rev == 3 || phy->radio_rev == 4 ||
2359                             phy->radio_rev == 6) {
2360                                 for (core = 0; core < 2; core++) {
2361                                         if (core == 0)
2362                                                 b43_radio_write(dev, 0x51,
2363                                                                 0x7f);
2364                                         else
2365                                                 b43_radio_write(dev, 0xd6,
2366                                                                 0x7f);
2367                                 }
2368                         }
2369                         if (phy->radio_rev == 3) {
2370                                 for (core = 0; core < 2; core++) {
2371                                         if (core == 0) {
2372                                                 b43_radio_write(dev, 0x64,
2373                                                                 0x13);
2374                                                 b43_radio_write(dev, 0x5F,
2375                                                                 0x1F);
2376                                                 b43_radio_write(dev, 0x66,
2377                                                                 0xEE);
2378                                                 b43_radio_write(dev, 0x59,
2379                                                                 0x8A);
2380                                                 b43_radio_write(dev, 0x80,
2381                                                                 0x3E);
2382                                         } else {
2383                                                 b43_radio_write(dev, 0x69,
2384                                                                 0x13);
2385                                                 b43_radio_write(dev, 0xE8,
2386                                                                 0x1F);
2387                                                 b43_radio_write(dev, 0xEB,
2388                                                                 0xEE);
2389                                                 b43_radio_write(dev, 0xDE,
2390                                                                 0x8A);
2391                                                 b43_radio_write(dev, 0x105,
2392                                                                 0x3E);
2393                                         }
2394                                 }
2395                         } else if (phy->radio_rev == 7 || phy->radio_rev == 8) {
2396                                 if (!phy->is_40mhz) {
2397                                         b43_radio_write(dev, 0x5F, 0x14);
2398                                         b43_radio_write(dev, 0xE8, 0x12);
2399                                 } else {
2400                                         b43_radio_write(dev, 0x5F, 0x16);
2401                                         b43_radio_write(dev, 0xE8, 0x16);
2402                                 }
2403                         }
2404                 } else {
2405                         u16 freq = phy->channel_freq;
2406                         if ((freq >= 5180 && freq <= 5230) ||
2407                             (freq >= 5745 && freq <= 5805)) {
2408                                 b43_radio_write(dev, 0x7D, 0xFF);
2409                                 b43_radio_write(dev, 0xFE, 0xFF);
2410                         }
2411                 }
2412         } else {
2413                 if (phy->radio_rev != 5) {
2414                         for (core = 0; core < 2; core++) {
2415                                 if (core == 0) {
2416                                         b43_radio_write(dev, 0x5c, 0x61);
2417                                         b43_radio_write(dev, 0x51, 0x70);
2418                                 } else {
2419                                         b43_radio_write(dev, 0xe1, 0x61);
2420                                         b43_radio_write(dev, 0xd6, 0x70);
2421                                 }
2422                         }
2423                 }
2424         }
2425
2426         if (phy->radio_rev == 4) {
2427                 b43_ntab_write(dev, B43_NTAB16(8, 0x05), 0x20);
2428                 b43_ntab_write(dev, B43_NTAB16(8, 0x15), 0x20);
2429                 for (core = 0; core < 2; core++) {
2430                         if (core == 0) {
2431                                 b43_radio_write(dev, 0x1a1, 0x00);
2432                                 b43_radio_write(dev, 0x1a2, 0x3f);
2433                                 b43_radio_write(dev, 0x1a6, 0x3f);
2434                         } else {
2435                                 b43_radio_write(dev, 0x1a7, 0x00);
2436                                 b43_radio_write(dev, 0x1ab, 0x3f);
2437                                 b43_radio_write(dev, 0x1ac, 0x3f);
2438                         }
2439                 }
2440         } else {
2441                 b43_phy_set(dev, B43_NPHY_AFECTL_C1, 0x4);
2442                 b43_phy_set(dev, B43_NPHY_AFECTL_OVER1, 0x4);
2443                 b43_phy_set(dev, B43_NPHY_AFECTL_C2, 0x4);
2444                 b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x4);
2445
2446                 b43_phy_mask(dev, B43_NPHY_AFECTL_C1, ~0x1);
2447                 b43_phy_set(dev, B43_NPHY_AFECTL_OVER1, 0x1);
2448                 b43_phy_mask(dev, B43_NPHY_AFECTL_C2, ~0x1);
2449                 b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x1);
2450                 b43_ntab_write(dev, B43_NTAB16(8, 0x05), 0x20);
2451                 b43_ntab_write(dev, B43_NTAB16(8, 0x15), 0x20);
2452
2453                 b43_phy_mask(dev, B43_NPHY_AFECTL_C1, ~0x4);
2454                 b43_phy_mask(dev, B43_NPHY_AFECTL_OVER1, ~0x4);
2455                 b43_phy_mask(dev, B43_NPHY_AFECTL_C2, ~0x4);
2456                 b43_phy_mask(dev, B43_NPHY_AFECTL_OVER, ~0x4);
2457         }
2458
2459         b43_phy_write(dev, B43_NPHY_ENDROP_TLEN, 0x2);
2460
2461         b43_ntab_write(dev, B43_NTAB32(16, 0x100), 20);
2462         b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x138), 2, ntab7_138_146);
2463         b43_ntab_write(dev, B43_NTAB16(7, 0x141), 0x77);
2464         b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x133), 3, ntab7_133);
2465         b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x146), 2, ntab7_138_146);
2466         b43_ntab_write(dev, B43_NTAB16(7, 0x123), 0x77);
2467         b43_ntab_write(dev, B43_NTAB16(7, 0x12A), 0x77);
2468
2469         if (!phy->is_40mhz) {
2470                 b43_ntab_write(dev, B43_NTAB32(16, 0x03), 0x18D);
2471                 b43_ntab_write(dev, B43_NTAB32(16, 0x7F), 0x18D);
2472         } else {
2473                 b43_ntab_write(dev, B43_NTAB32(16, 0x03), 0x14D);
2474                 b43_ntab_write(dev, B43_NTAB32(16, 0x7F), 0x14D);
2475         }
2476
2477         b43_nphy_gain_ctl_workarounds(dev);
2478
2479         /* TODO
2480         b43_ntab_write_bulk(dev, B43_NTAB16(8, 0x08), 4,
2481                             aux_adc_vmid_rev7_core0);
2482         b43_ntab_write_bulk(dev, B43_NTAB16(8, 0x18), 4,
2483                             aux_adc_vmid_rev7_core1);
2484         b43_ntab_write_bulk(dev, B43_NTAB16(8, 0x0C), 4,
2485                             aux_adc_gain_rev7);
2486         b43_ntab_write_bulk(dev, B43_NTAB16(8, 0x1C), 4,
2487                             aux_adc_gain_rev7);
2488         */
2489 }
2490
2491 static void b43_nphy_workarounds_rev3plus(struct b43_wldev *dev)
2492 {
2493         struct b43_phy_n *nphy = dev->phy.n;
2494         struct ssb_sprom *sprom = dev->dev->bus_sprom;
2495
2496         /* TX to RX */
2497         u8 tx2rx_events[8] = { 0x4, 0x3, 0x6, 0x5, 0x2, 0x1, 0x8, 0x1F };
2498         u8 tx2rx_delays[8] = { 8, 4, 2, 2, 4, 4, 6, 1 };
2499         /* RX to TX */
2500         u8 rx2tx_events_ipa[9] = { 0x0, 0x1, 0x2, 0x8, 0x5, 0x6, 0xF, 0x3,
2501                                         0x1F };
2502         u8 rx2tx_delays_ipa[9] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 };
2503         u8 rx2tx_events[9] = { 0x0, 0x1, 0x2, 0x8, 0x5, 0x6, 0x3, 0x4, 0x1F };
2504         u8 rx2tx_delays[9] = { 8, 6, 6, 4, 4, 18, 42, 1, 1 };
2505
2506         u16 tmp16;
2507         u32 tmp32;
2508
2509         b43_phy_write(dev, B43_NPHY_FORCEFRONT0, 0x1f8);
2510         b43_phy_write(dev, B43_NPHY_FORCEFRONT1, 0x1f8);
2511
2512         tmp32 = b43_ntab_read(dev, B43_NTAB32(30, 0));
2513         tmp32 &= 0xffffff;
2514         b43_ntab_write(dev, B43_NTAB32(30, 0), tmp32);
2515
2516         b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x0125);
2517         b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x01B3);
2518         b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x0105);
2519         b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x016E);
2520         b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0x00CD);
2521         b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x0020);
2522
2523         b43_phy_write(dev, B43_NPHY_REV3_C1_CLIP_LOGAIN_B, 0x000C);
2524         b43_phy_write(dev, B43_NPHY_REV3_C2_CLIP_LOGAIN_B, 0x000C);
2525
2526         /* TX to RX */
2527         b43_nphy_set_rf_sequence(dev, 1, tx2rx_events, tx2rx_delays,
2528                                  ARRAY_SIZE(tx2rx_events));
2529
2530         /* RX to TX */
2531         if (b43_nphy_ipa(dev))
2532                 b43_nphy_set_rf_sequence(dev, 0, rx2tx_events_ipa,
2533                                 rx2tx_delays_ipa, ARRAY_SIZE(rx2tx_events_ipa));
2534         if (nphy->hw_phyrxchain != 3 &&
2535             nphy->hw_phyrxchain != nphy->hw_phytxchain) {
2536                 if (b43_nphy_ipa(dev)) {
2537                         rx2tx_delays[5] = 59;
2538                         rx2tx_delays[6] = 1;
2539                         rx2tx_events[7] = 0x1F;
2540                 }
2541                 b43_nphy_set_rf_sequence(dev, 0, rx2tx_events, rx2tx_delays,
2542                                          ARRAY_SIZE(rx2tx_events));
2543         }
2544
2545         tmp16 = (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) ?
2546                 0x2 : 0x9C40;
2547         b43_phy_write(dev, B43_NPHY_ENDROP_TLEN, tmp16);
2548
2549         b43_phy_maskset(dev, B43_NPHY_SGILTRNOFFSET, 0xF0FF, 0x0700);
2550
2551         if (!dev->phy.is_40mhz) {
2552                 b43_ntab_write(dev, B43_NTAB32(16, 3), 0x18D);
2553                 b43_ntab_write(dev, B43_NTAB32(16, 127), 0x18D);
2554         } else {
2555                 b43_ntab_write(dev, B43_NTAB32(16, 3), 0x14D);
2556                 b43_ntab_write(dev, B43_NTAB32(16, 127), 0x14D);
2557         }
2558
2559         b43_nphy_gain_ctl_workarounds(dev);
2560
2561         b43_ntab_write(dev, B43_NTAB16(8, 0), 2);
2562         b43_ntab_write(dev, B43_NTAB16(8, 16), 2);
2563
2564         /* TODO */
2565
2566         b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_MAST_BIAS, 0x00);
2567         b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_MAST_BIAS, 0x00);
2568         b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_BIAS_MAIN, 0x06);
2569         b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_BIAS_MAIN, 0x06);
2570         b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_BIAS_AUX, 0x07);
2571         b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_BIAS_AUX, 0x07);
2572         b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_LOB_BIAS, 0x88);
2573         b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_LOB_BIAS, 0x88);
2574         b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_CMFB_IDAC, 0x00);
2575         b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_CMFB_IDAC, 0x00);
2576         b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXG_CMFB_IDAC, 0x00);
2577         b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXG_CMFB_IDAC, 0x00);
2578
2579         /* N PHY WAR TX Chain Update with hw_phytxchain as argument */
2580
2581         if ((sprom->boardflags2_lo & B43_BFL2_APLL_WAR &&
2582              b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ||
2583             (sprom->boardflags2_lo & B43_BFL2_GPLL_WAR &&
2584              b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ))
2585                 tmp32 = 0x00088888;
2586         else
2587                 tmp32 = 0x88888888;
2588         b43_ntab_write(dev, B43_NTAB32(30, 1), tmp32);
2589         b43_ntab_write(dev, B43_NTAB32(30, 2), tmp32);
2590         b43_ntab_write(dev, B43_NTAB32(30, 3), tmp32);
2591
2592         if (dev->phy.rev == 4 &&
2593             b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
2594                 b43_radio_write(dev, B2056_TX0 | B2056_TX_GMBB_IDAC,
2595                                 0x70);
2596                 b43_radio_write(dev, B2056_TX1 | B2056_TX_GMBB_IDAC,
2597                                 0x70);
2598         }
2599
2600         /* Dropped probably-always-true condition */
2601         b43_phy_write(dev, B43_NPHY_ED_CRS40ASSERTTHRESH0, 0x03eb);
2602         b43_phy_write(dev, B43_NPHY_ED_CRS40ASSERTTHRESH1, 0x03eb);
2603         b43_phy_write(dev, B43_NPHY_ED_CRS40DEASSERTTHRESH1, 0x0341);
2604         b43_phy_write(dev, B43_NPHY_ED_CRS40DEASSERTTHRESH1, 0x0341);
2605         b43_phy_write(dev, B43_NPHY_ED_CRS20LASSERTTHRESH0, 0x042b);
2606         b43_phy_write(dev, B43_NPHY_ED_CRS20LASSERTTHRESH1, 0x042b);
2607         b43_phy_write(dev, B43_NPHY_ED_CRS20LDEASSERTTHRESH0, 0x0381);
2608         b43_phy_write(dev, B43_NPHY_ED_CRS20LDEASSERTTHRESH1, 0x0381);
2609         b43_phy_write(dev, B43_NPHY_ED_CRS20UASSERTTHRESH0, 0x042b);
2610         b43_phy_write(dev, B43_NPHY_ED_CRS20UASSERTTHRESH1, 0x042b);
2611         b43_phy_write(dev, B43_NPHY_ED_CRS20UDEASSERTTHRESH0, 0x0381);
2612         b43_phy_write(dev, B43_NPHY_ED_CRS20UDEASSERTTHRESH1, 0x0381);
2613
2614         if (dev->phy.rev >= 6 && sprom->boardflags2_lo & B43_BFL2_SINGLEANT_CCK)
2615                 ; /* TODO: 0x0080000000000000 HF */
2616 }
2617
2618 static void b43_nphy_workarounds_rev1_2(struct b43_wldev *dev)
2619 {
2620         struct ssb_sprom *sprom = dev->dev->bus_sprom;
2621         struct b43_phy *phy = &dev->phy;
2622         struct b43_phy_n *nphy = phy->n;
2623
2624         u8 events1[7] = { 0x0, 0x1, 0x2, 0x8, 0x4, 0x5, 0x3 };
2625         u8 delays1[7] = { 0x8, 0x6, 0x6, 0x2, 0x4, 0x3C, 0x1 };
2626
2627         u8 events2[7] = { 0x0, 0x3, 0x5, 0x4, 0x2, 0x1, 0x8 };
2628         u8 delays2[7] = { 0x8, 0x6, 0x2, 0x4, 0x4, 0x6, 0x1 };
2629
2630         if (sprom->boardflags2_lo & B43_BFL2_SKWRKFEM_BRD ||
2631             dev->dev->board_type == BCMA_BOARD_TYPE_BCM943224M93) {
2632                 delays1[0] = 0x1;
2633                 delays1[5] = 0x14;
2634         }
2635
2636         if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ &&
2637             nphy->band5g_pwrgain) {
2638                 b43_radio_mask(dev, B2055_C1_TX_RF_SPARE, ~0x8);
2639                 b43_radio_mask(dev, B2055_C2_TX_RF_SPARE, ~0x8);
2640         } else {
2641                 b43_radio_set(dev, B2055_C1_TX_RF_SPARE, 0x8);
2642                 b43_radio_set(dev, B2055_C2_TX_RF_SPARE, 0x8);
2643         }
2644
2645         b43_ntab_write(dev, B43_NTAB16(8, 0x00), 0x000A);
2646         b43_ntab_write(dev, B43_NTAB16(8, 0x10), 0x000A);
2647         if (dev->phy.rev < 3) {
2648                 b43_ntab_write(dev, B43_NTAB16(8, 0x02), 0xCDAA);
2649                 b43_ntab_write(dev, B43_NTAB16(8, 0x12), 0xCDAA);
2650         }
2651
2652         if (dev->phy.rev < 2) {
2653                 b43_ntab_write(dev, B43_NTAB16(8, 0x08), 0x0000);
2654                 b43_ntab_write(dev, B43_NTAB16(8, 0x18), 0x0000);
2655                 b43_ntab_write(dev, B43_NTAB16(8, 0x07), 0x7AAB);
2656                 b43_ntab_write(dev, B43_NTAB16(8, 0x17), 0x7AAB);
2657                 b43_ntab_write(dev, B43_NTAB16(8, 0x06), 0x0800);
2658                 b43_ntab_write(dev, B43_NTAB16(8, 0x16), 0x0800);
2659         }
2660
2661         b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8);
2662         b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0x301);
2663         b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8);
2664         b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301);
2665
2666         b43_nphy_set_rf_sequence(dev, 0, events1, delays1, 7);
2667         b43_nphy_set_rf_sequence(dev, 1, events2, delays2, 7);
2668
2669         b43_nphy_gain_ctl_workarounds(dev);
2670
2671         if (dev->phy.rev < 2) {
2672                 if (b43_phy_read(dev, B43_NPHY_RXCTL) & 0x2)
2673                         b43_hf_write(dev, b43_hf_read(dev) |
2674                                         B43_HF_MLADVW);
2675         } else if (dev->phy.rev == 2) {
2676                 b43_phy_write(dev, B43_NPHY_CRSCHECK2, 0);
2677                 b43_phy_write(dev, B43_NPHY_CRSCHECK3, 0);
2678         }
2679
2680         if (dev->phy.rev < 2)
2681                 b43_phy_mask(dev, B43_NPHY_SCRAM_SIGCTL,
2682                                 ~B43_NPHY_SCRAM_SIGCTL_SCM);
2683
2684         /* Set phase track alpha and beta */
2685         b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x125);
2686         b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x1B3);
2687         b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x105);
2688         b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x16E);
2689         b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0xCD);
2690         b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x20);
2691
2692         if (dev->phy.rev < 3) {
2693                 b43_phy_mask(dev, B43_NPHY_PIL_DW1,
2694                              ~B43_NPHY_PIL_DW_64QAM & 0xFFFF);
2695                 b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B1, 0xB5);
2696                 b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B2, 0xA4);
2697                 b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B3, 0x00);
2698         }
2699
2700         if (dev->phy.rev == 2)
2701                 b43_phy_set(dev, B43_NPHY_FINERX2_CGC,
2702                                 B43_NPHY_FINERX2_CGC_DECGC);
2703 }
2704
2705 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Workarounds */
2706 static void b43_nphy_workarounds(struct b43_wldev *dev)
2707 {
2708         struct b43_phy *phy = &dev->phy;
2709         struct b43_phy_n *nphy = phy->n;
2710
2711         if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
2712                 b43_nphy_classifier(dev, 1, 0);
2713         else
2714                 b43_nphy_classifier(dev, 1, 1);
2715
2716         if (nphy->hang_avoid)
2717                 b43_nphy_stay_in_carrier_search(dev, 1);
2718
2719         b43_phy_set(dev, B43_NPHY_IQFLIP,
2720                     B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2);
2721
2722         if (dev->phy.rev >= 7)
2723                 b43_nphy_workarounds_rev7plus(dev);
2724         else if (dev->phy.rev >= 3)
2725                 b43_nphy_workarounds_rev3plus(dev);
2726         else
2727                 b43_nphy_workarounds_rev1_2(dev);
2728
2729         if (nphy->hang_avoid)
2730                 b43_nphy_stay_in_carrier_search(dev, 0);
2731 }
2732
2733 /**************************************************
2734  * Tx/Rx common
2735  **************************************************/
2736
2737 /*
2738  * Transmits a known value for LO calibration
2739  * http://bcm-v4.sipsolutions.net/802.11/PHY/N/TXTone
2740  */
2741 static int b43_nphy_tx_tone(struct b43_wldev *dev, u32 freq, u16 max_val,
2742                                 bool iqmode, bool dac_test)
2743 {
2744         u16 samp = b43_nphy_gen_load_samples(dev, freq, max_val, dac_test);
2745         if (samp == 0)
2746                 return -1;
2747         b43_nphy_run_samples(dev, samp, 0xFFFF, 0, iqmode, dac_test);
2748         return 0;
2749 }
2750
2751 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Chains */
2752 static void b43_nphy_update_txrx_chain(struct b43_wldev *dev)
2753 {
2754         struct b43_phy_n *nphy = dev->phy.n;
2755
2756         bool override = false;
2757         u16 chain = 0x33;
2758
2759         if (nphy->txrx_chain == 0) {
2760                 chain = 0x11;
2761                 override = true;
2762         } else if (nphy->txrx_chain == 1) {
2763                 chain = 0x22;
2764                 override = true;
2765         }
2766
2767         b43_phy_maskset(dev, B43_NPHY_RFSEQCA,
2768                         ~(B43_NPHY_RFSEQCA_TXEN | B43_NPHY_RFSEQCA_RXEN),
2769                         chain);
2770
2771         if (override)
2772                 b43_phy_set(dev, B43_NPHY_RFSEQMODE,
2773                                 B43_NPHY_RFSEQMODE_CAOVER);
2774         else
2775                 b43_phy_mask(dev, B43_NPHY_RFSEQMODE,
2776                                 ~B43_NPHY_RFSEQMODE_CAOVER);
2777 }
2778
2779 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/stop-playback */
2780 static void b43_nphy_stop_playback(struct b43_wldev *dev)
2781 {
2782         struct b43_phy_n *nphy = dev->phy.n;
2783         u16 tmp;
2784
2785         if (nphy->hang_avoid)
2786                 b43_nphy_stay_in_carrier_search(dev, 1);
2787
2788         tmp = b43_phy_read(dev, B43_NPHY_SAMP_STAT);
2789         if (tmp & 0x1)
2790                 b43_phy_set(dev, B43_NPHY_SAMP_CMD, B43_NPHY_SAMP_CMD_STOP);
2791         else if (tmp & 0x2)
2792                 b43_phy_mask(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x7FFF);
2793
2794         b43_phy_mask(dev, B43_NPHY_SAMP_CMD, ~0x0004);
2795
2796         if (nphy->bb_mult_save & 0x80000000) {
2797                 tmp = nphy->bb_mult_save & 0xFFFF;
2798                 b43_ntab_write(dev, B43_NTAB16(15, 87), tmp);
2799                 nphy->bb_mult_save = 0;
2800         }
2801
2802         if (nphy->hang_avoid)
2803                 b43_nphy_stay_in_carrier_search(dev, 0);
2804 }
2805
2806 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/IqCalGainParams */
2807 static void b43_nphy_iq_cal_gain_params(struct b43_wldev *dev, u16 core,
2808                                         struct nphy_txgains target,
2809                                         struct nphy_iqcal_params *params)
2810 {
2811         int i, j, indx;
2812         u16 gain;
2813
2814         if (dev->phy.rev >= 3) {
2815                 params->txgm = target.txgm[core];
2816                 params->pga = target.pga[core];
2817                 params->pad = target.pad[core];
2818                 params->ipa = target.ipa[core];
2819                 params->cal_gain = (params->txgm << 12) | (params->pga << 8) |
2820                                         (params->pad << 4) | (params->ipa);
2821                 for (j = 0; j < 5; j++)
2822                         params->ncorr[j] = 0x79;
2823         } else {
2824                 gain = (target.pad[core]) | (target.pga[core] << 4) |
2825                         (target.txgm[core] << 8);
2826
2827                 indx = (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ?
2828                         1 : 0;
2829                 for (i = 0; i < 9; i++)
2830                         if (tbl_iqcal_gainparams[indx][i][0] == gain)
2831                                 break;
2832                 i = min(i, 8);
2833
2834                 params->txgm = tbl_iqcal_gainparams[indx][i][1];
2835                 params->pga = tbl_iqcal_gainparams[indx][i][2];
2836                 params->pad = tbl_iqcal_gainparams[indx][i][3];
2837                 params->cal_gain = (params->txgm << 7) | (params->pga << 4) |
2838                                         (params->pad << 2);
2839                 for (j = 0; j < 4; j++)
2840                         params->ncorr[j] = tbl_iqcal_gainparams[indx][i][4 + j];
2841         }
2842 }
2843
2844 /**************************************************
2845  * Tx and Rx
2846  **************************************************/
2847
2848 static void b43_nphy_op_adjust_txpower(struct b43_wldev *dev)
2849 {//TODO
2850 }
2851
2852 static enum b43_txpwr_result b43_nphy_op_recalc_txpower(struct b43_wldev *dev,
2853                                                         bool ignore_tssi)
2854 {//TODO
2855         return B43_TXPWR_RES_DONE;
2856 }
2857
2858 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlEnable */
2859 static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable)
2860 {
2861         struct b43_phy_n *nphy = dev->phy.n;
2862         u8 i;
2863         u16 bmask, val, tmp;
2864         enum ieee80211_band band = b43_current_band(dev->wl);
2865
2866         if (nphy->hang_avoid)
2867                 b43_nphy_stay_in_carrier_search(dev, 1);
2868
2869         nphy->txpwrctrl = enable;
2870         if (!enable) {
2871                 if (dev->phy.rev >= 3 &&
2872                     (b43_phy_read(dev, B43_NPHY_TXPCTL_CMD) &
2873                      (B43_NPHY_TXPCTL_CMD_COEFF |
2874                       B43_NPHY_TXPCTL_CMD_HWPCTLEN |
2875                       B43_NPHY_TXPCTL_CMD_PCTLEN))) {
2876                         /* We disable enabled TX pwr ctl, save it's state */
2877                         nphy->tx_pwr_idx[0] = b43_phy_read(dev,
2878                                                 B43_NPHY_C1_TXPCTL_STAT) & 0x7f;
2879                         nphy->tx_pwr_idx[1] = b43_phy_read(dev,
2880                                                 B43_NPHY_C2_TXPCTL_STAT) & 0x7f;
2881                 }
2882
2883                 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x6840);
2884                 for (i = 0; i < 84; i++)
2885                         b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0);
2886
2887                 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x6C40);
2888                 for (i = 0; i < 84; i++)
2889                         b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0);
2890
2891                 tmp = B43_NPHY_TXPCTL_CMD_COEFF | B43_NPHY_TXPCTL_CMD_HWPCTLEN;
2892                 if (dev->phy.rev >= 3)
2893                         tmp |= B43_NPHY_TXPCTL_CMD_PCTLEN;
2894                 b43_phy_mask(dev, B43_NPHY_TXPCTL_CMD, ~tmp);
2895
2896                 if (dev->phy.rev >= 3) {
2897                         b43_phy_set(dev, B43_NPHY_AFECTL_OVER1, 0x0100);
2898                         b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x0100);
2899                 } else {
2900                         b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x4000);
2901                 }
2902
2903                 if (dev->phy.rev == 2)
2904                         b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3,
2905                                 ~B43_NPHY_BPHY_CTL3_SCALE, 0x53);
2906                 else if (dev->phy.rev < 2)
2907                         b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3,
2908                                 ~B43_NPHY_BPHY_CTL3_SCALE, 0x5A);
2909
2910                 if (dev->phy.rev < 2 && dev->phy.is_40mhz)
2911                         b43_hf_write(dev, b43_hf_read(dev) | B43_HF_TSSIRPSMW);
2912         } else {
2913                 b43_ntab_write_bulk(dev, B43_NTAB16(26, 64), 84,
2914                                     nphy->adj_pwr_tbl);
2915                 b43_ntab_write_bulk(dev, B43_NTAB16(27, 64), 84,
2916                                     nphy->adj_pwr_tbl);
2917
2918                 bmask = B43_NPHY_TXPCTL_CMD_COEFF |
2919                         B43_NPHY_TXPCTL_CMD_HWPCTLEN;
2920                 /* wl does useless check for "enable" param here */
2921                 val = B43_NPHY_TXPCTL_CMD_COEFF | B43_NPHY_TXPCTL_CMD_HWPCTLEN;
2922                 if (dev->phy.rev >= 3) {
2923                         bmask |= B43_NPHY_TXPCTL_CMD_PCTLEN;
2924                         if (val)
2925                                 val |= B43_NPHY_TXPCTL_CMD_PCTLEN;
2926                 }
2927                 b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD, ~(bmask), val);
2928
2929                 if (band == IEEE80211_BAND_5GHZ) {
2930                         b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD,
2931                                         ~B43_NPHY_TXPCTL_CMD_INIT, 0x64);
2932                         if (dev->phy.rev > 1)
2933                                 b43_phy_maskset(dev, B43_NPHY_TXPCTL_INIT,
2934                                                 ~B43_NPHY_TXPCTL_INIT_PIDXI1,
2935                                                 0x64);
2936                 }
2937
2938                 if (dev->phy.rev >= 3) {
2939                         if (nphy->tx_pwr_idx[0] != 128 &&
2940                             nphy->tx_pwr_idx[1] != 128) {
2941                                 /* Recover TX pwr ctl state */
2942                                 b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD,
2943                                                 ~B43_NPHY_TXPCTL_CMD_INIT,
2944                                                 nphy->tx_pwr_idx[0]);
2945                                 if (dev->phy.rev > 1)
2946                                         b43_phy_maskset(dev,
2947                                                 B43_NPHY_TXPCTL_INIT,
2948                                                 ~0xff, nphy->tx_pwr_idx[1]);
2949                         }
2950                 }
2951
2952                 if (dev->phy.rev >= 3) {
2953                         b43_phy_mask(dev, B43_NPHY_AFECTL_OVER1, ~0x100);
2954                         b43_phy_mask(dev, B43_NPHY_AFECTL_OVER, ~0x100);
2955                 } else {
2956                         b43_phy_mask(dev, B43_NPHY_AFECTL_OVER, ~0x4000);
2957                 }
2958
2959                 if (dev->phy.rev == 2)
2960                         b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3, ~0xFF, 0x3b);
2961                 else if (dev->phy.rev < 2)
2962                         b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3, ~0xFF, 0x40);
2963
2964                 if (dev->phy.rev < 2 && dev->phy.is_40mhz)
2965                         b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_TSSIRPSMW);
2966
2967                 if (b43_nphy_ipa(dev)) {
2968                         b43_phy_mask(dev, B43_NPHY_PAPD_EN0, ~0x4);
2969                         b43_phy_mask(dev, B43_NPHY_PAPD_EN1, ~0x4);
2970                 }
2971         }
2972
2973         if (nphy->hang_avoid)
2974                 b43_nphy_stay_in_carrier_search(dev, 0);
2975 }
2976
2977 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrFix */
2978 static void b43_nphy_tx_power_fix(struct b43_wldev *dev)
2979 {
2980         struct b43_phy_n *nphy = dev->phy.n;
2981         struct ssb_sprom *sprom = dev->dev->bus_sprom;
2982
2983         u8 txpi[2], bbmult, i;
2984         u16 tmp, radio_gain, dac_gain;
2985         u16 freq = dev->phy.channel_freq;
2986         u32 txgain;
2987         /* u32 gaintbl; rev3+ */
2988
2989         if (nphy->hang_avoid)
2990                 b43_nphy_stay_in_carrier_search(dev, 1);
2991
2992         if (dev->phy.rev >= 7) {
2993                 txpi[0] = txpi[1] = 30;
2994         } else if (dev->phy.rev >= 3) {
2995                 txpi[0] = 40;
2996                 txpi[1] = 40;
2997         } else if (sprom->revision < 4) {
2998                 txpi[0] = 72;
2999                 txpi[1] = 72;
3000         } else {
3001                 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
3002                         txpi[0] = sprom->txpid2g[0];
3003                         txpi[1] = sprom->txpid2g[1];
3004                 } else if (freq >= 4900 && freq < 5100) {
3005                         txpi[0] = sprom->txpid5gl[0];
3006                         txpi[1] = sprom->txpid5gl[1];
3007                 } else if (freq >= 5100 && freq < 5500) {
3008                         txpi[0] = sprom->txpid5g[0];
3009                         txpi[1] = sprom->txpid5g[1];
3010                 } else if (freq >= 5500) {
3011                         txpi[0] = sprom->txpid5gh[0];
3012                         txpi[1] = sprom->txpid5gh[1];
3013                 } else {
3014                         txpi[0] = 91;
3015                         txpi[1] = 91;
3016                 }
3017         }
3018         if (dev->phy.rev < 7 &&
3019             (txpi[0] < 40 || txpi[0] > 100 || txpi[1] < 40 || txpi[1] > 100))
3020                 txpi[0] = txpi[1] = 91;
3021
3022         /*
3023         for (i = 0; i < 2; i++) {
3024                 nphy->txpwrindex[i].index_internal = txpi[i];
3025                 nphy->txpwrindex[i].index_internal_save = txpi[i];
3026         }
3027         */
3028
3029         for (i = 0; i < 2; i++) {
3030                 txgain = *(b43_nphy_get_tx_gain_table(dev) + txpi[i]);
3031
3032                 if (dev->phy.rev >= 3)
3033                         radio_gain = (txgain >> 16) & 0x1FFFF;
3034                 else
3035                         radio_gain = (txgain >> 16) & 0x1FFF;
3036
3037                 if (dev->phy.rev >= 7)
3038                         dac_gain = (txgain >> 8) & 0x7;
3039                 else
3040                         dac_gain = (txgain >> 8) & 0x3F;
3041                 bbmult = txgain & 0xFF;
3042
3043                 if (dev->phy.rev >= 3) {
3044                         if (i == 0)
3045                                 b43_phy_set(dev, B43_NPHY_AFECTL_OVER1, 0x0100);
3046                         else
3047                                 b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x0100);
3048                 } else {
3049                         b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x4000);
3050                 }
3051
3052                 if (i == 0)
3053                         b43_phy_write(dev, B43_NPHY_AFECTL_DACGAIN1, dac_gain);
3054                 else
3055                         b43_phy_write(dev, B43_NPHY_AFECTL_DACGAIN2, dac_gain);
3056
3057                 b43_ntab_write(dev, B43_NTAB16(0x7, 0x110 + i), radio_gain);
3058
3059                 tmp = b43_ntab_read(dev, B43_NTAB16(0xF, 0x57));
3060                 if (i == 0)
3061                         tmp = (tmp & 0x00FF) | (bbmult << 8);
3062                 else
3063                         tmp = (tmp & 0xFF00) | bbmult;
3064                 b43_ntab_write(dev, B43_NTAB16(0xF, 0x57), tmp);
3065
3066                 if (b43_nphy_ipa(dev)) {
3067                         u32 tmp32;
3068                         u16 reg = (i == 0) ?
3069                                 B43_NPHY_PAPD_EN0 : B43_NPHY_PAPD_EN1;
3070                         tmp32 = b43_ntab_read(dev, B43_NTAB32(26 + i,
3071                                                               576 + txpi[i]));
3072                         b43_phy_maskset(dev, reg, 0xE00F, (u32) tmp32 << 4);
3073                         b43_phy_set(dev, reg, 0x4);
3074                 }
3075         }
3076
3077         b43_phy_mask(dev, B43_NPHY_BPHY_CTL2, ~B43_NPHY_BPHY_CTL2_LUT);
3078
3079         if (nphy->hang_avoid)
3080                 b43_nphy_stay_in_carrier_search(dev, 0);
3081 }
3082
3083 static void b43_nphy_ipa_internal_tssi_setup(struct b43_wldev *dev)
3084 {
3085         struct b43_phy *phy = &dev->phy;
3086
3087         u8 core;
3088         u16 r; /* routing */
3089
3090         if (phy->rev >= 7) {
3091                 for (core = 0; core < 2; core++) {
3092                         r = core ? 0x190 : 0x170;
3093                         if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
3094                                 b43_radio_write(dev, r + 0x5, 0x5);
3095                                 b43_radio_write(dev, r + 0x9, 0xE);
3096                                 if (phy->rev != 5)
3097                                         b43_radio_write(dev, r + 0xA, 0);
3098                                 if (phy->rev != 7)
3099                                         b43_radio_write(dev, r + 0xB, 1);
3100                                 else
3101                                         b43_radio_write(dev, r + 0xB, 0x31);
3102                         } else {
3103                                 b43_radio_write(dev, r + 0x5, 0x9);
3104                                 b43_radio_write(dev, r + 0x9, 0xC);
3105                                 b43_radio_write(dev, r + 0xB, 0x0);
3106                                 if (phy->rev != 5)
3107                                         b43_radio_write(dev, r + 0xA, 1);
3108                                 else
3109                                         b43_radio_write(dev, r + 0xA, 0x31);
3110                         }
3111                         b43_radio_write(dev, r + 0x6, 0);
3112                         b43_radio_write(dev, r + 0x7, 0);
3113                         b43_radio_write(dev, r + 0x8, 3);
3114                         b43_radio_write(dev, r + 0xC, 0);
3115                 }
3116         } else {
3117                 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
3118                         b43_radio_write(dev, B2056_SYN_RESERVED_ADDR31, 0x128);
3119                 else
3120                         b43_radio_write(dev, B2056_SYN_RESERVED_ADDR31, 0x80);
3121                 b43_radio_write(dev, B2056_SYN_RESERVED_ADDR30, 0);
3122                 b43_radio_write(dev, B2056_SYN_GPIO_MASTER1, 0x29);
3123
3124                 for (core = 0; core < 2; core++) {
3125                         r = core ? B2056_TX1 : B2056_TX0;
3126
3127                         b43_radio_write(dev, r | B2056_TX_IQCAL_VCM_HG, 0);
3128                         b43_radio_write(dev, r | B2056_TX_IQCAL_IDAC, 0);
3129                         b43_radio_write(dev, r | B2056_TX_TSSI_VCM, 3);
3130                         b43_radio_write(dev, r | B2056_TX_TX_AMP_DET, 0);
3131                         b43_radio_write(dev, r | B2056_TX_TSSI_MISC1, 8);
3132                         b43_radio_write(dev, r | B2056_TX_TSSI_MISC2, 0);
3133                         b43_radio_write(dev, r | B2056_TX_TSSI_MISC3, 0);
3134                         if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
3135                                 b43_radio_write(dev, r | B2056_TX_TX_SSI_MASTER,
3136                                                 0x5);
3137                                 if (phy->rev != 5)
3138                                         b43_radio_write(dev, r | B2056_TX_TSSIA,
3139                                                         0x00);
3140                                 if (phy->rev >= 5)
3141                                         b43_radio_write(dev, r | B2056_TX_TSSIG,
3142                                                         0x31);
3143                                 else
3144                                         b43_radio_write(dev, r | B2056_TX_TSSIG,
3145                                                         0x11);
3146                                 b43_radio_write(dev, r | B2056_TX_TX_SSI_MUX,
3147                                                 0xE);
3148                         } else {
3149                                 b43_radio_write(dev, r | B2056_TX_TX_SSI_MASTER,
3150                                                 0x9);
3151                                 b43_radio_write(dev, r | B2056_TX_TSSIA, 0x31);
3152                                 b43_radio_write(dev, r | B2056_TX_TSSIG, 0x0);
3153                                 b43_radio_write(dev, r | B2056_TX_TX_SSI_MUX,
3154                                                 0xC);
3155                         }
3156                 }
3157         }
3158 }
3159
3160 /*
3161  * Stop radio and transmit known signal. Then check received signal strength to
3162  * get TSSI (Transmit Signal Strength Indicator).
3163  * http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlIdleTssi
3164  */
3165 static void b43_nphy_tx_power_ctl_idle_tssi(struct b43_wldev *dev)
3166 {
3167         struct b43_phy *phy = &dev->phy;
3168         struct b43_phy_n *nphy = dev->phy.n;
3169
3170         u32 tmp;
3171         s32 rssi[4] = { };
3172
3173         /* TODO: check if we can transmit */
3174
3175         if (b43_nphy_ipa(dev))
3176                 b43_nphy_ipa_internal_tssi_setup(dev);
3177
3178         if (phy->rev >= 7)
3179                 b43_nphy_rf_ctl_override_rev7(dev, 0x2000, 0, 3, false, 0);
3180         else if (phy->rev >= 3)
3181                 b43_nphy_rf_ctl_override(dev, 0x2000, 0, 3, false);
3182
3183         b43_nphy_stop_playback(dev);
3184         b43_nphy_tx_tone(dev, 0xFA0, 0, false, false);
3185         udelay(20);
3186         tmp = b43_nphy_poll_rssi(dev, N_RSSI_TSSI_2G, rssi, 1);
3187         b43_nphy_stop_playback(dev);
3188         b43_nphy_rssi_select(dev, 0, N_RSSI_W1);
3189
3190         if (phy->rev >= 7)
3191                 b43_nphy_rf_ctl_override_rev7(dev, 0x2000, 0, 3, true, 0);
3192         else if (phy->rev >= 3)
3193                 b43_nphy_rf_ctl_override(dev, 0x2000, 0, 3, true);
3194
3195         if (phy->rev >= 3) {
3196                 nphy->pwr_ctl_info[0].idle_tssi_5g = (tmp >> 24) & 0xFF;
3197                 nphy->pwr_ctl_info[1].idle_tssi_5g = (tmp >> 8) & 0xFF;
3198         } else {
3199                 nphy->pwr_ctl_info[0].idle_tssi_5g = (tmp >> 16) & 0xFF;
3200                 nphy->pwr_ctl_info[1].idle_tssi_5g = tmp & 0xFF;
3201         }
3202         nphy->pwr_ctl_info[0].idle_tssi_2g = (tmp >> 24) & 0xFF;
3203         nphy->pwr_ctl_info[1].idle_tssi_2g = (tmp >> 8) & 0xFF;
3204 }
3205
3206 /* http://bcm-v4.sipsolutions.net/PHY/N/TxPwrLimitToTbl */
3207 static void b43_nphy_tx_prepare_adjusted_power_table(struct b43_wldev *dev)
3208 {
3209         struct b43_phy_n *nphy = dev->phy.n;
3210
3211         u8 idx, delta;
3212         u8 i, stf_mode;
3213
3214         for (i = 0; i < 4; i++)
3215                 nphy->adj_pwr_tbl[i] = nphy->tx_power_offset[i];
3216
3217         for (stf_mode = 0; stf_mode < 4; stf_mode++) {
3218                 delta = 0;
3219                 switch (stf_mode) {
3220                 case 0:
3221                         if (dev->phy.is_40mhz && dev->phy.rev >= 5) {
3222                                 idx = 68;
3223                         } else {
3224                                 delta = 1;
3225                                 idx = dev->phy.is_40mhz ? 52 : 4;
3226                         }
3227                         break;
3228                 case 1:
3229                         idx = dev->phy.is_40mhz ? 76 : 28;
3230                         break;
3231                 case 2:
3232                         idx = dev->phy.is_40mhz ? 84 : 36;
3233                         break;
3234                 case 3:
3235                         idx = dev->phy.is_40mhz ? 92 : 44;
3236                         break;
3237                 }
3238
3239                 for (i = 0; i < 20; i++) {
3240                         nphy->adj_pwr_tbl[4 + 4 * i + stf_mode] =
3241                                 nphy->tx_power_offset[idx];
3242                         if (i == 0)
3243                                 idx += delta;
3244                         if (i == 14)
3245                                 idx += 1 - delta;
3246                         if (i == 3 || i == 4 || i == 7 || i == 8 || i == 11 ||
3247                             i == 13)
3248                                 idx += 1;
3249                 }
3250         }
3251 }
3252
3253 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlSetup */
3254 static void b43_nphy_tx_power_ctl_setup(struct b43_wldev *dev)
3255 {
3256         struct b43_phy_n *nphy = dev->phy.n;
3257         struct ssb_sprom *sprom = dev->dev->bus_sprom;
3258
3259         s16 a1[2], b0[2], b1[2];
3260         u8 idle[2];
3261         s8 target[2];
3262         s32 num, den, pwr;
3263         u32 regval[64];
3264
3265         u16 freq = dev->phy.channel_freq;
3266         u16 tmp;
3267         u16 r; /* routing */
3268         u8 i, c;
3269
3270         if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12) {
3271                 b43_maskset32(dev, B43_MMIO_MACCTL, ~0, 0x200000);
3272                 b43_read32(dev, B43_MMIO_MACCTL);
3273                 udelay(1);
3274         }
3275
3276         if (nphy->hang_avoid)
3277                 b43_nphy_stay_in_carrier_search(dev, true);
3278
3279         b43_phy_set(dev, B43_NPHY_TSSIMODE, B43_NPHY_TSSIMODE_EN);
3280         if (dev->phy.rev >= 3)
3281                 b43_phy_mask(dev, B43_NPHY_TXPCTL_CMD,
3282                              ~B43_NPHY_TXPCTL_CMD_PCTLEN & 0xFFFF);
3283         else
3284                 b43_phy_set(dev, B43_NPHY_TXPCTL_CMD,
3285                             B43_NPHY_TXPCTL_CMD_PCTLEN);
3286
3287         if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12)
3288                 b43_maskset32(dev, B43_MMIO_MACCTL, ~0x200000, 0);
3289
3290         if (sprom->revision < 4) {
3291                 idle[0] = nphy->pwr_ctl_info[0].idle_tssi_2g;
3292                 idle[1] = nphy->pwr_ctl_info[1].idle_tssi_2g;
3293                 target[0] = target[1] = 52;
3294                 a1[0] = a1[1] = -424;
3295                 b0[0] = b0[1] = 5612;
3296                 b1[0] = b1[1] = -1393;
3297         } else {
3298                 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
3299                         for (c = 0; c < 2; c++) {
3300                                 idle[c] = nphy->pwr_ctl_info[c].idle_tssi_2g;
3301                                 target[c] = sprom->core_pwr_info[c].maxpwr_2g;
3302                                 a1[c] = sprom->core_pwr_info[c].pa_2g[0];
3303                                 b0[c] = sprom->core_pwr_info[c].pa_2g[1];
3304                                 b1[c] = sprom->core_pwr_info[c].pa_2g[2];
3305                         }
3306                 } else if (freq >= 4900 && freq < 5100) {
3307                         for (c = 0; c < 2; c++) {
3308                                 idle[c] = nphy->pwr_ctl_info[c].idle_tssi_5g;
3309                                 target[c] = sprom->core_pwr_info[c].maxpwr_5gl;
3310                                 a1[c] = sprom->core_pwr_info[c].pa_5gl[0];
3311                                 b0[c] = sprom->core_pwr_info[c].pa_5gl[1];
3312                                 b1[c] = sprom->core_pwr_info[c].pa_5gl[2];
3313                         }
3314                 } else if (freq >= 5100 && freq < 5500) {
3315                         for (c = 0; c < 2; c++) {
3316                                 idle[c] = nphy->pwr_ctl_info[c].idle_tssi_5g;
3317                                 target[c] = sprom->core_pwr_info[c].maxpwr_5g;
3318                                 a1[c] = sprom->core_pwr_info[c].pa_5g[0];
3319                                 b0[c] = sprom->core_pwr_info[c].pa_5g[1];
3320                                 b1[c] = sprom->core_pwr_info[c].pa_5g[2];
3321                         }
3322                 } else if (freq >= 5500) {
3323                         for (c = 0; c < 2; c++) {
3324                                 idle[c] = nphy->pwr_ctl_info[c].idle_tssi_5g;
3325                                 target[c] = sprom->core_pwr_info[c].maxpwr_5gh;
3326                                 a1[c] = sprom->core_pwr_info[c].pa_5gh[0];
3327                                 b0[c] = sprom->core_pwr_info[c].pa_5gh[1];
3328                                 b1[c] = sprom->core_pwr_info[c].pa_5gh[2];
3329                         }
3330                 } else {
3331                         idle[0] = nphy->pwr_ctl_info[0].idle_tssi_5g;
3332                         idle[1] = nphy->pwr_ctl_info[1].idle_tssi_5g;
3333                         target[0] = target[1] = 52;
3334                         a1[0] = a1[1] = -424;
3335                         b0[0] = b0[1] = 5612;
3336                         b1[0] = b1[1] = -1393;
3337                 }
3338         }
3339         /* target[0] = target[1] = nphy->tx_power_max; */
3340
3341         if (dev->phy.rev >= 3) {
3342                 if (sprom->fem.ghz2.tssipos)
3343                         b43_phy_set(dev, B43_NPHY_TXPCTL_ITSSI, 0x4000);
3344                 if (dev->phy.rev >= 7) {
3345                         for (c = 0; c < 2; c++) {
3346                                 r = c ? 0x190 : 0x170;
3347                                 if (b43_nphy_ipa(dev))
3348                                         b43_radio_write(dev, r + 0x9, (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) ? 0xE : 0xC);
3349                         }
3350                 } else {
3351                         if (b43_nphy_ipa(dev)) {
3352                                 tmp = (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ? 0xC : 0xE;
3353                                 b43_radio_write(dev,
3354                                         B2056_TX0 | B2056_TX_TX_SSI_MUX, tmp);
3355                                 b43_radio_write(dev,
3356                                         B2056_TX1 | B2056_TX_TX_SSI_MUX, tmp);
3357                         } else {
3358                                 b43_radio_write(dev,
3359                                         B2056_TX0 | B2056_TX_TX_SSI_MUX, 0x11);
3360                                 b43_radio_write(dev,
3361                                         B2056_TX1 | B2056_TX_TX_SSI_MUX, 0x11);
3362                         }
3363                 }
3364         }
3365
3366         if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12) {
3367                 b43_maskset32(dev, B43_MMIO_MACCTL, ~0, 0x200000);
3368                 b43_read32(dev, B43_MMIO_MACCTL);
3369                 udelay(1);
3370         }
3371
3372         if (dev->phy.rev >= 7) {
3373                 b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD,
3374                                 ~B43_NPHY_TXPCTL_CMD_INIT, 0x19);
3375                 b43_phy_maskset(dev, B43_NPHY_TXPCTL_INIT,
3376                                 ~B43_NPHY_TXPCTL_INIT_PIDXI1, 0x19);
3377         } else {
3378                 b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD,
3379                                 ~B43_NPHY_TXPCTL_CMD_INIT, 0x40);
3380                 if (dev->phy.rev > 1)
3381                         b43_phy_maskset(dev, B43_NPHY_TXPCTL_INIT,
3382                                 ~B43_NPHY_TXPCTL_INIT_PIDXI1, 0x40);
3383         }
3384
3385         if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12)
3386                 b43_maskset32(dev, B43_MMIO_MACCTL, ~0x200000, 0);
3387
3388         b43_phy_write(dev, B43_NPHY_TXPCTL_N,
3389                       0xF0 << B43_NPHY_TXPCTL_N_TSSID_SHIFT |
3390                       3 << B43_NPHY_TXPCTL_N_NPTIL2_SHIFT);
3391         b43_phy_write(dev, B43_NPHY_TXPCTL_ITSSI,
3392                       idle[0] << B43_NPHY_TXPCTL_ITSSI_0_SHIFT |
3393                       idle[1] << B43_NPHY_TXPCTL_ITSSI_1_SHIFT |
3394                       B43_NPHY_TXPCTL_ITSSI_BINF);
3395         b43_phy_write(dev, B43_NPHY_TXPCTL_TPWR,
3396                       target[0] << B43_NPHY_TXPCTL_TPWR_0_SHIFT |
3397                       target[1] << B43_NPHY_TXPCTL_TPWR_1_SHIFT);
3398
3399         for (c = 0; c < 2; c++) {
3400                 for (i = 0; i < 64; i++) {
3401                         num = 8 * (16 * b0[c] + b1[c] * i);
3402                         den = 32768 + a1[c] * i;
3403                         pwr = max((4 * num + den / 2) / den, -8);
3404                         if (dev->phy.rev < 3 && (i <= (31 - idle[c] + 1)))
3405                                 pwr = max(pwr, target[c] + 1);
3406                         regval[i] = pwr;
3407                 }
3408                 b43_ntab_write_bulk(dev, B43_NTAB32(26 + c, 0), 64, regval);
3409         }
3410
3411         b43_nphy_tx_prepare_adjusted_power_table(dev);
3412         /*
3413         b43_ntab_write_bulk(dev, B43_NTAB16(26, 64), 84, nphy->adj_pwr_tbl);
3414         b43_ntab_write_bulk(dev, B43_NTAB16(27, 64), 84, nphy->adj_pwr_tbl);
3415         */
3416
3417         if (nphy->hang_avoid)
3418                 b43_nphy_stay_in_carrier_search(dev, false);
3419 }
3420
3421 static void b43_nphy_tx_gain_table_upload(struct b43_wldev *dev)
3422 {
3423         struct b43_phy *phy = &dev->phy;
3424
3425         const u32 *table = NULL;
3426         u32 rfpwr_offset;
3427         u8 pga_gain;
3428         int i;
3429
3430         table = b43_nphy_get_tx_gain_table(dev);
3431         b43_ntab_write_bulk(dev, B43_NTAB32(26, 192), 128, table);
3432         b43_ntab_write_bulk(dev, B43_NTAB32(27, 192), 128, table);
3433
3434         if (phy->rev >= 3) {
3435 #if 0
3436                 nphy->gmval = (table[0] >> 16) & 0x7000;
3437 #endif
3438
3439                 for (i = 0; i < 128; i++) {
3440                         pga_gain = (table[i] >> 24) & 0xF;
3441                         if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
3442                                 rfpwr_offset =
3443                                  b43_ntab_papd_pga_gain_delta_ipa_2g[pga_gain];
3444                         else
3445                                 rfpwr_offset =
3446                                  0; /* FIXME */
3447                         b43_ntab_write(dev, B43_NTAB32(26, 576 + i),
3448                                        rfpwr_offset);
3449                         b43_ntab_write(dev, B43_NTAB32(27, 576 + i),
3450                                        rfpwr_offset);
3451                 }
3452         }
3453 }
3454
3455 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/PA%20override */
3456 static void b43_nphy_pa_override(struct b43_wldev *dev, bool enable)
3457 {
3458         struct b43_phy_n *nphy = dev->phy.n;
3459         enum ieee80211_band band;
3460         u16 tmp;
3461
3462         if (!enable) {
3463                 nphy->rfctrl_intc1_save = b43_phy_read(dev,
3464                                                        B43_NPHY_RFCTL_INTC1);
3465                 nphy->rfctrl_intc2_save = b43_phy_read(dev,
3466                                                        B43_NPHY_RFCTL_INTC2);
3467                 band = b43_current_band(dev->wl);
3468                 if (dev->phy.rev >= 3) {
3469                         if (band == IEEE80211_BAND_5GHZ)
3470                                 tmp = 0x600;
3471                         else
3472                                 tmp = 0x480;
3473                 } else {
3474                         if (band == IEEE80211_BAND_5GHZ)
3475                                 tmp = 0x180;
3476                         else
3477                                 tmp = 0x120;
3478                 }
3479                 b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, tmp);
3480                 b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, tmp);
3481         } else {
3482                 b43_phy_write(dev, B43_NPHY_RFCTL_INTC1,
3483                                 nphy->rfctrl_intc1_save);
3484                 b43_phy_write(dev, B43_NPHY_RFCTL_INTC2,
3485                                 nphy->rfctrl_intc2_save);
3486         }
3487 }
3488
3489 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxLpFbw */
3490 static void b43_nphy_tx_lp_fbw(struct b43_wldev *dev)
3491 {
3492         u16 tmp;
3493
3494         if (dev->phy.rev >= 3) {
3495                 if (b43_nphy_ipa(dev)) {
3496                         tmp = 4;
3497                         b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S2,
3498                               (((((tmp << 3) | tmp) << 3) | tmp) << 3) | tmp);
3499                 }
3500
3501                 tmp = 1;
3502                 b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S2,
3503                               (((((tmp << 3) | tmp) << 3) | tmp) << 3) | tmp);
3504         }
3505 }
3506
3507 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxIqEst */
3508 static void b43_nphy_rx_iq_est(struct b43_wldev *dev, struct nphy_iq_est *est,
3509                                 u16 samps, u8 time, bool wait)
3510 {
3511         int i;
3512         u16 tmp;
3513
3514         b43_phy_write(dev, B43_NPHY_IQEST_SAMCNT, samps);
3515         b43_phy_maskset(dev, B43_NPHY_IQEST_WT, ~B43_NPHY_IQEST_WT_VAL, time);
3516         if (wait)
3517                 b43_phy_set(dev, B43_NPHY_IQEST_CMD, B43_NPHY_IQEST_CMD_MODE);
3518         else
3519                 b43_phy_mask(dev, B43_NPHY_IQEST_CMD, ~B43_NPHY_IQEST_CMD_MODE);
3520
3521         b43_phy_set(dev, B43_NPHY_IQEST_CMD, B43_NPHY_IQEST_CMD_START);
3522
3523         for (i = 1000; i; i--) {
3524                 tmp = b43_phy_read(dev, B43_NPHY_IQEST_CMD);
3525                 if (!(tmp & B43_NPHY_IQEST_CMD_START)) {
3526                         est->i0_pwr = (b43_phy_read(dev, B43_NPHY_IQEST_IPACC_HI0) << 16) |
3527                                         b43_phy_read(dev, B43_NPHY_IQEST_IPACC_LO0);
3528                         est->q0_pwr = (b43_phy_read(dev, B43_NPHY_IQEST_QPACC_HI0) << 16) |
3529                                         b43_phy_read(dev, B43_NPHY_IQEST_QPACC_LO0);
3530                         est->iq0_prod = (b43_phy_read(dev, B43_NPHY_IQEST_IQACC_HI0) << 16) |
3531                                         b43_phy_read(dev, B43_NPHY_IQEST_IQACC_LO0);
3532
3533                         est->i1_pwr = (b43_phy_read(dev, B43_NPHY_IQEST_IPACC_HI1) << 16) |
3534                                         b43_phy_read(dev, B43_NPHY_IQEST_IPACC_LO1);
3535                         est->q1_pwr = (b43_phy_read(dev, B43_NPHY_IQEST_QPACC_HI1) << 16) |
3536                                         b43_phy_read(dev, B43_NPHY_IQEST_QPACC_LO1);
3537                         est->iq1_prod = (b43_phy_read(dev, B43_NPHY_IQEST_IQACC_HI1) << 16) |
3538                                         b43_phy_read(dev, B43_NPHY_IQEST_IQACC_LO1);
3539                         return;
3540                 }
3541                 udelay(10);
3542         }
3543         memset(est, 0, sizeof(*est));
3544 }
3545
3546 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxIqCoeffs */
3547 static void b43_nphy_rx_iq_coeffs(struct b43_wldev *dev, bool write,
3548                                         struct b43_phy_n_iq_comp *pcomp)
3549 {
3550         if (write) {
3551                 b43_phy_write(dev, B43_NPHY_C1_RXIQ_COMPA0, pcomp->a0);
3552                 b43_phy_write(dev, B43_NPHY_C1_RXIQ_COMPB0, pcomp->b0);
3553                 b43_phy_write(dev, B43_NPHY_C2_RXIQ_COMPA1, pcomp->a1);
3554                 b43_phy_write(dev, B43_NPHY_C2_RXIQ_COMPB1, pcomp->b1);
3555         } else {
3556                 pcomp->a0 = b43_phy_read(dev, B43_NPHY_C1_RXIQ_COMPA0);
3557                 pcomp->b0 = b43_phy_read(dev, B43_NPHY_C1_RXIQ_COMPB0);
3558                 pcomp->a1 = b43_phy_read(dev, B43_NPHY_C2_RXIQ_COMPA1);
3559                 pcomp->b1 = b43_phy_read(dev, B43_NPHY_C2_RXIQ_COMPB1);
3560         }
3561 }
3562
3563 #if 0
3564 /* Ready but not used anywhere */
3565 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCalPhyCleanup */
3566 static void b43_nphy_rx_cal_phy_cleanup(struct b43_wldev *dev, u8 core)
3567 {
3568         u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs;
3569
3570         b43_phy_write(dev, B43_NPHY_RFSEQCA, regs[0]);
3571         if (core == 0) {
3572                 b43_phy_write(dev, B43_NPHY_AFECTL_C1, regs[1]);
3573                 b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, regs[2]);
3574         } else {
3575                 b43_phy_write(dev, B43_NPHY_AFECTL_C2, regs[1]);
3576                 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, regs[2]);
3577         }
3578         b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs[3]);
3579         b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs[4]);
3580         b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO1, regs[5]);
3581         b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO2, regs[6]);
3582         b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S1, regs[7]);
3583         b43_phy_write(dev, B43_NPHY_RFCTL_OVER, regs[8]);
3584         b43_phy_write(dev, B43_NPHY_PAPD_EN0, regs[9]);
3585         b43_phy_write(dev, B43_NPHY_PAPD_EN1, regs[10]);
3586 }
3587
3588 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCalPhySetup */
3589 static void b43_nphy_rx_cal_phy_setup(struct b43_wldev *dev, u8 core)
3590 {
3591         u8 rxval, txval;
3592         u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs;
3593
3594         regs[0] = b43_phy_read(dev, B43_NPHY_RFSEQCA);
3595         if (core == 0) {
3596                 regs[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
3597                 regs[2] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER1);
3598         } else {
3599                 regs[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
3600                 regs[2] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
3601         }
3602         regs[3] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
3603         regs[4] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
3604         regs[5] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO1);
3605         regs[6] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO2);
3606         regs[7] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S1);
3607         regs[8] = b43_phy_read(dev, B43_NPHY_RFCTL_OVER);
3608         regs[9] = b43_phy_read(dev, B43_NPHY_PAPD_EN0);
3609         regs[10] = b43_phy_read(dev, B43_NPHY_PAPD_EN1);
3610
3611         b43_phy_mask(dev, B43_NPHY_PAPD_EN0, ~0x0001);
3612         b43_phy_mask(dev, B43_NPHY_PAPD_EN1, ~0x0001);
3613
3614         b43_phy_maskset(dev, B43_NPHY_RFSEQCA,
3615                         ~B43_NPHY_RFSEQCA_RXDIS & 0xFFFF,
3616                         ((1 - core) << B43_NPHY_RFSEQCA_RXDIS_SHIFT));
3617         b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_TXEN,
3618                         ((1 - core) << B43_NPHY_RFSEQCA_TXEN_SHIFT));
3619         b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_RXEN,
3620                         (core << B43_NPHY_RFSEQCA_RXEN_SHIFT));
3621         b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_TXDIS,
3622                         (core << B43_NPHY_RFSEQCA_TXDIS_SHIFT));
3623
3624         if (core == 0) {
3625                 b43_phy_mask(dev, B43_NPHY_AFECTL_C1, ~0x0007);
3626                 b43_phy_set(dev, B43_NPHY_AFECTL_OVER1, 0x0007);
3627         } else {
3628                 b43_phy_mask(dev, B43_NPHY_AFECTL_C2, ~0x0007);
3629                 b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x0007);
3630         }
3631
3632         b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_PA, 0, 3);
3633         b43_nphy_rf_ctl_override(dev, 8, 0, 3, false);
3634         b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX);
3635
3636         if (core == 0) {
3637                 rxval = 1;
3638                 txval = 8;
3639         } else {
3640                 rxval = 4;
3641                 txval = 2;
3642         }
3643         b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_TRSW, rxval,
3644                                       core + 1);
3645         b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_TRSW, txval,
3646                                       2 - core);
3647 }
3648 #endif
3649
3650 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalcRxIqComp */
3651 static void b43_nphy_calc_rx_iq_comp(struct b43_wldev *dev, u8 mask)
3652 {
3653         int i;
3654         s32 iq;
3655         u32 ii;
3656         u32 qq;
3657         int iq_nbits, qq_nbits;
3658         int arsh, brsh;
3659         u16 tmp, a, b;
3660
3661         struct nphy_iq_est est;
3662         struct b43_phy_n_iq_comp old;
3663         struct b43_phy_n_iq_comp new = { };
3664         bool error = false;
3665
3666         if (mask == 0)
3667                 return;
3668
3669         b43_nphy_rx_iq_coeffs(dev, false, &old);
3670         b43_nphy_rx_iq_coeffs(dev, true, &new);
3671         b43_nphy_rx_iq_est(dev, &est, 0x4000, 32, false);
3672         new = old;
3673
3674         for (i = 0; i < 2; i++) {
3675                 if (i == 0 && (mask & 1)) {
3676                         iq = est.iq0_prod;
3677                         ii = est.i0_pwr;
3678                         qq = est.q0_pwr;
3679                 } else if (i == 1 && (mask & 2)) {
3680                         iq = est.iq1_prod;
3681                         ii = est.i1_pwr;
3682                         qq = est.q1_pwr;
3683                 } else {
3684                         continue;
3685                 }
3686
3687                 if (ii + qq < 2) {
3688                         error = true;
3689                         break;
3690                 }
3691
3692                 iq_nbits = fls(abs(iq));
3693                 qq_nbits = fls(qq);
3694
3695                 arsh = iq_nbits - 20;
3696                 if (arsh >= 0) {
3697                         a = -((iq << (30 - iq_nbits)) + (ii >> (1 + arsh)));
3698                         tmp = ii >> arsh;
3699                 } else {
3700                         a = -((iq << (30 - iq_nbits)) + (ii << (-1 - arsh)));
3701                         tmp = ii << -arsh;
3702                 }
3703                 if (tmp == 0) {
3704                         error = true;
3705                         break;
3706                 }
3707                 a /= tmp;
3708
3709                 brsh = qq_nbits - 11;
3710                 if (brsh >= 0) {
3711                         b = (qq << (31 - qq_nbits));
3712                         tmp = ii >> brsh;
3713                 } else {
3714                         b = (qq << (31 - qq_nbits));
3715                         tmp = ii << -brsh;
3716                 }
3717                 if (tmp == 0) {
3718                         error = true;
3719                         break;
3720                 }
3721                 b = int_sqrt(b / tmp - a * a) - (1 << 10);
3722
3723                 if (i == 0 && (mask & 0x1)) {
3724                         if (dev->phy.rev >= 3) {
3725                                 new.a0 = a & 0x3FF;
3726                                 new.b0 = b & 0x3FF;
3727                         } else {
3728                                 new.a0 = b & 0x3FF;
3729                                 new.b0 = a & 0x3FF;
3730                         }
3731                 } else if (i == 1 && (mask & 0x2)) {
3732                         if (dev->phy.rev >= 3) {
3733                                 new.a1 = a & 0x3FF;
3734                                 new.b1 = b & 0x3FF;
3735                         } else {
3736                                 new.a1 = b & 0x3FF;
3737                                 new.b1 = a & 0x3FF;
3738                         }
3739                 }
3740         }
3741
3742         if (error)
3743                 new = old;
3744
3745         b43_nphy_rx_iq_coeffs(dev, true, &new);
3746 }
3747
3748 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxIqWar */
3749 static void b43_nphy_tx_iq_workaround(struct b43_wldev *dev)
3750 {
3751         u16 array[4];
3752         b43_ntab_read_bulk(dev, B43_NTAB16(0xF, 0x50), 4, array);
3753
3754         b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_NPHY_TXIQW0, array[0]);
3755         b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_NPHY_TXIQW1, array[1]);
3756         b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_NPHY_TXIQW2, array[2]);
3757         b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_NPHY_TXIQW3, array[3]);
3758 }
3759
3760 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SpurWar */
3761 static void b43_nphy_spur_workaround(struct b43_wldev *dev)
3762 {
3763         struct b43_phy_n *nphy = dev->phy.n;
3764
3765         u8 channel = dev->phy.channel;
3766         int tone[2] = { 57, 58 };
3767         u32 noise[2] = { 0x3FF, 0x3FF };
3768
3769         B43_WARN_ON(dev->phy.rev < 3);
3770
3771         if (nphy->hang_avoid)
3772                 b43_nphy_stay_in_carrier_search(dev, 1);
3773
3774         if (nphy->gband_spurwar_en) {
3775                 /* TODO: N PHY Adjust Analog Pfbw (7) */
3776                 if (channel == 11 && dev->phy.is_40mhz)
3777                         ; /* TODO: N PHY Adjust Min Noise Var(2, tone, noise)*/
3778                 else
3779                         ; /* TODO: N PHY Adjust Min Noise Var(0, NULL, NULL)*/
3780                 /* TODO: N PHY Adjust CRS Min Power (0x1E) */
3781         }
3782
3783         if (nphy->aband_spurwar_en) {
3784                 if (channel == 54) {
3785                         tone[0] = 0x20;
3786                         noise[0] = 0x25F;
3787                 } else if (channel == 38 || channel == 102 || channel == 118) {
3788                         if (0 /* FIXME */) {
3789                                 tone[0] = 0x20;
3790                                 noise[0] = 0x21F;
3791                         } else {
3792                                 tone[0] = 0;
3793                                 noise[0] = 0;
3794                         }
3795                 } else if (channel == 134) {
3796                         tone[0] = 0x20;
3797                         noise[0] = 0x21F;
3798                 } else if (channel == 151) {
3799                         tone[0] = 0x10;
3800                         noise[0] = 0x23F;
3801                 } else if (channel == 153 || channel == 161) {
3802                         tone[0] = 0x30;
3803                         noise[0] = 0x23F;
3804                 } else {
3805                         tone[0] = 0;
3806                         noise[0] = 0;
3807                 }
3808
3809                 if (!tone[0] && !noise[0])
3810                         ; /* TODO: N PHY Adjust Min Noise Var(1, tone, noise)*/
3811                 else
3812                         ; /* TODO: N PHY Adjust Min Noise Var(0, NULL, NULL)*/
3813         }
3814
3815         if (nphy->hang_avoid)
3816                 b43_nphy_stay_in_carrier_search(dev, 0);
3817 }
3818
3819 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlCoefSetup */
3820 static void b43_nphy_tx_pwr_ctrl_coef_setup(struct b43_wldev *dev)
3821 {
3822         struct b43_phy_n *nphy = dev->phy.n;
3823         int i, j;
3824         u32 tmp;
3825         u32 cur_real, cur_imag, real_part, imag_part;
3826
3827         u16 buffer[7];
3828
3829         if (nphy->hang_avoid)
3830                 b43_nphy_stay_in_carrier_search(dev, true);
3831
3832         b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer);
3833
3834         for (i = 0; i < 2; i++) {
3835                 tmp = ((buffer[i * 2] & 0x3FF) << 10) |
3836                         (buffer[i * 2 + 1] & 0x3FF);
3837                 b43_phy_write(dev, B43_NPHY_TABLE_ADDR,
3838                                 (((i + 26) << 10) | 320));
3839                 for (j = 0; j < 128; j++) {
3840                         b43_phy_write(dev, B43_NPHY_TABLE_DATAHI,
3841                                         ((tmp >> 16) & 0xFFFF));
3842                         b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
3843                                         (tmp & 0xFFFF));
3844                 }
3845         }
3846
3847         for (i = 0; i < 2; i++) {
3848                 tmp = buffer[5 + i];
3849                 real_part = (tmp >> 8) & 0xFF;
3850                 imag_part = (tmp & 0xFF);
3851                 b43_phy_write(dev, B43_NPHY_TABLE_ADDR,
3852                                 (((i + 26) << 10) | 448));
3853
3854                 if (dev->phy.rev >= 3) {
3855                         cur_real = real_part;
3856                         cur_imag = imag_part;
3857                         tmp = ((cur_real & 0xFF) << 8) | (cur_imag & 0xFF);
3858                 }
3859
3860                 for (j = 0; j < 128; j++) {
3861                         if (dev->phy.rev < 3) {
3862                                 cur_real = (real_part * loscale[j] + 128) >> 8;
3863                                 cur_imag = (imag_part * loscale[j] + 128) >> 8;
3864                                 tmp = ((cur_real & 0xFF) << 8) |
3865                                         (cur_imag & 0xFF);
3866                         }
3867                         b43_phy_write(dev, B43_NPHY_TABLE_DATAHI,
3868                                         ((tmp >> 16) & 0xFFFF));
3869                         b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
3870                                         (tmp & 0xFFFF));
3871                 }
3872         }
3873
3874         if (dev->phy.rev >= 3) {
3875                 b43_shm_write16(dev, B43_SHM_SHARED,
3876                                 B43_SHM_SH_NPHY_TXPWR_INDX0, 0xFFFF);
3877                 b43_shm_write16(dev, B43_SHM_SHARED,
3878                                 B43_SHM_SH_NPHY_TXPWR_INDX1, 0xFFFF);
3879         }
3880
3881         if (nphy->hang_avoid)
3882                 b43_nphy_stay_in_carrier_search(dev, false);
3883 }
3884
3885 /*
3886  * Restore RSSI Calibration
3887  * http://bcm-v4.sipsolutions.net/802.11/PHY/N/RestoreRssiCal
3888  */
3889 static void b43_nphy_restore_rssi_cal(struct b43_wldev *dev)
3890 {
3891         struct b43_phy_n *nphy = dev->phy.n;
3892
3893         u16 *rssical_radio_regs = NULL;
3894         u16 *rssical_phy_regs = NULL;
3895
3896         if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
3897                 if (!nphy->rssical_chanspec_2G.center_freq)
3898                         return;
3899                 rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_2G;
3900                 rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_2G;
3901         } else {
3902                 if (!nphy->rssical_chanspec_5G.center_freq)
3903                         return;
3904                 rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_5G;
3905                 rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G;
3906         }
3907
3908         if (dev->phy.rev >= 7) {
3909         } else {
3910                 b43_radio_maskset(dev, B2056_RX0 | B2056_RX_RSSI_MISC, 0xE3,
3911                                   rssical_radio_regs[0]);
3912                 b43_radio_maskset(dev, B2056_RX1 | B2056_RX_RSSI_MISC, 0xE3,
3913                                   rssical_radio_regs[1]);
3914         }
3915
3916         b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Z, rssical_phy_regs[0]);
3917         b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Z, rssical_phy_regs[1]);
3918         b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Z, rssical_phy_regs[2]);
3919         b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Z, rssical_phy_regs[3]);
3920
3921         b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_X, rssical_phy_regs[4]);
3922         b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_X, rssical_phy_regs[5]);
3923         b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_X, rssical_phy_regs[6]);
3924         b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_X, rssical_phy_regs[7]);
3925
3926         b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Y, rssical_phy_regs[8]);
3927         b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Y, rssical_phy_regs[9]);
3928         b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Y, rssical_phy_regs[10]);
3929         b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Y, rssical_phy_regs[11]);
3930 }
3931
3932 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalRadioSetup */
3933 static void b43_nphy_tx_cal_radio_setup(struct b43_wldev *dev)
3934 {
3935         struct b43_phy_n *nphy = dev->phy.n;
3936         u16 *save = nphy->tx_rx_cal_radio_saveregs;
3937         u16 tmp;
3938         u8 offset, i;
3939
3940         if (dev->phy.rev >= 3) {
3941             for (i = 0; i < 2; i++) {
3942                 tmp = (i == 0) ? 0x2000 : 0x3000;
3943                 offset = i * 11;
3944
3945                 save[offset + 0] = b43_radio_read(dev, B2055_CAL_RVARCTL);
3946                 save[offset + 1] = b43_radio_read(dev, B2055_CAL_LPOCTL);
3947                 save[offset + 2] = b43_radio_read(dev, B2055_CAL_TS);
3948                 save[offset + 3] = b43_radio_read(dev, B2055_CAL_RCCALRTS);
3949                 save[offset + 4] = b43_radio_read(dev, B2055_CAL_RCALRTS);
3950                 save[offset + 5] = b43_radio_read(dev, B2055_PADDRV);
3951                 save[offset + 6] = b43_radio_read(dev, B2055_XOCTL1);
3952                 save[offset + 7] = b43_radio_read(dev, B2055_XOCTL2);
3953                 save[offset + 8] = b43_radio_read(dev, B2055_XOREGUL);
3954                 save[offset + 9] = b43_radio_read(dev, B2055_XOMISC);
3955                 save[offset + 10] = b43_radio_read(dev, B2055_PLL_LFC1);
3956
3957                 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
3958                         b43_radio_write(dev, tmp | B2055_CAL_RVARCTL, 0x0A);
3959                         b43_radio_write(dev, tmp | B2055_CAL_LPOCTL, 0x40);
3960                         b43_radio_write(dev, tmp | B2055_CAL_TS, 0x55);
3961                         b43_radio_write(dev, tmp | B2055_CAL_RCCALRTS, 0);
3962                         b43_radio_write(dev, tmp | B2055_CAL_RCALRTS, 0);
3963                         if (nphy->ipa5g_on) {
3964                                 b43_radio_write(dev, tmp | B2055_PADDRV, 4);
3965                                 b43_radio_write(dev, tmp | B2055_XOCTL1, 1);
3966                         } else {
3967                                 b43_radio_write(dev, tmp | B2055_PADDRV, 0);
3968                                 b43_radio_write(dev, tmp | B2055_XOCTL1, 0x2F);
3969                         }
3970                         b43_radio_write(dev, tmp | B2055_XOCTL2, 0);
3971                 } else {
3972                         b43_radio_write(dev, tmp | B2055_CAL_RVARCTL, 0x06);
3973                         b43_radio_write(dev, tmp | B2055_CAL_LPOCTL, 0x40);
3974                         b43_radio_write(dev, tmp | B2055_CAL_TS, 0x55);
3975                         b43_radio_write(dev, tmp | B2055_CAL_RCCALRTS, 0);
3976                         b43_radio_write(dev, tmp | B2055_CAL_RCALRTS, 0);
3977                         b43_radio_write(dev, tmp | B2055_XOCTL1, 0);
3978                         if (nphy->ipa2g_on) {
3979                                 b43_radio_write(dev, tmp | B2055_PADDRV, 6);
3980                                 b43_radio_write(dev, tmp | B2055_XOCTL2,
3981                                         (dev->phy.rev < 5) ? 0x11 : 0x01);
3982                         } else {
3983                                 b43_radio_write(dev, tmp | B2055_PADDRV, 0);
3984                                 b43_radio_write(dev, tmp | B2055_XOCTL2, 0);
3985                         }
3986                 }
3987                 b43_radio_write(dev, tmp | B2055_XOREGUL, 0);
3988                 b43_radio_write(dev, tmp | B2055_XOMISC, 0);
3989                 b43_radio_write(dev, tmp | B2055_PLL_LFC1, 0);
3990             }
3991         } else {
3992                 save[0] = b43_radio_read(dev, B2055_C1_TX_RF_IQCAL1);
3993                 b43_radio_write(dev, B2055_C1_TX_RF_IQCAL1, 0x29);
3994
3995                 save[1] = b43_radio_read(dev, B2055_C1_TX_RF_IQCAL2);
3996                 b43_radio_write(dev, B2055_C1_TX_RF_IQCAL2, 0x54);
3997
3998                 save[2] = b43_radio_read(dev, B2055_C2_TX_RF_IQCAL1);
3999                 b43_radio_write(dev, B2055_C2_TX_RF_IQCAL1, 0x29);
4000
4001                 save[3] = b43_radio_read(dev, B2055_C2_TX_RF_IQCAL2);
4002                 b43_radio_write(dev, B2055_C2_TX_RF_IQCAL2, 0x54);
4003
4004                 save[3] = b43_radio_read(dev, B2055_C1_PWRDET_RXTX);
4005                 save[4] = b43_radio_read(dev, B2055_C2_PWRDET_RXTX);
4006
4007                 if (!(b43_phy_read(dev, B43_NPHY_BANDCTL) &
4008                     B43_NPHY_BANDCTL_5GHZ)) {
4009                         b43_radio_write(dev, B2055_C1_PWRDET_RXTX, 0x04);
4010                         b43_radio_write(dev, B2055_C2_PWRDET_RXTX, 0x04);
4011                 } else {
4012                         b43_radio_write(dev, B2055_C1_PWRDET_RXTX, 0x20);
4013                         b43_radio_write(dev, B2055_C2_PWRDET_RXTX, 0x20);
4014                 }
4015
4016                 if (dev->phy.rev < 2) {
4017                         b43_radio_set(dev, B2055_C1_TX_BB_MXGM, 0x20);
4018                         b43_radio_set(dev, B2055_C2_TX_BB_MXGM, 0x20);
4019                 } else {
4020                         b43_radio_mask(dev, B2055_C1_TX_BB_MXGM, ~0x20);
4021                         b43_radio_mask(dev, B2055_C2_TX_BB_MXGM, ~0x20);
4022                 }
4023         }
4024 }
4025
4026 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/UpdateTxCalLadder */
4027 static void b43_nphy_update_tx_cal_ladder(struct b43_wldev *dev, u16 core)
4028 {
4029         struct b43_phy_n *nphy = dev->phy.n;
4030         int i;
4031         u16 scale, entry;
4032
4033         u16 tmp = nphy->txcal_bbmult;
4034         if (core == 0)
4035                 tmp >>= 8;
4036         tmp &= 0xff;
4037
4038         for (i = 0; i < 18; i++) {
4039                 scale = (ladder_lo[i].percent * tmp) / 100;
4040                 entry = ((scale & 0xFF) << 8) | ladder_lo[i].g_env;
4041                 b43_ntab_write(dev, B43_NTAB16(15, i), entry);
4042
4043                 scale = (ladder_iq[i].percent * tmp) / 100;
4044                 entry = ((scale & 0xFF) << 8) | ladder_iq[i].g_env;
4045                 b43_ntab_write(dev, B43_NTAB16(15, i + 32), entry);
4046         }
4047 }
4048
4049 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ExtPaSetTxDigiFilts */
4050 static void b43_nphy_ext_pa_set_tx_dig_filters(struct b43_wldev *dev)
4051 {
4052         int i;
4053         for (i = 0; i < 15; i++)
4054                 b43_phy_write(dev, B43_PHY_N(0x2C5 + i),
4055                                 tbl_tx_filter_coef_rev4[2][i]);
4056 }
4057
4058 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/IpaSetTxDigiFilts */
4059 static void b43_nphy_int_pa_set_tx_dig_filters(struct b43_wldev *dev)
4060 {
4061         int i, j;
4062         /* B43_NPHY_TXF_20CO_S0A1, B43_NPHY_TXF_40CO_S0A1, unknown */
4063         static const u16 offset[] = { 0x186, 0x195, 0x2C5 };
4064
4065         for (i = 0; i < 3; i++)
4066                 for (j = 0; j < 15; j++)
4067                         b43_phy_write(dev, B43_PHY_N(offset[i] + j),
4068                                         tbl_tx_filter_coef_rev4[i][j]);
4069
4070         if (dev->phy.is_40mhz) {
4071                 for (j = 0; j < 15; j++)
4072                         b43_phy_write(dev, B43_PHY_N(offset[0] + j),
4073                                         tbl_tx_filter_coef_rev4[3][j]);
4074         } else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
4075                 for (j = 0; j < 15; j++)
4076                         b43_phy_write(dev, B43_PHY_N(offset[0] + j),
4077                                         tbl_tx_filter_coef_rev4[5][j]);
4078         }
4079
4080         if (dev->phy.channel == 14)
4081                 for (j = 0; j < 15; j++)
4082                         b43_phy_write(dev, B43_PHY_N(offset[0] + j),
4083                                         tbl_tx_filter_coef_rev4[6][j]);
4084 }
4085
4086 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetTxGain */
4087 static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev)
4088 {
4089         struct b43_phy_n *nphy = dev->phy.n;
4090
4091         u16 curr_gain[2];
4092         struct nphy_txgains target;
4093         const u32 *table = NULL;
4094
4095         if (!nphy->txpwrctrl) {
4096                 int i;
4097
4098                 if (nphy->hang_avoid)
4099                         b43_nphy_stay_in_carrier_search(dev, true);
4100                 b43_ntab_read_bulk(dev, B43_NTAB16(7, 0x110), 2, curr_gain);
4101                 if (nphy->hang_avoid)
4102                         b43_nphy_stay_in_carrier_search(dev, false);
4103
4104                 for (i = 0; i < 2; ++i) {
4105                         if (dev->phy.rev >= 3) {
4106                                 target.ipa[i] = curr_gain[i] & 0x000F;
4107                                 target.pad[i] = (curr_gain[i] & 0x00F0) >> 4;
4108                                 target.pga[i] = (curr_gain[i] & 0x0F00) >> 8;
4109                                 target.txgm[i] = (curr_gain[i] & 0x7000) >> 12;
4110                         } else {
4111                                 target.ipa[i] = curr_gain[i] & 0x0003;
4112                                 target.pad[i] = (curr_gain[i] & 0x000C) >> 2;
4113                                 target.pga[i] = (curr_gain[i] & 0x0070) >> 4;
4114                                 target.txgm[i] = (curr_gain[i] & 0x0380) >> 7;
4115                         }
4116                 }
4117         } else {
4118                 int i;
4119                 u16 index[2];
4120                 index[0] = (b43_phy_read(dev, B43_NPHY_C1_TXPCTL_STAT) &
4121                         B43_NPHY_TXPCTL_STAT_BIDX) >>
4122                         B43_NPHY_TXPCTL_STAT_BIDX_SHIFT;
4123                 index[1] = (b43_phy_read(dev, B43_NPHY_C2_TXPCTL_STAT) &
4124                         B43_NPHY_TXPCTL_STAT_BIDX) >>
4125                         B43_NPHY_TXPCTL_STAT_BIDX_SHIFT;
4126
4127                 for (i = 0; i < 2; ++i) {
4128                         table = b43_nphy_get_tx_gain_table(dev);
4129                         if (dev->phy.rev >= 3) {
4130                                 target.ipa[i] = (table[index[i]] >> 16) & 0xF;
4131                                 target.pad[i] = (table[index[i]] >> 20) & 0xF;
4132                                 target.pga[i] = (table[index[i]] >> 24) & 0xF;
4133                                 target.txgm[i] = (table[index[i]] >> 28) & 0xF;
4134                         } else {
4135                                 target.ipa[i] = (table[index[i]] >> 16) & 0x3;
4136                                 target.pad[i] = (table[index[i]] >> 18) & 0x3;
4137                                 target.pga[i] = (table[index[i]] >> 20) & 0x7;
4138                                 target.txgm[i] = (table[index[i]] >> 23) & 0x7;
4139                         }
4140                 }
4141         }
4142
4143         return target;
4144 }
4145
4146 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalPhyCleanup */
4147 static void b43_nphy_tx_cal_phy_cleanup(struct b43_wldev *dev)
4148 {
4149         u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs;
4150
4151         if (dev->phy.rev >= 3) {
4152                 b43_phy_write(dev, B43_NPHY_AFECTL_C1, regs[0]);
4153                 b43_phy_write(dev, B43_NPHY_AFECTL_C2, regs[1]);
4154                 b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, regs[2]);
4155                 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, regs[3]);
4156                 b43_phy_write(dev, B43_NPHY_BBCFG, regs[4]);
4157                 b43_ntab_write(dev, B43_NTAB16(8, 3), regs[5]);
4158                 b43_ntab_write(dev, B43_NTAB16(8, 19), regs[6]);
4159                 b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs[7]);
4160                 b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs[8]);
4161                 b43_phy_write(dev, B43_NPHY_PAPD_EN0, regs[9]);
4162                 b43_phy_write(dev, B43_NPHY_PAPD_EN1, regs[10]);
4163                 b43_nphy_reset_cca(dev);
4164         } else {
4165                 b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, regs[0]);
4166                 b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, regs[1]);
4167                 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, regs[2]);
4168                 b43_ntab_write(dev, B43_NTAB16(8, 2), regs[3]);
4169                 b43_ntab_write(dev, B43_NTAB16(8, 18), regs[4]);
4170                 b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs[5]);
4171                 b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs[6]);
4172         }
4173 }
4174
4175 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalPhySetup */
4176 static void b43_nphy_tx_cal_phy_setup(struct b43_wldev *dev)
4177 {
4178         u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs;
4179         u16 tmp;
4180
4181         regs[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
4182         regs[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
4183         if (dev->phy.rev >= 3) {
4184                 b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0xF0FF, 0x0A00);
4185                 b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0xF0FF, 0x0A00);
4186
4187                 tmp = b43_phy_read(dev, B43_NPHY_AFECTL_OVER1);
4188                 regs[2] = tmp;
4189                 b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, tmp | 0x0600);
4190
4191                 tmp = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
4192                 regs[3] = tmp;
4193                 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, tmp | 0x0600);
4194
4195                 regs[4] = b43_phy_read(dev, B43_NPHY_BBCFG);
4196                 b43_phy_mask(dev, B43_NPHY_BBCFG,
4197                              ~B43_NPHY_BBCFG_RSTRX & 0xFFFF);
4198
4199                 tmp = b43_ntab_read(dev, B43_NTAB16(8, 3));
4200                 regs[5] = tmp;
4201                 b43_ntab_write(dev, B43_NTAB16(8, 3), 0);
4202
4203                 tmp = b43_ntab_read(dev, B43_NTAB16(8, 19));
4204                 regs[6] = tmp;
4205                 b43_ntab_write(dev, B43_NTAB16(8, 19), 0);
4206                 regs[7] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
4207                 regs[8] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
4208
4209                 b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_PA, 1, 3);
4210                 b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_TRSW, 2, 1);
4211                 b43_nphy_rf_ctl_intc_override(dev, N_INTC_OVERRIDE_TRSW, 8, 2);
4212
4213                 regs[9] = b43_phy_read(dev, B43_NPHY_PAPD_EN0);
4214                 regs[10] = b43_phy_read(dev, B43_NPHY_PAPD_EN1);
4215                 b43_phy_mask(dev, B43_NPHY_PAPD_EN0, ~0x0001);
4216                 b43_phy_mask(dev, B43_NPHY_PAPD_EN1, ~0x0001);
4217         } else {
4218                 b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, 0xA000);
4219                 b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, 0xA000);
4220                 tmp = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
4221                 regs[2] = tmp;
4222                 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, tmp | 0x3000);
4223                 tmp = b43_ntab_read(dev, B43_NTAB16(8, 2));
4224                 regs[3] = tmp;
4225                 tmp |= 0x2000;
4226                 b43_ntab_write(dev, B43_NTAB16(8, 2), tmp);
4227                 tmp = b43_ntab_read(dev, B43_NTAB16(8, 18));
4228                 regs[4] = tmp;
4229                 tmp |= 0x2000;
4230                 b43_ntab_write(dev, B43_NTAB16(8, 18), tmp);
4231                 regs[5] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
4232                 regs[6] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
4233                 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
4234                         tmp = 0x0180;
4235                 else
4236                         tmp = 0x0120;
4237                 b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, tmp);
4238                 b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, tmp);
4239         }
4240 }
4241
4242 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SaveCal */
4243 static void b43_nphy_save_cal(struct b43_wldev *dev)
4244 {
4245         struct b43_phy_n *nphy = dev->phy.n;
4246
4247         struct b43_phy_n_iq_comp *rxcal_coeffs = NULL;
4248         u16 *txcal_radio_regs = NULL;
4249         struct b43_chanspec *iqcal_chanspec;
4250         u16 *table = NULL;
4251
4252         if (nphy->hang_avoid)
4253                 b43_nphy_stay_in_carrier_search(dev, 1);
4254
4255         if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
4256                 rxcal_coeffs = &nphy->cal_cache.rxcal_coeffs_2G;
4257                 txcal_radio_regs = nphy->cal_cache.txcal_radio_regs_2G;
4258                 iqcal_chanspec = &nphy->iqcal_chanspec_2G;
4259                 table = nphy->cal_cache.txcal_coeffs_2G;
4260         } else {
4261                 rxcal_coeffs = &nphy->cal_cache.rxcal_coeffs_5G;
4262                 txcal_radio_regs = nphy->cal_cache.txcal_radio_regs_5G;
4263                 iqcal_chanspec = &nphy->iqcal_chanspec_5G;
4264                 table = nphy->cal_cache.txcal_coeffs_5G;
4265         }
4266
4267         b43_nphy_rx_iq_coeffs(dev, false, rxcal_coeffs);
4268         /* TODO use some definitions */
4269         if (dev->phy.rev >= 3) {
4270                 txcal_radio_regs[0] = b43_radio_read(dev, 0x2021);
4271                 txcal_radio_regs[1] = b43_radio_read(dev, 0x2022);
4272                 txcal_radio_regs[2] = b43_radio_read(dev, 0x3021);
4273                 txcal_radio_regs[3] = b43_radio_read(dev, 0x3022);
4274                 txcal_radio_regs[4] = b43_radio_read(dev, 0x2023);
4275                 txcal_radio_regs[5] = b43_radio_read(dev, 0x2024);
4276                 txcal_radio_regs[6] = b43_radio_read(dev, 0x3023);
4277                 txcal_radio_regs[7] = b43_radio_read(dev, 0x3024);
4278         } else {
4279                 txcal_radio_regs[0] = b43_radio_read(dev, 0x8B);
4280                 txcal_radio_regs[1] = b43_radio_read(dev, 0xBA);
4281                 txcal_radio_regs[2] = b43_radio_read(dev, 0x8D);
4282                 txcal_radio_regs[3] = b43_radio_read(dev, 0xBC);
4283         }
4284         iqcal_chanspec->center_freq = dev->phy.channel_freq;
4285         iqcal_chanspec->channel_type = dev->phy.channel_type;
4286         b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 8, table);
4287
4288         if (nphy->hang_avoid)
4289                 b43_nphy_stay_in_carrier_search(dev, 0);
4290 }
4291
4292 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RestoreCal */
4293 static void b43_nphy_restore_cal(struct b43_wldev *dev)
4294 {
4295         struct b43_phy_n *nphy = dev->phy.n;
4296
4297         u16 coef[4];
4298         u16 *loft = NULL;
4299         u16 *table = NULL;
4300
4301         int i;
4302         u16 *txcal_radio_regs = NULL;
4303         struct b43_phy_n_iq_comp *rxcal_coeffs = NULL;
4304
4305         if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
4306                 if (!nphy->iqcal_chanspec_2G.center_freq)
4307                         return;
4308                 table = nphy->cal_cache.txcal_coeffs_2G;
4309                 loft = &nphy->cal_cache.txcal_coeffs_2G[5];
4310         } else {
4311                 if (!nphy->iqcal_chanspec_5G.center_freq)
4312                         return;
4313                 table = nphy->cal_cache.txcal_coeffs_5G;
4314                 loft = &nphy->cal_cache.txcal_coeffs_5G[5];
4315         }
4316
4317         b43_ntab_write_bulk(dev, B43_NTAB16(15, 80), 4, table);
4318
4319         for (i = 0; i < 4; i++) {
4320                 if (dev->phy.rev >= 3)
4321                         table[i] = coef[i];
4322                 else
4323                         coef[i] = 0;
4324         }
4325
4326         b43_ntab_write_bulk(dev, B43_NTAB16(15, 88), 4, coef);
4327         b43_ntab_write_bulk(dev, B43_NTAB16(15, 85), 2, loft);
4328         b43_ntab_write_bulk(dev, B43_NTAB16(15, 93), 2, loft);
4329
4330         if (dev->phy.rev < 2)
4331                 b43_nphy_tx_iq_workaround(dev);
4332
4333         if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
4334                 txcal_radio_regs = nphy->cal_cache.txcal_radio_regs_2G;
4335                 rxcal_coeffs = &nphy->cal_cache.rxcal_coeffs_2G;
4336         } else {
4337                 txcal_radio_regs = nphy->cal_cache.txcal_radio_regs_5G;
4338                 rxcal_coeffs = &nphy->cal_cache.rxcal_coeffs_5G;
4339         }
4340
4341         /* TODO use some definitions */
4342         if (dev->phy.rev >= 3) {
4343                 b43_radio_write(dev, 0x2021, txcal_radio_regs[0]);
4344                 b43_radio_write(dev, 0x2022, txcal_radio_regs[1]);
4345                 b43_radio_write(dev, 0x3021, txcal_radio_regs[2]);
4346                 b43_radio_write(dev, 0x3022, txcal_radio_regs[3]);
4347                 b43_radio_write(dev, 0x2023, txcal_radio_regs[4]);
4348                 b43_radio_write(dev, 0x2024, txcal_radio_regs[5]);
4349                 b43_radio_write(dev, 0x3023, txcal_radio_regs[6]);
4350                 b43_radio_write(dev, 0x3024, txcal_radio_regs[7]);
4351         } else {
4352                 b43_radio_write(dev, 0x8B, txcal_radio_regs[0]);
4353                 b43_radio_write(dev, 0xBA, txcal_radio_regs[1]);
4354                 b43_radio_write(dev, 0x8D, txcal_radio_regs[2]);
4355                 b43_radio_write(dev, 0xBC, txcal_radio_regs[3]);
4356         }
4357         b43_nphy_rx_iq_coeffs(dev, true, rxcal_coeffs);
4358 }
4359
4360 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalTxIqlo */
4361 static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
4362                                 struct nphy_txgains target,
4363                                 bool full, bool mphase)
4364 {
4365         struct b43_phy_n *nphy = dev->phy.n;
4366         int i;
4367         int error = 0;
4368         int freq;
4369         bool avoid = false;
4370         u8 length;
4371         u16 tmp, core, type, count, max, numb, last = 0, cmd;
4372         const u16 *table;
4373         bool phy6or5x;
4374
4375         u16 buffer[11];
4376         u16 diq_start = 0;
4377         u16 save[2];
4378         u16 gain[2];
4379         struct nphy_iqcal_params params[2];
4380         bool updated[2] = { };
4381
4382         b43_nphy_stay_in_carrier_search(dev, true);
4383
4384         if (dev->phy.rev >= 4) {
4385                 avoid = nphy->hang_avoid;
4386                 nphy->hang_avoid = false;
4387         }
4388
4389         b43_ntab_read_bulk(dev, B43_NTAB16(7, 0x110), 2, save);
4390
4391         for (i = 0; i < 2; i++) {
4392                 b43_nphy_iq_cal_gain_params(dev, i, target, &params[i]);
4393                 gain[i] = params[i].cal_gain;
4394         }
4395
4396         b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, gain);
4397
4398         b43_nphy_tx_cal_radio_setup(dev);
4399         b43_nphy_tx_cal_phy_setup(dev);
4400
4401         phy6or5x = dev->phy.rev >= 6 ||
4402                 (dev->phy.rev == 5 && nphy->ipa2g_on &&
4403                 b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ);
4404         if (phy6or5x) {
4405                 if (dev->phy.is_40mhz) {
4406                         b43_ntab_write_bulk(dev, B43_NTAB16(15, 0), 18,
4407                                         tbl_tx_iqlo_cal_loft_ladder_40);
4408                         b43_ntab_write_bulk(dev, B43_NTAB16(15, 32), 18,
4409                                         tbl_tx_iqlo_cal_iqimb_ladder_40);
4410                 } else {
4411                         b43_ntab_write_bulk(dev, B43_NTAB16(15, 0), 18,
4412                                         tbl_tx_iqlo_cal_loft_ladder_20);
4413                         b43_ntab_write_bulk(dev, B43_NTAB16(15, 32), 18,
4414                                         tbl_tx_iqlo_cal_iqimb_ladder_20);
4415                 }
4416         }
4417
4418         b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8AA9);
4419
4420         if (!dev->phy.is_40mhz)
4421                 freq = 2500;
4422         else
4423                 freq = 5000;
4424
4425         if (nphy->mphase_cal_phase_id > 2)
4426                 b43_nphy_run_samples(dev, (dev->phy.is_40mhz ? 40 : 20) * 8,
4427                                         0xFFFF, 0, true, false);
4428         else
4429                 error = b43_nphy_tx_tone(dev, freq, 250, true, false);
4430
4431         if (error == 0) {
4432                 if (nphy->mphase_cal_phase_id > 2) {
4433                         table = nphy->mphase_txcal_bestcoeffs;
4434                         length = 11;
4435                         if (dev->phy.rev < 3)
4436                                 length -= 2;
4437                 } else {
4438                         if (!full && nphy->txiqlocal_coeffsvalid) {
4439                                 table = nphy->txiqlocal_bestc;
4440                                 length = 11;
4441                                 if (dev->phy.rev < 3)
4442                                         length -= 2;
4443                         } else {
4444                                 full = true;
4445                                 if (dev->phy.rev >= 3) {
4446                                         table = tbl_tx_iqlo_cal_startcoefs_nphyrev3;
4447                                         length = B43_NTAB_TX_IQLO_CAL_STARTCOEFS_REV3;
4448                                 } else {
4449                                         table = tbl_tx_iqlo_cal_startcoefs;
4450                                         length = B43_NTAB_TX_IQLO_CAL_STARTCOEFS;
4451                                 }
4452                         }
4453                 }
4454
4455                 b43_ntab_write_bulk(dev, B43_NTAB16(15, 64), length, table);
4456
4457                 if (full) {
4458                         if (dev->phy.rev >= 3)
4459                                 max = B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL_REV3;
4460                         else
4461                                 max = B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL;
4462                 } else {
4463                         if (dev->phy.rev >= 3)
4464                                 max = B43_NTAB_TX_IQLO_CAL_CMDS_RECAL_REV3;
4465                         else
4466                                 max = B43_NTAB_TX_IQLO_CAL_CMDS_RECAL;
4467                 }
4468
4469                 if (mphase) {
4470                         count = nphy->mphase_txcal_cmdidx;
4471                         numb = min(max,
4472                                 (u16)(count + nphy->mphase_txcal_numcmds));
4473                 } else {
4474                         count = 0;
4475                         numb = max;
4476                 }
4477
4478                 for (; count < numb; count++) {
4479                         if (full) {
4480                                 if (dev->phy.rev >= 3)
4481                                         cmd = tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[count];
4482                                 else
4483                                         cmd = tbl_tx_iqlo_cal_cmds_fullcal[count];
4484                         } else {
4485                                 if (dev->phy.rev >= 3)
4486                                         cmd = tbl_tx_iqlo_cal_cmds_recal_nphyrev3[count];
4487                                 else
4488                                         cmd = tbl_tx_iqlo_cal_cmds_recal[count];
4489                         }
4490
4491                         core = (cmd & 0x3000) >> 12;
4492                         type = (cmd & 0x0F00) >> 8;
4493
4494                         if (phy6or5x && updated[core] == 0) {
4495                                 b43_nphy_update_tx_cal_ladder(dev, core);
4496                                 updated[core] = true;
4497                         }
4498
4499                         tmp = (params[core].ncorr[type] << 8) | 0x66;
4500                         b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDNNUM, tmp);
4501
4502                         if (type == 1 || type == 3 || type == 4) {
4503                                 buffer[0] = b43_ntab_read(dev,
4504                                                 B43_NTAB16(15, 69 + core));
4505                                 diq_start = buffer[0];
4506                                 buffer[0] = 0;
4507                                 b43_ntab_write(dev, B43_NTAB16(15, 69 + core),
4508                                                 0);
4509                         }
4510
4511                         b43_phy_write(dev, B43_NPHY_IQLOCAL_CMD, cmd);
4512                         for (i = 0; i < 2000; i++) {
4513                                 tmp = b43_phy_read(dev, B43_NPHY_IQLOCAL_CMD);
4514                                 if (tmp & 0xC000)
4515                                         break;
4516                                 udelay(10);
4517                         }
4518
4519                         b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length,
4520                                                 buffer);
4521                         b43_ntab_write_bulk(dev, B43_NTAB16(15, 64), length,
4522                                                 buffer);
4523
4524                         if (type == 1 || type == 3 || type == 4)
4525                                 buffer[0] = diq_start;
4526                 }
4527
4528                 if (mphase)
4529                         nphy->mphase_txcal_cmdidx = (numb >= max) ? 0 : numb;
4530
4531                 last = (dev->phy.rev < 3) ? 6 : 7;
4532
4533                 if (!mphase || nphy->mphase_cal_phase_id == last) {
4534                         b43_ntab_write_bulk(dev, B43_NTAB16(15, 96), 4, buffer);
4535                         b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 4, buffer);
4536                         if (dev->phy.rev < 3) {
4537                                 buffer[0] = 0;
4538                                 buffer[1] = 0;
4539                                 buffer[2] = 0;
4540                                 buffer[3] = 0;
4541                         }
4542                         b43_ntab_write_bulk(dev, B43_NTAB16(15, 88), 4,
4543                                                 buffer);
4544                         b43_ntab_read_bulk(dev, B43_NTAB16(15, 101), 2,
4545                                                 buffer);
4546                         b43_ntab_write_bulk(dev, B43_NTAB16(15, 85), 2,
4547                                                 buffer);
4548                         b43_ntab_write_bulk(dev, B43_NTAB16(15, 93), 2,
4549                                                 buffer);
4550                         length = 11;
4551                         if (dev->phy.rev < 3)
4552                                 length -= 2;
4553                         b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length,
4554                                                 nphy->txiqlocal_bestc);
4555                         nphy->txiqlocal_coeffsvalid = true;
4556                         nphy->txiqlocal_chanspec.center_freq =
4557                                                         dev->phy.channel_freq;
4558                         nphy->txiqlocal_chanspec.channel_type =
4559                                                         dev->phy.channel_type;
4560                 } else {
4561                         length = 11;
4562                         if (dev->phy.rev < 3)
4563                                 length -= 2;
4564                         b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length,
4565                                                 nphy->mphase_txcal_bestcoeffs);
4566                 }
4567
4568                 b43_nphy_stop_playback(dev);
4569                 b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0);
4570         }
4571
4572         b43_nphy_tx_cal_phy_cleanup(dev);
4573         b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, save);
4574
4575         if (dev->phy.rev < 2 && (!mphase || nphy->mphase_cal_phase_id == last))
4576                 b43_nphy_tx_iq_workaround(dev);
4577
4578         if (dev->phy.rev >= 4)
4579                 nphy->hang_avoid = avoid;
4580
4581         b43_nphy_stay_in_carrier_search(dev, false);
4582
4583         return error;
4584 }
4585
4586 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ReapplyTxCalCoeffs */
4587 static void b43_nphy_reapply_tx_cal_coeffs(struct b43_wldev *dev)
4588 {
4589         struct b43_phy_n *nphy = dev->phy.n;
4590         u8 i;
4591         u16 buffer[7];
4592         bool equal = true;
4593
4594         if (!nphy->txiqlocal_coeffsvalid ||
4595             nphy->txiqlocal_chanspec.center_freq != dev->phy.channel_freq ||
4596             nphy->txiqlocal_chanspec.channel_type != dev->phy.channel_type)
4597                 return;
4598
4599         b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer);
4600         for (i = 0; i < 4; i++) {
4601                 if (buffer[i] != nphy->txiqlocal_bestc[i]) {
4602                         equal = false;
4603                         break;
4604                 }
4605         }
4606
4607         if (!equal) {
4608                 b43_ntab_write_bulk(dev, B43_NTAB16(15, 80), 4,
4609                                         nphy->txiqlocal_bestc);
4610                 for (i = 0; i < 4; i++)
4611                         buffer[i] = 0;
4612                 b43_ntab_write_bulk(dev, B43_NTAB16(15, 88), 4,
4613                                         buffer);
4614                 b43_ntab_write_bulk(dev, B43_NTAB16(15, 85), 2,
4615                                         &nphy->txiqlocal_bestc[5]);
4616                 b43_ntab_write_bulk(dev, B43_NTAB16(15, 93), 2,
4617                                         &nphy->txiqlocal_bestc[5]);
4618         }
4619 }
4620
4621 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalRxIqRev2 */
4622 static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev,
4623                         struct nphy_txgains target, u8 type, bool debug)
4624 {
4625         struct b43_phy_n *nphy = dev->phy.n;
4626         int i, j, index;
4627         u8 rfctl[2];
4628         u8 afectl_core;
4629         u16 tmp[6];
4630         u16 uninitialized_var(cur_hpf1), uninitialized_var(cur_hpf2), cur_lna;
4631         u32 real, imag;
4632         enum ieee80211_band band;
4633
4634         u8 use;
4635         u16 cur_hpf;
4636         u16 lna[3] = { 3, 3, 1 };
4637         u16 hpf1[3] = { 7, 2, 0 };
4638         u16 hpf2[3] = { 2, 0, 0 };
4639         u32 power[3] = { };
4640         u16 gain_save[2];
4641         u16 cal_gain[2];
4642         struct nphy_iqcal_params cal_params[2];
4643         struct nphy_iq_est est;
4644         int ret = 0;
4645         bool playtone = true;
4646         int desired = 13;
4647
4648         b43_nphy_stay_in_carrier_search(dev, 1);
4649
4650         if (dev->phy.rev < 2)
4651                 b43_nphy_reapply_tx_cal_coeffs(dev);
4652         b43_ntab_read_bulk(dev, B43_NTAB16(7, 0x110), 2, gain_save);
4653         for (i = 0; i < 2; i++) {
4654                 b43_nphy_iq_cal_gain_params(dev, i, target, &cal_params[i]);
4655                 cal_gain[i] = cal_params[i].cal_gain;
4656         }
4657         b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, cal_gain);
4658
4659         for (i = 0; i < 2; i++) {
4660                 if (i == 0) {
4661                         rfctl[0] = B43_NPHY_RFCTL_INTC1;
4662                         rfctl[1] = B43_NPHY_RFCTL_INTC2;
4663                         afectl_core = B43_NPHY_AFECTL_C1;
4664                 } else {
4665                         rfctl[0] = B43_NPHY_RFCTL_INTC2;
4666                         rfctl[1] = B43_NPHY_RFCTL_INTC1;
4667                         afectl_core = B43_NPHY_AFECTL_C2;
4668                 }
4669
4670                 tmp[1] = b43_phy_read(dev, B43_NPHY_RFSEQCA);
4671                 tmp[2] = b43_phy_read(dev, afectl_core);
4672                 tmp[3] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
4673                 tmp[4] = b43_phy_read(dev, rfctl[0]);
4674                 tmp[5] = b43_phy_read(dev, rfctl[1]);
4675
4676                 b43_phy_maskset(dev, B43_NPHY_RFSEQCA,
4677                                 ~B43_NPHY_RFSEQCA_RXDIS & 0xFFFF,
4678                                 ((1 - i) << B43_NPHY_RFSEQCA_RXDIS_SHIFT));
4679                 b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_TXEN,
4680                                 (1 - i));
4681                 b43_phy_set(dev, afectl_core, 0x0006);
4682                 b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x0006);
4683
4684                 band = b43_current_band(dev->wl);
4685
4686                 if (nphy->rxcalparams & 0xFF000000) {
4687                         if (band == IEEE80211_BAND_5GHZ)
4688                                 b43_phy_write(dev, rfctl[0], 0x140);
4689                         else
4690                                 b43_phy_write(dev, rfctl[0], 0x110);
4691                 } else {
4692                         if (band == IEEE80211_BAND_5GHZ)
4693                                 b43_phy_write(dev, rfctl[0], 0x180);
4694                         else
4695                                 b43_phy_write(dev, rfctl[0], 0x120);
4696                 }
4697
4698                 if (band == IEEE80211_BAND_5GHZ)
4699                         b43_phy_write(dev, rfctl[1], 0x148);
4700                 else
4701                         b43_phy_write(dev, rfctl[1], 0x114);
4702
4703                 if (nphy->rxcalparams & 0x10000) {
4704                         b43_radio_maskset(dev, B2055_C1_GENSPARE2, 0xFC,
4705                                         (i + 1));
4706                         b43_radio_maskset(dev, B2055_C2_GENSPARE2, 0xFC,
4707                                         (2 - i));
4708                 }
4709
4710                 for (j = 0; j < 4; j++) {
4711                         if (j < 3) {
4712                                 cur_lna = lna[j];
4713                                 cur_hpf1 = hpf1[j];
4714                                 cur_hpf2 = hpf2[j];
4715                         } else {
4716                                 if (power[1] > 10000) {
4717                                         use = 1;
4718                                         cur_hpf = cur_hpf1;
4719                                         index = 2;
4720                                 } else {
4721                                         if (power[0] > 10000) {
4722                                                 use = 1;
4723                                                 cur_hpf = cur_hpf1;
4724                                                 index = 1;
4725                                         } else {
4726                                                 index = 0;
4727                                                 use = 2;
4728                                                 cur_hpf = cur_hpf2;
4729                                         }
4730                                 }
4731                                 cur_lna = lna[index];
4732                                 cur_hpf1 = hpf1[index];
4733                                 cur_hpf2 = hpf2[index];
4734                                 cur_hpf += desired - hweight32(power[index]);
4735                                 cur_hpf = clamp_val(cur_hpf, 0, 10);
4736                                 if (use == 1)
4737                                         cur_hpf1 = cur_hpf;
4738                                 else
4739                                         cur_hpf2 = cur_hpf;
4740                         }
4741
4742                         tmp[0] = ((cur_hpf2 << 8) | (cur_hpf1 << 4) |
4743                                         (cur_lna << 2));
4744                         b43_nphy_rf_ctl_override(dev, 0x400, tmp[0], 3,
4745                                                                         false);
4746                         b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
4747                         b43_nphy_stop_playback(dev);
4748
4749                         if (playtone) {
4750                                 ret = b43_nphy_tx_tone(dev, 4000,
4751                                                 (nphy->rxcalparams & 0xFFFF),
4752                                                 false, false);
4753                                 playtone = false;
4754                         } else {
4755                                 b43_nphy_run_samples(dev, 160, 0xFFFF, 0,
4756                                                         false, false);
4757                         }
4758
4759                         if (ret == 0) {
4760                                 if (j < 3) {
4761                                         b43_nphy_rx_iq_est(dev, &est, 1024, 32,
4762                                                                         false);
4763                                         if (i == 0) {
4764                                                 real = est.i0_pwr;
4765                                                 imag = est.q0_pwr;
4766                                         } else {
4767                                                 real = est.i1_pwr;
4768                                                 imag = est.q1_pwr;
4769                                         }
4770                                         power[i] = ((real + imag) / 1024) + 1;
4771                                 } else {
4772                                         b43_nphy_calc_rx_iq_comp(dev, 1 << i);
4773                                 }
4774                                 b43_nphy_stop_playback(dev);
4775                         }
4776
4777                         if (ret != 0)
4778                                 break;
4779                 }
4780
4781                 b43_radio_mask(dev, B2055_C1_GENSPARE2, 0xFC);
4782                 b43_radio_mask(dev, B2055_C2_GENSPARE2, 0xFC);
4783                 b43_phy_write(dev, rfctl[1], tmp[5]);
4784                 b43_phy_write(dev, rfctl[0], tmp[4]);
4785                 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, tmp[3]);
4786                 b43_phy_write(dev, afectl_core, tmp[2]);
4787                 b43_phy_write(dev, B43_NPHY_RFSEQCA, tmp[1]);
4788
4789                 if (ret != 0)
4790                         break;
4791         }
4792
4793         b43_nphy_rf_ctl_override(dev, 0x400, 0, 3, true);
4794         b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
4795         b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, gain_save);
4796
4797         b43_nphy_stay_in_carrier_search(dev, 0);
4798
4799         return ret;
4800 }
4801
4802 static int b43_nphy_rev3_cal_rx_iq(struct b43_wldev *dev,
4803                         struct nphy_txgains target, u8 type, bool debug)
4804 {
4805         return -1;
4806 }
4807
4808 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalRxIq */
4809 static int b43_nphy_cal_rx_iq(struct b43_wldev *dev,
4810                         struct nphy_txgains target, u8 type, bool debug)
4811 {
4812         if (dev->phy.rev >= 3)
4813                 return b43_nphy_rev3_cal_rx_iq(dev, target, type, debug);
4814         else
4815                 return b43_nphy_rev2_cal_rx_iq(dev, target, type, debug);
4816 }
4817
4818 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCoreSetState */
4819 static void b43_nphy_set_rx_core_state(struct b43_wldev *dev, u8 mask)
4820 {
4821         struct b43_phy *phy = &dev->phy;
4822         struct b43_phy_n *nphy = phy->n;
4823         /* u16 buf[16]; it's rev3+ */
4824
4825         nphy->phyrxchain = mask;
4826
4827         if (0 /* FIXME clk */)
4828                 return;
4829
4830         b43_mac_suspend(dev);
4831
4832         if (nphy->hang_avoid)
4833                 b43_nphy_stay_in_carrier_search(dev, true);
4834
4835         b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_RXEN,
4836                         (mask & 0x3) << B43_NPHY_RFSEQCA_RXEN_SHIFT);
4837
4838         if ((mask & 0x3) != 0x3) {
4839                 b43_phy_write(dev, B43_NPHY_HPANT_SWTHRES, 1);
4840                 if (dev->phy.rev >= 3) {
4841                         /* TODO */
4842                 }
4843         } else {
4844                 b43_phy_write(dev, B43_NPHY_HPANT_SWTHRES, 0x1E);
4845                 if (dev->phy.rev >= 3) {
4846                         /* TODO */
4847                 }
4848         }
4849
4850         b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
4851
4852         if (nphy->hang_avoid)
4853                 b43_nphy_stay_in_carrier_search(dev, false);
4854
4855         b43_mac_enable(dev);
4856 }
4857
4858 /**************************************************
4859  * N-PHY init
4860  **************************************************/
4861
4862 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MIMOConfig */
4863 static void b43_nphy_update_mimo_config(struct b43_wldev *dev, s32 preamble)
4864 {
4865         u16 mimocfg = b43_phy_read(dev, B43_NPHY_MIMOCFG);
4866
4867         mimocfg |= B43_NPHY_MIMOCFG_AUTO;
4868         if (preamble == 1)
4869                 mimocfg |= B43_NPHY_MIMOCFG_GFMIX;
4870         else
4871                 mimocfg &= ~B43_NPHY_MIMOCFG_GFMIX;
4872
4873         b43_phy_write(dev, B43_NPHY_MIMOCFG, mimocfg);
4874 }
4875
4876 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/BPHYInit */
4877 static void b43_nphy_bphy_init(struct b43_wldev *dev)
4878 {
4879         unsigned int i;
4880         u16 val;
4881
4882         val = 0x1E1F;
4883         for (i = 0; i < 16; i++) {
4884                 b43_phy_write(dev, B43_PHY_N_BMODE(0x88 + i), val);
4885                 val -= 0x202;
4886         }
4887         val = 0x3E3F;
4888         for (i = 0; i < 16; i++) {
4889                 b43_phy_write(dev, B43_PHY_N_BMODE(0x98 + i), val);
4890                 val -= 0x202;
4891         }
4892         b43_phy_write(dev, B43_PHY_N_BMODE(0x38), 0x668);
4893 }
4894
4895 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SuperSwitchInit */
4896 static void b43_nphy_superswitch_init(struct b43_wldev *dev, bool init)
4897 {
4898         if (dev->phy.rev >= 3) {
4899                 if (!init)
4900                         return;
4901                 if (0 /* FIXME */) {
4902                         b43_ntab_write(dev, B43_NTAB16(9, 2), 0x211);
4903                         b43_ntab_write(dev, B43_NTAB16(9, 3), 0x222);
4904                         b43_ntab_write(dev, B43_NTAB16(9, 8), 0x144);
4905                         b43_ntab_write(dev, B43_NTAB16(9, 12), 0x188);
4906                 }
4907         } else {
4908                 b43_phy_write(dev, B43_NPHY_GPIO_LOOEN, 0);
4909                 b43_phy_write(dev, B43_NPHY_GPIO_HIOEN, 0);
4910
4911                 switch (dev->dev->bus_type) {
4912 #ifdef CONFIG_B43_BCMA
4913                 case B43_BUS_BCMA:
4914                         bcma_chipco_gpio_control(&dev->dev->bdev->bus->drv_cc,
4915                                                  0xFC00, 0xFC00);
4916                         break;
4917 #endif
4918 #ifdef CONFIG_B43_SSB
4919                 case B43_BUS_SSB:
4920                         ssb_chipco_gpio_control(&dev->dev->sdev->bus->chipco,
4921                                                 0xFC00, 0xFC00);
4922                         break;
4923 #endif
4924                 }
4925
4926                 b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_GPOUTSMSK, 0);
4927                 b43_maskset16(dev, B43_MMIO_GPIO_MASK, ~0, 0xFC00);
4928                 b43_maskset16(dev, B43_MMIO_GPIO_CONTROL, (~0xFC00 & 0xFFFF),
4929                               0);
4930
4931                 if (init) {
4932                         b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8);
4933                         b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0x301);
4934                         b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8);
4935                         b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301);
4936                 }
4937         }
4938 }
4939
4940 /* http://bcm-v4.sipsolutions.net/802.11/PHY/Init/N */
4941 static int b43_phy_initn(struct b43_wldev *dev)
4942 {
4943         struct ssb_sprom *sprom = dev->dev->bus_sprom;
4944         struct b43_phy *phy = &dev->phy;
4945         struct b43_phy_n *nphy = phy->n;
4946         u8 tx_pwr_state;
4947         struct nphy_txgains target;
4948         u16 tmp;
4949         enum ieee80211_band tmp2;
4950         bool do_rssi_cal;
4951
4952         u16 clip[2];
4953         bool do_cal = false;
4954
4955         if ((dev->phy.rev >= 3) &&
4956            (sprom->boardflags_lo & B43_BFL_EXTLNA) &&
4957            (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)) {
4958                 switch (dev->dev->bus_type) {
4959 #ifdef CONFIG_B43_BCMA
4960                 case B43_BUS_BCMA:
4961                         bcma_cc_set32(&dev->dev->bdev->bus->drv_cc,
4962                                       BCMA_CC_CHIPCTL, 0x40);
4963                         break;
4964 #endif
4965 #ifdef CONFIG_B43_SSB
4966                 case B43_BUS_SSB:
4967                         chipco_set32(&dev->dev->sdev->bus->chipco,
4968                                      SSB_CHIPCO_CHIPCTL, 0x40);
4969                         break;
4970 #endif
4971                 }
4972         }
4973         nphy->deaf_count = 0;
4974         b43_nphy_tables_init(dev);
4975         nphy->crsminpwr_adjusted = false;
4976         nphy->noisevars_adjusted = false;
4977
4978         /* Clear all overrides */
4979         if (dev->phy.rev >= 3) {
4980                 b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S1, 0);
4981                 b43_phy_write(dev, B43_NPHY_RFCTL_OVER, 0);
4982                 b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S0, 0);
4983                 b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S1, 0);
4984         } else {
4985                 b43_phy_write(dev, B43_NPHY_RFCTL_OVER, 0);
4986         }
4987         b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, 0);
4988         b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, 0);
4989         if (dev->phy.rev < 6) {
4990                 b43_phy_write(dev, B43_NPHY_RFCTL_INTC3, 0);
4991                 b43_phy_write(dev, B43_NPHY_RFCTL_INTC4, 0);
4992         }
4993         b43_phy_mask(dev, B43_NPHY_RFSEQMODE,
4994                      ~(B43_NPHY_RFSEQMODE_CAOVER |
4995                        B43_NPHY_RFSEQMODE_TROVER));
4996         if (dev->phy.rev >= 3)
4997                 b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, 0);
4998         b43_phy_write(dev, B43_NPHY_AFECTL_OVER, 0);
4999
5000         if (dev->phy.rev <= 2) {
5001                 tmp = (dev->phy.rev == 2) ? 0x3B : 0x40;
5002                 b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3,
5003                                 ~B43_NPHY_BPHY_CTL3_SCALE,
5004                                 tmp << B43_NPHY_BPHY_CTL3_SCALE_SHIFT);
5005         }
5006         b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_20M, 0x20);
5007         b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_40M, 0x20);
5008
5009         if (sprom->boardflags2_lo & B43_BFL2_SKWRKFEM_BRD ||
5010             (dev->dev->board_vendor == PCI_VENDOR_ID_APPLE &&
5011              dev->dev->board_type == BCMA_BOARD_TYPE_BCM943224M93))
5012                 b43_phy_write(dev, B43_NPHY_TXREALFD, 0xA0);
5013         else
5014                 b43_phy_write(dev, B43_NPHY_TXREALFD, 0xB8);
5015         b43_phy_write(dev, B43_NPHY_MIMO_CRSTXEXT, 0xC8);
5016         b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x50);
5017         b43_phy_write(dev, B43_NPHY_TXRIFS_FRDEL, 0x30);
5018
5019         b43_nphy_update_mimo_config(dev, nphy->preamble_override);
5020         b43_nphy_update_txrx_chain(dev);
5021
5022         if (phy->rev < 2) {
5023                 b43_phy_write(dev, B43_NPHY_DUP40_GFBL, 0xAA8);
5024                 b43_phy_write(dev, B43_NPHY_DUP40_BL, 0x9A4);
5025         }
5026
5027         tmp2 = b43_current_band(dev->wl);
5028         if (b43_nphy_ipa(dev)) {
5029                 b43_phy_set(dev, B43_NPHY_PAPD_EN0, 0x1);
5030                 b43_phy_maskset(dev, B43_NPHY_EPS_TABLE_ADJ0, 0x007F,
5031                                 nphy->papd_epsilon_offset[0] << 7);
5032                 b43_phy_set(dev, B43_NPHY_PAPD_EN1, 0x1);
5033                 b43_phy_maskset(dev, B43_NPHY_EPS_TABLE_ADJ1, 0x007F,
5034                                 nphy->papd_epsilon_offset[1] << 7);
5035                 b43_nphy_int_pa_set_tx_dig_filters(dev);
5036         } else if (phy->rev >= 5) {
5037                 b43_nphy_ext_pa_set_tx_dig_filters(dev);
5038         }
5039
5040         b43_nphy_workarounds(dev);
5041
5042         /* Reset CCA, in init code it differs a little from standard way */
5043         b43_phy_force_clock(dev, 1);
5044         tmp = b43_phy_read(dev, B43_NPHY_BBCFG);
5045         b43_phy_write(dev, B43_NPHY_BBCFG, tmp | B43_NPHY_BBCFG_RSTCCA);
5046         b43_phy_write(dev, B43_NPHY_BBCFG, tmp & ~B43_NPHY_BBCFG_RSTCCA);
5047         b43_phy_force_clock(dev, 0);
5048
5049         b43_mac_phy_clock_set(dev, true);
5050
5051         b43_nphy_pa_override(dev, false);
5052         b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX);
5053         b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
5054         b43_nphy_pa_override(dev, true);
5055
5056         b43_nphy_classifier(dev, 0, 0);
5057         b43_nphy_read_clip_detection(dev, clip);
5058         if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
5059                 b43_nphy_bphy_init(dev);
5060
5061         tx_pwr_state = nphy->txpwrctrl;
5062         b43_nphy_tx_power_ctrl(dev, false);
5063         b43_nphy_tx_power_fix(dev);
5064         b43_nphy_tx_power_ctl_idle_tssi(dev);
5065         b43_nphy_tx_power_ctl_setup(dev);
5066         b43_nphy_tx_gain_table_upload(dev);
5067
5068         if (nphy->phyrxchain != 3)
5069                 b43_nphy_set_rx_core_state(dev, nphy->phyrxchain);
5070         if (nphy->mphase_cal_phase_id > 0)
5071                 ;/* TODO PHY Periodic Calibration Multi-Phase Restart */
5072
5073         do_rssi_cal = false;
5074         if (phy->rev >= 3) {
5075                 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
5076                         do_rssi_cal = !nphy->rssical_chanspec_2G.center_freq;
5077                 else
5078                         do_rssi_cal = !nphy->rssical_chanspec_5G.center_freq;
5079
5080                 if (do_rssi_cal)
5081                         b43_nphy_rssi_cal(dev);
5082                 else
5083                         b43_nphy_restore_rssi_cal(dev);
5084         } else {
5085                 b43_nphy_rssi_cal(dev);
5086         }
5087
5088         if (!((nphy->measure_hold & 0x6) != 0)) {
5089                 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
5090                         do_cal = !nphy->iqcal_chanspec_2G.center_freq;
5091                 else
5092                         do_cal = !nphy->iqcal_chanspec_5G.center_freq;
5093
5094                 if (nphy->mute)
5095                         do_cal = false;
5096
5097                 if (do_cal) {
5098                         target = b43_nphy_get_tx_gains(dev);
5099
5100                         if (nphy->antsel_type == 2)
5101                                 b43_nphy_superswitch_init(dev, true);
5102                         if (nphy->perical != 2) {
5103                                 b43_nphy_rssi_cal(dev);
5104                                 if (phy->rev >= 3) {
5105                                         nphy->cal_orig_pwr_idx[0] =
5106                                             nphy->txpwrindex[0].index_internal;
5107                                         nphy->cal_orig_pwr_idx[1] =
5108                                             nphy->txpwrindex[1].index_internal;
5109                                         /* TODO N PHY Pre Calibrate TX Gain */
5110                                         target = b43_nphy_get_tx_gains(dev);
5111                                 }
5112                                 if (!b43_nphy_cal_tx_iq_lo(dev, target, true, false))
5113                                         if (b43_nphy_cal_rx_iq(dev, target, 2, 0) == 0)
5114                                                 b43_nphy_save_cal(dev);
5115                         } else if (nphy->mphase_cal_phase_id == 0)
5116                                 ;/* N PHY Periodic Calibration with arg 3 */
5117                 } else {
5118                         b43_nphy_restore_cal(dev);
5119                 }
5120         }
5121
5122         b43_nphy_tx_pwr_ctrl_coef_setup(dev);
5123         b43_nphy_tx_power_ctrl(dev, tx_pwr_state);
5124         b43_phy_write(dev, B43_NPHY_TXMACIF_HOLDOFF, 0x0015);
5125         b43_phy_write(dev, B43_NPHY_TXMACDELAY, 0x0320);
5126         if (phy->rev >= 3 && phy->rev <= 6)
5127                 b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x0014);
5128         b43_nphy_tx_lp_fbw(dev);
5129         if (phy->rev >= 3)
5130                 b43_nphy_spur_workaround(dev);
5131
5132         return 0;
5133 }
5134
5135 /**************************************************
5136  * Channel switching ops.
5137  **************************************************/
5138
5139 static void b43_chantab_phy_upload(struct b43_wldev *dev,
5140                                    const struct b43_phy_n_sfo_cfg *e)
5141 {
5142         b43_phy_write(dev, B43_NPHY_BW1A, e->phy_bw1a);
5143         b43_phy_write(dev, B43_NPHY_BW2, e->phy_bw2);
5144         b43_phy_write(dev, B43_NPHY_BW3, e->phy_bw3);
5145         b43_phy_write(dev, B43_NPHY_BW4, e->phy_bw4);
5146         b43_phy_write(dev, B43_NPHY_BW5, e->phy_bw5);
5147         b43_phy_write(dev, B43_NPHY_BW6, e->phy_bw6);
5148 }
5149
5150 /* http://bcm-v4.sipsolutions.net/802.11/PmuSpurAvoid */
5151 static void b43_nphy_pmu_spur_avoid(struct b43_wldev *dev, bool avoid)
5152 {
5153         switch (dev->dev->bus_type) {
5154 #ifdef CONFIG_B43_BCMA
5155         case B43_BUS_BCMA:
5156                 bcma_pmu_spuravoid_pllupdate(&dev->dev->bdev->bus->drv_cc,
5157                                              avoid);
5158                 break;
5159 #endif
5160 #ifdef CONFIG_B43_SSB
5161         case B43_BUS_SSB:
5162                 ssb_pmu_spuravoid_pllupdate(&dev->dev->sdev->bus->chipco,
5163                                             avoid);
5164                 break;
5165 #endif
5166         }
5167 }
5168
5169 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ChanspecSetup */
5170 static void b43_nphy_channel_setup(struct b43_wldev *dev,
5171                                 const struct b43_phy_n_sfo_cfg *e,
5172                                 struct ieee80211_channel *new_channel)
5173 {
5174         struct b43_phy *phy = &dev->phy;
5175         struct b43_phy_n *nphy = dev->phy.n;
5176         int ch = new_channel->hw_value;
5177
5178         u16 old_band_5ghz;
5179         u32 tmp32;
5180
5181         old_band_5ghz =
5182                 b43_phy_read(dev, B43_NPHY_BANDCTL) & B43_NPHY_BANDCTL_5GHZ;
5183         if (new_channel->band == IEEE80211_BAND_5GHZ && !old_band_5ghz) {
5184                 tmp32 = b43_read32(dev, B43_MMIO_PSM_PHY_HDR);
5185                 b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32 | 4);
5186                 b43_phy_set(dev, B43_PHY_B_BBCFG, 0xC000);
5187                 b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32);
5188                 b43_phy_set(dev, B43_NPHY_BANDCTL, B43_NPHY_BANDCTL_5GHZ);
5189         } else if (new_channel->band == IEEE80211_BAND_2GHZ && old_band_5ghz) {
5190                 b43_phy_mask(dev, B43_NPHY_BANDCTL, ~B43_NPHY_BANDCTL_5GHZ);
5191                 tmp32 = b43_read32(dev, B43_MMIO_PSM_PHY_HDR);
5192                 b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32 | 4);
5193                 b43_phy_mask(dev, B43_PHY_B_BBCFG, 0x3FFF);
5194                 b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32);
5195         }
5196
5197         b43_chantab_phy_upload(dev, e);
5198
5199         if (new_channel->hw_value == 14) {
5200                 b43_nphy_classifier(dev, 2, 0);
5201                 b43_phy_set(dev, B43_PHY_B_TEST, 0x0800);
5202         } else {
5203                 b43_nphy_classifier(dev, 2, 2);
5204                 if (new_channel->band == IEEE80211_BAND_2GHZ)
5205                         b43_phy_mask(dev, B43_PHY_B_TEST, ~0x840);
5206         }
5207
5208         if (!nphy->txpwrctrl)
5209                 b43_nphy_tx_power_fix(dev);
5210
5211         if (dev->phy.rev < 3)
5212                 b43_nphy_adjust_lna_gain_table(dev);
5213
5214         b43_nphy_tx_lp_fbw(dev);
5215
5216         if (dev->phy.rev >= 3 &&
5217             dev->phy.n->spur_avoid != B43_SPUR_AVOID_DISABLE) {
5218                 bool avoid = false;
5219                 if (dev->phy.n->spur_avoid == B43_SPUR_AVOID_FORCE) {
5220                         avoid = true;
5221                 } else if (!b43_channel_type_is_40mhz(phy->channel_type)) {
5222                         if ((ch >= 5 && ch <= 8) || ch == 13 || ch == 14)
5223                                 avoid = true;
5224                 } else { /* 40MHz */
5225                         if (nphy->aband_spurwar_en &&
5226                             (ch == 38 || ch == 102 || ch == 118))
5227                                 avoid = dev->dev->chip_id == 0x4716;
5228                 }
5229
5230                 b43_nphy_pmu_spur_avoid(dev, avoid);
5231
5232                 if (dev->dev->chip_id == 43222 || dev->dev->chip_id == 43224 ||
5233                     dev->dev->chip_id == 43225) {
5234                         b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW,
5235                                     avoid ? 0x5341 : 0x8889);
5236                         b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
5237                 }
5238
5239                 if (dev->phy.rev == 3 || dev->phy.rev == 4)
5240                         ; /* TODO: reset PLL */
5241
5242                 if (avoid)
5243                         b43_phy_set(dev, B43_NPHY_BBCFG, B43_NPHY_BBCFG_RSTRX);
5244                 else
5245                         b43_phy_mask(dev, B43_NPHY_BBCFG,
5246                                      ~B43_NPHY_BBCFG_RSTRX & 0xFFFF);
5247
5248                 b43_nphy_reset_cca(dev);
5249
5250                 /* wl sets useless phy_isspuravoid here */
5251         }
5252
5253         b43_phy_write(dev, B43_NPHY_NDATAT_DUP40, 0x3830);
5254
5255         if (phy->rev >= 3)
5256                 b43_nphy_spur_workaround(dev);
5257 }
5258
5259 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetChanspec */
5260 static int b43_nphy_set_channel(struct b43_wldev *dev,
5261                                 struct ieee80211_channel *channel,
5262                                 enum nl80211_channel_type channel_type)
5263 {
5264         struct b43_phy *phy = &dev->phy;
5265
5266         const struct b43_nphy_channeltab_entry_rev2 *tabent_r2 = NULL;
5267         const struct b43_nphy_channeltab_entry_rev3 *tabent_r3 = NULL;
5268
5269         u8 tmp;
5270
5271         if (dev->phy.rev >= 3) {
5272                 tabent_r3 = b43_nphy_get_chantabent_rev3(dev,
5273                                                         channel->center_freq);
5274                 if (!tabent_r3)
5275                         return -ESRCH;
5276         } else {
5277                 tabent_r2 = b43_nphy_get_chantabent_rev2(dev,
5278                                                         channel->hw_value);
5279                 if (!tabent_r2)
5280                         return -ESRCH;
5281         }
5282
5283         /* Channel is set later in common code, but we need to set it on our
5284            own to let this function's subcalls work properly. */
5285         phy->channel = channel->hw_value;
5286         phy->channel_freq = channel->center_freq;
5287
5288         if (b43_channel_type_is_40mhz(phy->channel_type) !=
5289                 b43_channel_type_is_40mhz(channel_type))
5290                 ; /* TODO: BMAC BW Set (channel_type) */
5291
5292         if (channel_type == NL80211_CHAN_HT40PLUS)
5293                 b43_phy_set(dev, B43_NPHY_RXCTL,
5294                                 B43_NPHY_RXCTL_BSELU20);
5295         else if (channel_type == NL80211_CHAN_HT40MINUS)
5296                 b43_phy_mask(dev, B43_NPHY_RXCTL,
5297                                 ~B43_NPHY_RXCTL_BSELU20);
5298
5299         if (dev->phy.rev >= 3) {
5300                 tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 4 : 0;
5301                 b43_radio_maskset(dev, 0x08, 0xFFFB, tmp);
5302                 b43_radio_2056_setup(dev, tabent_r3);
5303                 b43_nphy_channel_setup(dev, &(tabent_r3->phy_regs), channel);
5304         } else {
5305                 tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 0x0020 : 0x0050;
5306                 b43_radio_maskset(dev, B2055_MASTER1, 0xFF8F, tmp);
5307                 b43_radio_2055_setup(dev, tabent_r2);
5308                 b43_nphy_channel_setup(dev, &(tabent_r2->phy_regs), channel);
5309         }
5310
5311         return 0;
5312 }
5313
5314 /**************************************************
5315  * Basic PHY ops.
5316  **************************************************/
5317
5318 static int b43_nphy_op_allocate(struct b43_wldev *dev)
5319 {
5320         struct b43_phy_n *nphy;
5321
5322         nphy = kzalloc(sizeof(*nphy), GFP_KERNEL);
5323         if (!nphy)
5324                 return -ENOMEM;
5325         dev->phy.n = nphy;
5326
5327         return 0;
5328 }
5329
5330 static void b43_nphy_op_prepare_structs(struct b43_wldev *dev)
5331 {
5332         struct b43_phy *phy = &dev->phy;
5333         struct b43_phy_n *nphy = phy->n;
5334         struct ssb_sprom *sprom = dev->dev->bus_sprom;
5335
5336         memset(nphy, 0, sizeof(*nphy));
5337
5338         nphy->hang_avoid = (phy->rev == 3 || phy->rev == 4);
5339         nphy->spur_avoid = (phy->rev >= 3) ?
5340                                 B43_SPUR_AVOID_AUTO : B43_SPUR_AVOID_DISABLE;
5341         nphy->init_por = true;
5342         nphy->gain_boost = true; /* this way we follow wl, assume it is true */
5343         nphy->txrx_chain = 2; /* sth different than 0 and 1 for now */
5344         nphy->phyrxchain = 3; /* to avoid b43_nphy_set_rx_core_state like wl */
5345         nphy->perical = 2; /* avoid additional rssi cal on init (like wl) */
5346         /* 128 can mean disabled-by-default state of TX pwr ctl. Max value is
5347          * 0x7f == 127 and we check for 128 when restoring TX pwr ctl. */
5348         nphy->tx_pwr_idx[0] = 128;
5349         nphy->tx_pwr_idx[1] = 128;
5350
5351         /* Hardware TX power control and 5GHz power gain */
5352         nphy->txpwrctrl = false;
5353         nphy->pwg_gain_5ghz = false;
5354         if (dev->phy.rev >= 3 ||
5355             (dev->dev->board_vendor == PCI_VENDOR_ID_APPLE &&
5356              (dev->dev->core_rev == 11 || dev->dev->core_rev == 12))) {
5357                 nphy->txpwrctrl = true;
5358                 nphy->pwg_gain_5ghz = true;
5359         } else if (sprom->revision >= 4) {
5360                 if (dev->phy.rev >= 2 &&
5361                     (sprom->boardflags2_lo & B43_BFL2_TXPWRCTRL_EN)) {
5362                         nphy->txpwrctrl = true;
5363 #ifdef CONFIG_B43_SSB
5364                         if (dev->dev->bus_type == B43_BUS_SSB &&
5365                             dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI) {
5366                                 struct pci_dev *pdev =
5367                                         dev->dev->sdev->bus->host_pci;
5368                                 if (pdev->device == 0x4328 ||
5369                                     pdev->device == 0x432a)
5370                                         nphy->pwg_gain_5ghz = true;
5371                         }
5372 #endif
5373                 } else if (sprom->boardflags2_lo & B43_BFL2_5G_PWRGAIN) {
5374                         nphy->pwg_gain_5ghz = true;
5375                 }
5376         }
5377
5378         if (dev->phy.rev >= 3) {
5379                 nphy->ipa2g_on = sprom->fem.ghz2.extpa_gain == 2;
5380                 nphy->ipa5g_on = sprom->fem.ghz5.extpa_gain == 2;
5381         }
5382
5383         nphy->init_por = true;
5384 }
5385
5386 static void b43_nphy_op_free(struct b43_wldev *dev)
5387 {
5388         struct b43_phy *phy = &dev->phy;
5389         struct b43_phy_n *nphy = phy->n;
5390
5391         kfree(nphy);
5392         phy->n = NULL;
5393 }
5394
5395 static int b43_nphy_op_init(struct b43_wldev *dev)
5396 {
5397         return b43_phy_initn(dev);
5398 }
5399
5400 static inline void check_phyreg(struct b43_wldev *dev, u16 offset)
5401 {
5402 #if B43_DEBUG
5403         if ((offset & B43_PHYROUTE) == B43_PHYROUTE_OFDM_GPHY) {
5404                 /* OFDM registers are onnly available on A/G-PHYs */
5405                 b43err(dev->wl, "Invalid OFDM PHY access at "
5406                        "0x%04X on N-PHY\n", offset);
5407                 dump_stack();
5408         }
5409         if ((offset & B43_PHYROUTE) == B43_PHYROUTE_EXT_GPHY) {
5410                 /* Ext-G registers are only available on G-PHYs */
5411                 b43err(dev->wl, "Invalid EXT-G PHY access at "
5412                        "0x%04X on N-PHY\n", offset);
5413                 dump_stack();
5414         }
5415 #endif /* B43_DEBUG */
5416 }
5417
5418 static u16 b43_nphy_op_read(struct b43_wldev *dev, u16 reg)
5419 {
5420         check_phyreg(dev, reg);
5421         b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
5422         return b43_read16(dev, B43_MMIO_PHY_DATA);
5423 }
5424
5425 static void b43_nphy_op_write(struct b43_wldev *dev, u16 reg, u16 value)
5426 {
5427         check_phyreg(dev, reg);
5428         b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
5429         b43_write16(dev, B43_MMIO_PHY_DATA, value);
5430 }
5431
5432 static void b43_nphy_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
5433                                  u16 set)
5434 {
5435         check_phyreg(dev, reg);
5436         b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
5437         b43_maskset16(dev, B43_MMIO_PHY_DATA, mask, set);
5438 }
5439
5440 static u16 b43_nphy_op_radio_read(struct b43_wldev *dev, u16 reg)
5441 {
5442         /* Register 1 is a 32-bit register. */
5443         B43_WARN_ON(reg == 1);
5444         /* N-PHY needs 0x100 for read access */
5445         reg |= 0x100;
5446
5447         b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
5448         return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
5449 }
5450
5451 static void b43_nphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
5452 {
5453         /* Register 1 is a 32-bit register. */
5454         B43_WARN_ON(reg == 1);
5455
5456         b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
5457         b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
5458 }
5459
5460 /* http://bcm-v4.sipsolutions.net/802.11/Radio/Switch%20Radio */
5461 static void b43_nphy_op_software_rfkill(struct b43_wldev *dev,
5462                                         bool blocked)
5463 {
5464         if (b43_read32(dev, B43_MMIO_MACCTL) & B43_MACCTL_ENABLED)
5465                 b43err(dev->wl, "MAC not suspended\n");
5466
5467         if (blocked) {
5468                 b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
5469                                 ~B43_NPHY_RFCTL_CMD_CHIP0PU);
5470                 if (dev->phy.rev >= 7) {
5471                         /* TODO */
5472                 } else if (dev->phy.rev >= 3) {
5473                         b43_radio_mask(dev, 0x09, ~0x2);
5474
5475                         b43_radio_write(dev, 0x204D, 0);
5476                         b43_radio_write(dev, 0x2053, 0);
5477                         b43_radio_write(dev, 0x2058, 0);
5478                         b43_radio_write(dev, 0x205E, 0);
5479                         b43_radio_mask(dev, 0x2062, ~0xF0);
5480                         b43_radio_write(dev, 0x2064, 0);
5481
5482                         b43_radio_write(dev, 0x304D, 0);
5483                         b43_radio_write(dev, 0x3053, 0);
5484                         b43_radio_write(dev, 0x3058, 0);
5485                         b43_radio_write(dev, 0x305E, 0);
5486                         b43_radio_mask(dev, 0x3062, ~0xF0);
5487                         b43_radio_write(dev, 0x3064, 0);
5488                 }
5489         } else {
5490                 if (dev->phy.rev >= 7) {
5491                         b43_radio_2057_init(dev);
5492                         b43_switch_channel(dev, dev->phy.channel);
5493                 } else if (dev->phy.rev >= 3) {
5494                         b43_radio_init2056(dev);
5495                         b43_switch_channel(dev, dev->phy.channel);
5496                 } else {
5497                         b43_radio_init2055(dev);
5498                 }
5499         }
5500 }
5501
5502 /* http://bcm-v4.sipsolutions.net/802.11/PHY/Anacore */
5503 static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on)
5504 {
5505         u16 override = on ? 0x0 : 0x7FFF;
5506         u16 core = on ? 0xD : 0x00FD;
5507
5508         if (dev->phy.rev >= 3) {
5509                 if (on) {
5510                         b43_phy_write(dev, B43_NPHY_AFECTL_C1, core);
5511                         b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, override);
5512                         b43_phy_write(dev, B43_NPHY_AFECTL_C2, core);
5513                         b43_phy_write(dev, B43_NPHY_AFECTL_OVER, override);
5514                 } else {
5515                         b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, override);
5516                         b43_phy_write(dev, B43_NPHY_AFECTL_C1, core);
5517                         b43_phy_write(dev, B43_NPHY_AFECTL_OVER, override);
5518                         b43_phy_write(dev, B43_NPHY_AFECTL_C2, core);
5519                 }
5520         } else {
5521                 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, override);
5522         }
5523 }
5524
5525 static int b43_nphy_op_switch_channel(struct b43_wldev *dev,
5526                                       unsigned int new_channel)
5527 {
5528         struct ieee80211_channel *channel = dev->wl->hw->conf.chandef.chan;
5529         enum nl80211_channel_type channel_type =
5530                 cfg80211_get_chandef_type(&dev->wl->hw->conf.chandef);
5531
5532         if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
5533                 if ((new_channel < 1) || (new_channel > 14))
5534                         return -EINVAL;
5535         } else {
5536                 if (new_channel > 200)
5537                         return -EINVAL;
5538         }
5539
5540         return b43_nphy_set_channel(dev, channel, channel_type);
5541 }
5542
5543 static unsigned int b43_nphy_op_get_default_chan(struct b43_wldev *dev)
5544 {
5545         if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
5546                 return 1;
5547         return 36;
5548 }
5549
5550 const struct b43_phy_operations b43_phyops_n = {
5551         .allocate               = b43_nphy_op_allocate,
5552         .free                   = b43_nphy_op_free,
5553         .prepare_structs        = b43_nphy_op_prepare_structs,
5554         .init                   = b43_nphy_op_init,
5555         .phy_read               = b43_nphy_op_read,
5556         .phy_write              = b43_nphy_op_write,
5557         .phy_maskset            = b43_nphy_op_maskset,
5558         .radio_read             = b43_nphy_op_radio_read,
5559         .radio_write            = b43_nphy_op_radio_write,
5560         .software_rfkill        = b43_nphy_op_software_rfkill,
5561         .switch_analog          = b43_nphy_op_switch_analog,
5562         .switch_channel         = b43_nphy_op_switch_channel,
5563         .get_default_chan       = b43_nphy_op_get_default_chan,
5564         .recalc_txpower         = b43_nphy_op_recalc_txpower,
5565         .adjust_txpower         = b43_nphy_op_adjust_txpower,
5566 };