063db5c00ce7f81f678547b0152a130f4ed6261d
[pandora-kernel.git] / drivers / net / wireless / b43 / phy_g.c
1 /*
2
3   Broadcom B43 wireless driver
4   IEEE 802.11g PHY driver
5
6   Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
7   Copyright (c) 2005-2007 Stefano Brivio <stefano.brivio@polimi.it>
8   Copyright (c) 2005-2008 Michael Buesch <mb@bu3sch.de>
9   Copyright (c) 2005, 2006 Danny van Dyk <kugelfang@gentoo.org>
10   Copyright (c) 2005, 2006 Andreas Jaggi <andreas.jaggi@waterwave.ch>
11
12   This program is free software; you can redistribute it and/or modify
13   it under the terms of the GNU General Public License as published by
14   the Free Software Foundation; either version 2 of the License, or
15   (at your option) any later version.
16
17   This program is distributed in the hope that it will be useful,
18   but WITHOUT ANY WARRANTY; without even the implied warranty of
19   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20   GNU General Public License for more details.
21
22   You should have received a copy of the GNU General Public License
23   along with this program; see the file COPYING.  If not, write to
24   the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
25   Boston, MA 02110-1301, USA.
26
27 */
28
29 #include "b43.h"
30 #include "phy_g.h"
31 #include "phy_common.h"
32 #include "lo.h"
33 #include "main.h"
34
35 #include <linux/bitrev.h>
36
37
38 static const s8 b43_tssi2dbm_g_table[] = {
39         77, 77, 77, 76,
40         76, 76, 75, 75,
41         74, 74, 73, 73,
42         73, 72, 72, 71,
43         71, 70, 70, 69,
44         68, 68, 67, 67,
45         66, 65, 65, 64,
46         63, 63, 62, 61,
47         60, 59, 58, 57,
48         56, 55, 54, 53,
49         52, 50, 49, 47,
50         45, 43, 40, 37,
51         33, 28, 22, 14,
52         5, -7, -20, -20,
53         -20, -20, -20, -20,
54         -20, -20, -20, -20,
55 };
56
57 const u8 b43_radio_channel_codes_bg[] = {
58         12, 17, 22, 27,
59         32, 37, 42, 47,
60         52, 57, 62, 67,
61         72, 84,
62 };
63
64
65 static void b43_calc_nrssi_threshold(struct b43_wldev *dev);
66
67
68 #define bitrev4(tmp) (bitrev8(tmp) >> 4)
69
70
71 /* Get the freq, as it has to be written to the device. */
72 static inline u16 channel2freq_bg(u8 channel)
73 {
74         B43_WARN_ON(!(channel >= 1 && channel <= 14));
75
76         return b43_radio_channel_codes_bg[channel - 1];
77 }
78
79 static void generate_rfatt_list(struct b43_wldev *dev,
80                                 struct b43_rfatt_list *list)
81 {
82         struct b43_phy *phy = &dev->phy;
83
84         /* APHY.rev < 5 || GPHY.rev < 6 */
85         static const struct b43_rfatt rfatt_0[] = {
86                 {.att = 3,.with_padmix = 0,},
87                 {.att = 1,.with_padmix = 0,},
88                 {.att = 5,.with_padmix = 0,},
89                 {.att = 7,.with_padmix = 0,},
90                 {.att = 9,.with_padmix = 0,},
91                 {.att = 2,.with_padmix = 0,},
92                 {.att = 0,.with_padmix = 0,},
93                 {.att = 4,.with_padmix = 0,},
94                 {.att = 6,.with_padmix = 0,},
95                 {.att = 8,.with_padmix = 0,},
96                 {.att = 1,.with_padmix = 1,},
97                 {.att = 2,.with_padmix = 1,},
98                 {.att = 3,.with_padmix = 1,},
99                 {.att = 4,.with_padmix = 1,},
100         };
101         /* Radio.rev == 8 && Radio.version == 0x2050 */
102         static const struct b43_rfatt rfatt_1[] = {
103                 {.att = 2,.with_padmix = 1,},
104                 {.att = 4,.with_padmix = 1,},
105                 {.att = 6,.with_padmix = 1,},
106                 {.att = 8,.with_padmix = 1,},
107                 {.att = 10,.with_padmix = 1,},
108                 {.att = 12,.with_padmix = 1,},
109                 {.att = 14,.with_padmix = 1,},
110         };
111         /* Otherwise */
112         static const struct b43_rfatt rfatt_2[] = {
113                 {.att = 0,.with_padmix = 1,},
114                 {.att = 2,.with_padmix = 1,},
115                 {.att = 4,.with_padmix = 1,},
116                 {.att = 6,.with_padmix = 1,},
117                 {.att = 8,.with_padmix = 1,},
118                 {.att = 9,.with_padmix = 1,},
119                 {.att = 9,.with_padmix = 1,},
120         };
121
122         if (!b43_has_hardware_pctl(dev)) {
123                 /* Software pctl */
124                 list->list = rfatt_0;
125                 list->len = ARRAY_SIZE(rfatt_0);
126                 list->min_val = 0;
127                 list->max_val = 9;
128                 return;
129         }
130         if (phy->radio_ver == 0x2050 && phy->radio_rev == 8) {
131                 /* Hardware pctl */
132                 list->list = rfatt_1;
133                 list->len = ARRAY_SIZE(rfatt_1);
134                 list->min_val = 0;
135                 list->max_val = 14;
136                 return;
137         }
138         /* Hardware pctl */
139         list->list = rfatt_2;
140         list->len = ARRAY_SIZE(rfatt_2);
141         list->min_val = 0;
142         list->max_val = 9;
143 }
144
145 static void generate_bbatt_list(struct b43_wldev *dev,
146                                 struct b43_bbatt_list *list)
147 {
148         static const struct b43_bbatt bbatt_0[] = {
149                 {.att = 0,},
150                 {.att = 1,},
151                 {.att = 2,},
152                 {.att = 3,},
153                 {.att = 4,},
154                 {.att = 5,},
155                 {.att = 6,},
156                 {.att = 7,},
157                 {.att = 8,},
158         };
159
160         list->list = bbatt_0;
161         list->len = ARRAY_SIZE(bbatt_0);
162         list->min_val = 0;
163         list->max_val = 8;
164 }
165
166 static void b43_shm_clear_tssi(struct b43_wldev *dev)
167 {
168         b43_shm_write16(dev, B43_SHM_SHARED, 0x0058, 0x7F7F);
169         b43_shm_write16(dev, B43_SHM_SHARED, 0x005a, 0x7F7F);
170         b43_shm_write16(dev, B43_SHM_SHARED, 0x0070, 0x7F7F);
171         b43_shm_write16(dev, B43_SHM_SHARED, 0x0072, 0x7F7F);
172 }
173
174 /* Synthetic PU workaround */
175 static void b43_synth_pu_workaround(struct b43_wldev *dev, u8 channel)
176 {
177         struct b43_phy *phy = &dev->phy;
178
179         might_sleep();
180
181         if (phy->radio_ver != 0x2050 || phy->radio_rev >= 6) {
182                 /* We do not need the workaround. */
183                 return;
184         }
185
186         if (channel <= 10) {
187                 b43_write16(dev, B43_MMIO_CHANNEL,
188                             channel2freq_bg(channel + 4));
189         } else {
190                 b43_write16(dev, B43_MMIO_CHANNEL, channel2freq_bg(1));
191         }
192         msleep(1);
193         b43_write16(dev, B43_MMIO_CHANNEL, channel2freq_bg(channel));
194 }
195
196 /* Set the baseband attenuation value on chip. */
197 void b43_gphy_set_baseband_attenuation(struct b43_wldev *dev,
198                                        u16 baseband_attenuation)
199 {
200         struct b43_phy *phy = &dev->phy;
201
202         if (phy->analog == 0) {
203                 b43_write16(dev, B43_MMIO_PHY0, (b43_read16(dev, B43_MMIO_PHY0)
204                                                  & 0xFFF0) |
205                             baseband_attenuation);
206         } else if (phy->analog > 1) {
207                 b43_phy_write(dev, B43_PHY_DACCTL,
208                               (b43_phy_read(dev, B43_PHY_DACCTL)
209                                & 0xFFC3) | (baseband_attenuation << 2));
210         } else {
211                 b43_phy_write(dev, B43_PHY_DACCTL,
212                               (b43_phy_read(dev, B43_PHY_DACCTL)
213                                & 0xFF87) | (baseband_attenuation << 3));
214         }
215 }
216
217 /* Adjust the transmission power output (G-PHY) */
218 void b43_set_txpower_g(struct b43_wldev *dev,
219                        const struct b43_bbatt *bbatt,
220                        const struct b43_rfatt *rfatt, u8 tx_control)
221 {
222         struct b43_phy *phy = &dev->phy;
223         struct b43_phy_g *gphy = phy->g;
224         struct b43_txpower_lo_control *lo = gphy->lo_control;
225         u16 bb, rf;
226         u16 tx_bias, tx_magn;
227
228         bb = bbatt->att;
229         rf = rfatt->att;
230         tx_bias = lo->tx_bias;
231         tx_magn = lo->tx_magn;
232         if (unlikely(tx_bias == 0xFF))
233                 tx_bias = 0;
234
235         /* Save the values for later. Use memmove, because it's valid
236          * to pass &gphy->rfatt as rfatt pointer argument. Same for bbatt. */
237         gphy->tx_control = tx_control;
238         memmove(&gphy->rfatt, rfatt, sizeof(*rfatt));
239         gphy->rfatt.with_padmix = !!(tx_control & B43_TXCTL_TXMIX);
240         memmove(&gphy->bbatt, bbatt, sizeof(*bbatt));
241
242         if (b43_debug(dev, B43_DBG_XMITPOWER)) {
243                 b43dbg(dev->wl, "Tuning TX-power to bbatt(%u), "
244                        "rfatt(%u), tx_control(0x%02X), "
245                        "tx_bias(0x%02X), tx_magn(0x%02X)\n",
246                        bb, rf, tx_control, tx_bias, tx_magn);
247         }
248
249         b43_gphy_set_baseband_attenuation(dev, bb);
250         b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_RFATT, rf);
251         if (phy->radio_ver == 0x2050 && phy->radio_rev == 8) {
252                 b43_radio_write16(dev, 0x43,
253                                   (rf & 0x000F) | (tx_control & 0x0070));
254         } else {
255                 b43_radio_write16(dev, 0x43, (b43_radio_read16(dev, 0x43)
256                                               & 0xFFF0) | (rf & 0x000F));
257                 b43_radio_write16(dev, 0x52, (b43_radio_read16(dev, 0x52)
258                                               & ~0x0070) | (tx_control &
259                                                             0x0070));
260         }
261         if (has_tx_magnification(phy)) {
262                 b43_radio_write16(dev, 0x52, tx_magn | tx_bias);
263         } else {
264                 b43_radio_write16(dev, 0x52, (b43_radio_read16(dev, 0x52)
265                                               & 0xFFF0) | (tx_bias & 0x000F));
266         }
267         b43_lo_g_adjust(dev);
268 }
269
270 /* GPHY_TSSI_Power_Lookup_Table_Init */
271 static void b43_gphy_tssi_power_lt_init(struct b43_wldev *dev)
272 {
273         struct b43_phy_g *gphy = dev->phy.g;
274         int i;
275         u16 value;
276
277         for (i = 0; i < 32; i++)
278                 b43_ofdmtab_write16(dev, 0x3C20, i, gphy->tssi2dbm[i]);
279         for (i = 32; i < 64; i++)
280                 b43_ofdmtab_write16(dev, 0x3C00, i - 32, gphy->tssi2dbm[i]);
281         for (i = 0; i < 64; i += 2) {
282                 value = (u16) gphy->tssi2dbm[i];
283                 value |= ((u16) gphy->tssi2dbm[i + 1]) << 8;
284                 b43_phy_write(dev, 0x380 + (i / 2), value);
285         }
286 }
287
288 /* GPHY_Gain_Lookup_Table_Init */
289 static void b43_gphy_gain_lt_init(struct b43_wldev *dev)
290 {
291         struct b43_phy *phy = &dev->phy;
292         struct b43_phy_g *gphy = phy->g;
293         struct b43_txpower_lo_control *lo = gphy->lo_control;
294         u16 nr_written = 0;
295         u16 tmp;
296         u8 rf, bb;
297
298         for (rf = 0; rf < lo->rfatt_list.len; rf++) {
299                 for (bb = 0; bb < lo->bbatt_list.len; bb++) {
300                         if (nr_written >= 0x40)
301                                 return;
302                         tmp = lo->bbatt_list.list[bb].att;
303                         tmp <<= 8;
304                         if (phy->radio_rev == 8)
305                                 tmp |= 0x50;
306                         else
307                                 tmp |= 0x40;
308                         tmp |= lo->rfatt_list.list[rf].att;
309                         b43_phy_write(dev, 0x3C0 + nr_written, tmp);
310                         nr_written++;
311                 }
312         }
313 }
314
315 static void b43_set_all_gains(struct b43_wldev *dev,
316                               s16 first, s16 second, s16 third)
317 {
318         struct b43_phy *phy = &dev->phy;
319         u16 i;
320         u16 start = 0x08, end = 0x18;
321         u16 tmp;
322         u16 table;
323
324         if (phy->rev <= 1) {
325                 start = 0x10;
326                 end = 0x20;
327         }
328
329         table = B43_OFDMTAB_GAINX;
330         if (phy->rev <= 1)
331                 table = B43_OFDMTAB_GAINX_R1;
332         for (i = 0; i < 4; i++)
333                 b43_ofdmtab_write16(dev, table, i, first);
334
335         for (i = start; i < end; i++)
336                 b43_ofdmtab_write16(dev, table, i, second);
337
338         if (third != -1) {
339                 tmp = ((u16) third << 14) | ((u16) third << 6);
340                 b43_phy_write(dev, 0x04A0,
341                               (b43_phy_read(dev, 0x04A0) & 0xBFBF) | tmp);
342                 b43_phy_write(dev, 0x04A1,
343                               (b43_phy_read(dev, 0x04A1) & 0xBFBF) | tmp);
344                 b43_phy_write(dev, 0x04A2,
345                               (b43_phy_read(dev, 0x04A2) & 0xBFBF) | tmp);
346         }
347         b43_dummy_transmission(dev);
348 }
349
350 static void b43_set_original_gains(struct b43_wldev *dev)
351 {
352         struct b43_phy *phy = &dev->phy;
353         u16 i, tmp;
354         u16 table;
355         u16 start = 0x0008, end = 0x0018;
356
357         if (phy->rev <= 1) {
358                 start = 0x0010;
359                 end = 0x0020;
360         }
361
362         table = B43_OFDMTAB_GAINX;
363         if (phy->rev <= 1)
364                 table = B43_OFDMTAB_GAINX_R1;
365         for (i = 0; i < 4; i++) {
366                 tmp = (i & 0xFFFC);
367                 tmp |= (i & 0x0001) << 1;
368                 tmp |= (i & 0x0002) >> 1;
369
370                 b43_ofdmtab_write16(dev, table, i, tmp);
371         }
372
373         for (i = start; i < end; i++)
374                 b43_ofdmtab_write16(dev, table, i, i - start);
375
376         b43_phy_write(dev, 0x04A0,
377                       (b43_phy_read(dev, 0x04A0) & 0xBFBF) | 0x4040);
378         b43_phy_write(dev, 0x04A1,
379                       (b43_phy_read(dev, 0x04A1) & 0xBFBF) | 0x4040);
380         b43_phy_write(dev, 0x04A2,
381                       (b43_phy_read(dev, 0x04A2) & 0xBFBF) | 0x4000);
382         b43_dummy_transmission(dev);
383 }
384
385 /* http://bcm-specs.sipsolutions.net/NRSSILookupTable */
386 void b43_nrssi_hw_write(struct b43_wldev *dev, u16 offset, s16 val)
387 {
388         b43_phy_write(dev, B43_PHY_NRSSILT_CTRL, offset);
389         mmiowb();
390         b43_phy_write(dev, B43_PHY_NRSSILT_DATA, (u16) val);
391 }
392
393 /* http://bcm-specs.sipsolutions.net/NRSSILookupTable */
394 s16 b43_nrssi_hw_read(struct b43_wldev *dev, u16 offset)
395 {
396         u16 val;
397
398         b43_phy_write(dev, B43_PHY_NRSSILT_CTRL, offset);
399         val = b43_phy_read(dev, B43_PHY_NRSSILT_DATA);
400
401         return (s16) val;
402 }
403
404 /* http://bcm-specs.sipsolutions.net/NRSSILookupTable */
405 void b43_nrssi_hw_update(struct b43_wldev *dev, u16 val)
406 {
407         u16 i;
408         s16 tmp;
409
410         for (i = 0; i < 64; i++) {
411                 tmp = b43_nrssi_hw_read(dev, i);
412                 tmp -= val;
413                 tmp = clamp_val(tmp, -32, 31);
414                 b43_nrssi_hw_write(dev, i, tmp);
415         }
416 }
417
418 /* http://bcm-specs.sipsolutions.net/NRSSILookupTable */
419 void b43_nrssi_mem_update(struct b43_wldev *dev)
420 {
421         struct b43_phy_g *gphy = dev->phy.g;
422         s16 i, delta;
423         s32 tmp;
424
425         delta = 0x1F - gphy->nrssi[0];
426         for (i = 0; i < 64; i++) {
427                 tmp = (i - delta) * gphy->nrssislope;
428                 tmp /= 0x10000;
429                 tmp += 0x3A;
430                 tmp = clamp_val(tmp, 0, 0x3F);
431                 gphy->nrssi_lt[i] = tmp;
432         }
433 }
434
435 static void b43_calc_nrssi_offset(struct b43_wldev *dev)
436 {
437         struct b43_phy *phy = &dev->phy;
438         u16 backup[20] = { 0 };
439         s16 v47F;
440         u16 i;
441         u16 saved = 0xFFFF;
442
443         backup[0] = b43_phy_read(dev, 0x0001);
444         backup[1] = b43_phy_read(dev, 0x0811);
445         backup[2] = b43_phy_read(dev, 0x0812);
446         if (phy->rev != 1) {    /* Not in specs, but needed to prevent PPC machine check */
447                 backup[3] = b43_phy_read(dev, 0x0814);
448                 backup[4] = b43_phy_read(dev, 0x0815);
449         }
450         backup[5] = b43_phy_read(dev, 0x005A);
451         backup[6] = b43_phy_read(dev, 0x0059);
452         backup[7] = b43_phy_read(dev, 0x0058);
453         backup[8] = b43_phy_read(dev, 0x000A);
454         backup[9] = b43_phy_read(dev, 0x0003);
455         backup[10] = b43_radio_read16(dev, 0x007A);
456         backup[11] = b43_radio_read16(dev, 0x0043);
457
458         b43_phy_write(dev, 0x0429, b43_phy_read(dev, 0x0429) & 0x7FFF);
459         b43_phy_write(dev, 0x0001,
460                       (b43_phy_read(dev, 0x0001) & 0x3FFF) | 0x4000);
461         b43_phy_write(dev, 0x0811, b43_phy_read(dev, 0x0811) | 0x000C);
462         b43_phy_write(dev, 0x0812,
463                       (b43_phy_read(dev, 0x0812) & 0xFFF3) | 0x0004);
464         b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) & ~(0x1 | 0x2));
465         if (phy->rev >= 6) {
466                 backup[12] = b43_phy_read(dev, 0x002E);
467                 backup[13] = b43_phy_read(dev, 0x002F);
468                 backup[14] = b43_phy_read(dev, 0x080F);
469                 backup[15] = b43_phy_read(dev, 0x0810);
470                 backup[16] = b43_phy_read(dev, 0x0801);
471                 backup[17] = b43_phy_read(dev, 0x0060);
472                 backup[18] = b43_phy_read(dev, 0x0014);
473                 backup[19] = b43_phy_read(dev, 0x0478);
474
475                 b43_phy_write(dev, 0x002E, 0);
476                 b43_phy_write(dev, 0x002F, 0);
477                 b43_phy_write(dev, 0x080F, 0);
478                 b43_phy_write(dev, 0x0810, 0);
479                 b43_phy_write(dev, 0x0478, b43_phy_read(dev, 0x0478) | 0x0100);
480                 b43_phy_write(dev, 0x0801, b43_phy_read(dev, 0x0801) | 0x0040);
481                 b43_phy_write(dev, 0x0060, b43_phy_read(dev, 0x0060) | 0x0040);
482                 b43_phy_write(dev, 0x0014, b43_phy_read(dev, 0x0014) | 0x0200);
483         }
484         b43_radio_write16(dev, 0x007A, b43_radio_read16(dev, 0x007A) | 0x0070);
485         b43_radio_write16(dev, 0x007A, b43_radio_read16(dev, 0x007A) | 0x0080);
486         udelay(30);
487
488         v47F = (s16) ((b43_phy_read(dev, 0x047F) >> 8) & 0x003F);
489         if (v47F >= 0x20)
490                 v47F -= 0x40;
491         if (v47F == 31) {
492                 for (i = 7; i >= 4; i--) {
493                         b43_radio_write16(dev, 0x007B, i);
494                         udelay(20);
495                         v47F =
496                             (s16) ((b43_phy_read(dev, 0x047F) >> 8) & 0x003F);
497                         if (v47F >= 0x20)
498                                 v47F -= 0x40;
499                         if (v47F < 31 && saved == 0xFFFF)
500                                 saved = i;
501                 }
502                 if (saved == 0xFFFF)
503                         saved = 4;
504         } else {
505                 b43_radio_write16(dev, 0x007A,
506                                   b43_radio_read16(dev, 0x007A) & 0x007F);
507                 if (phy->rev != 1) {    /* Not in specs, but needed to prevent PPC machine check */
508                         b43_phy_write(dev, 0x0814,
509                                       b43_phy_read(dev, 0x0814) | 0x0001);
510                         b43_phy_write(dev, 0x0815,
511                                       b43_phy_read(dev, 0x0815) & 0xFFFE);
512                 }
513                 b43_phy_write(dev, 0x0811, b43_phy_read(dev, 0x0811) | 0x000C);
514                 b43_phy_write(dev, 0x0812, b43_phy_read(dev, 0x0812) | 0x000C);
515                 b43_phy_write(dev, 0x0811, b43_phy_read(dev, 0x0811) | 0x0030);
516                 b43_phy_write(dev, 0x0812, b43_phy_read(dev, 0x0812) | 0x0030);
517                 b43_phy_write(dev, 0x005A, 0x0480);
518                 b43_phy_write(dev, 0x0059, 0x0810);
519                 b43_phy_write(dev, 0x0058, 0x000D);
520                 if (phy->rev == 0) {
521                         b43_phy_write(dev, 0x0003, 0x0122);
522                 } else {
523                         b43_phy_write(dev, 0x000A, b43_phy_read(dev, 0x000A)
524                                       | 0x2000);
525                 }
526                 if (phy->rev != 1) {    /* Not in specs, but needed to prevent PPC machine check */
527                         b43_phy_write(dev, 0x0814,
528                                       b43_phy_read(dev, 0x0814) | 0x0004);
529                         b43_phy_write(dev, 0x0815,
530                                       b43_phy_read(dev, 0x0815) & 0xFFFB);
531                 }
532                 b43_phy_write(dev, 0x0003, (b43_phy_read(dev, 0x0003) & 0xFF9F)
533                               | 0x0040);
534                 b43_radio_write16(dev, 0x007A,
535                                   b43_radio_read16(dev, 0x007A) | 0x000F);
536                 b43_set_all_gains(dev, 3, 0, 1);
537                 b43_radio_write16(dev, 0x0043, (b43_radio_read16(dev, 0x0043)
538                                                 & 0x00F0) | 0x000F);
539                 udelay(30);
540                 v47F = (s16) ((b43_phy_read(dev, 0x047F) >> 8) & 0x003F);
541                 if (v47F >= 0x20)
542                         v47F -= 0x40;
543                 if (v47F == -32) {
544                         for (i = 0; i < 4; i++) {
545                                 b43_radio_write16(dev, 0x007B, i);
546                                 udelay(20);
547                                 v47F =
548                                     (s16) ((b43_phy_read(dev, 0x047F) >> 8) &
549                                            0x003F);
550                                 if (v47F >= 0x20)
551                                         v47F -= 0x40;
552                                 if (v47F > -31 && saved == 0xFFFF)
553                                         saved = i;
554                         }
555                         if (saved == 0xFFFF)
556                                 saved = 3;
557                 } else
558                         saved = 0;
559         }
560         b43_radio_write16(dev, 0x007B, saved);
561
562         if (phy->rev >= 6) {
563                 b43_phy_write(dev, 0x002E, backup[12]);
564                 b43_phy_write(dev, 0x002F, backup[13]);
565                 b43_phy_write(dev, 0x080F, backup[14]);
566                 b43_phy_write(dev, 0x0810, backup[15]);
567         }
568         if (phy->rev != 1) {    /* Not in specs, but needed to prevent PPC machine check */
569                 b43_phy_write(dev, 0x0814, backup[3]);
570                 b43_phy_write(dev, 0x0815, backup[4]);
571         }
572         b43_phy_write(dev, 0x005A, backup[5]);
573         b43_phy_write(dev, 0x0059, backup[6]);
574         b43_phy_write(dev, 0x0058, backup[7]);
575         b43_phy_write(dev, 0x000A, backup[8]);
576         b43_phy_write(dev, 0x0003, backup[9]);
577         b43_radio_write16(dev, 0x0043, backup[11]);
578         b43_radio_write16(dev, 0x007A, backup[10]);
579         b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) | 0x1 | 0x2);
580         b43_phy_write(dev, 0x0429, b43_phy_read(dev, 0x0429) | 0x8000);
581         b43_set_original_gains(dev);
582         if (phy->rev >= 6) {
583                 b43_phy_write(dev, 0x0801, backup[16]);
584                 b43_phy_write(dev, 0x0060, backup[17]);
585                 b43_phy_write(dev, 0x0014, backup[18]);
586                 b43_phy_write(dev, 0x0478, backup[19]);
587         }
588         b43_phy_write(dev, 0x0001, backup[0]);
589         b43_phy_write(dev, 0x0812, backup[2]);
590         b43_phy_write(dev, 0x0811, backup[1]);
591 }
592
593 void b43_calc_nrssi_slope(struct b43_wldev *dev)
594 {
595         struct b43_phy *phy = &dev->phy;
596         struct b43_phy_g *gphy = phy->g;
597         u16 backup[18] = { 0 };
598         u16 tmp;
599         s16 nrssi0, nrssi1;
600
601         B43_WARN_ON(phy->type != B43_PHYTYPE_G);
602
603         if (phy->radio_rev >= 9)
604                 return;
605         if (phy->radio_rev == 8)
606                 b43_calc_nrssi_offset(dev);
607
608         b43_phy_write(dev, B43_PHY_G_CRS,
609                       b43_phy_read(dev, B43_PHY_G_CRS) & 0x7FFF);
610         b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) & 0xFFFC);
611         backup[7] = b43_read16(dev, 0x03E2);
612         b43_write16(dev, 0x03E2, b43_read16(dev, 0x03E2) | 0x8000);
613         backup[0] = b43_radio_read16(dev, 0x007A);
614         backup[1] = b43_radio_read16(dev, 0x0052);
615         backup[2] = b43_radio_read16(dev, 0x0043);
616         backup[3] = b43_phy_read(dev, 0x0015);
617         backup[4] = b43_phy_read(dev, 0x005A);
618         backup[5] = b43_phy_read(dev, 0x0059);
619         backup[6] = b43_phy_read(dev, 0x0058);
620         backup[8] = b43_read16(dev, 0x03E6);
621         backup[9] = b43_read16(dev, B43_MMIO_CHANNEL_EXT);
622         if (phy->rev >= 3) {
623                 backup[10] = b43_phy_read(dev, 0x002E);
624                 backup[11] = b43_phy_read(dev, 0x002F);
625                 backup[12] = b43_phy_read(dev, 0x080F);
626                 backup[13] = b43_phy_read(dev, B43_PHY_G_LO_CONTROL);
627                 backup[14] = b43_phy_read(dev, 0x0801);
628                 backup[15] = b43_phy_read(dev, 0x0060);
629                 backup[16] = b43_phy_read(dev, 0x0014);
630                 backup[17] = b43_phy_read(dev, 0x0478);
631                 b43_phy_write(dev, 0x002E, 0);
632                 b43_phy_write(dev, B43_PHY_G_LO_CONTROL, 0);
633                 switch (phy->rev) {
634                 case 4:
635                 case 6:
636                 case 7:
637                         b43_phy_write(dev, 0x0478,
638                                       b43_phy_read(dev, 0x0478)
639                                       | 0x0100);
640                         b43_phy_write(dev, 0x0801,
641                                       b43_phy_read(dev, 0x0801)
642                                       | 0x0040);
643                         break;
644                 case 3:
645                 case 5:
646                         b43_phy_write(dev, 0x0801,
647                                       b43_phy_read(dev, 0x0801)
648                                       & 0xFFBF);
649                         break;
650                 }
651                 b43_phy_write(dev, 0x0060, b43_phy_read(dev, 0x0060)
652                               | 0x0040);
653                 b43_phy_write(dev, 0x0014, b43_phy_read(dev, 0x0014)
654                               | 0x0200);
655         }
656         b43_radio_write16(dev, 0x007A,
657                           b43_radio_read16(dev, 0x007A) | 0x0070);
658         b43_set_all_gains(dev, 0, 8, 0);
659         b43_radio_write16(dev, 0x007A,
660                           b43_radio_read16(dev, 0x007A) & 0x00F7);
661         if (phy->rev >= 2) {
662                 b43_phy_write(dev, 0x0811,
663                               (b43_phy_read(dev, 0x0811) & 0xFFCF) |
664                               0x0030);
665                 b43_phy_write(dev, 0x0812,
666                               (b43_phy_read(dev, 0x0812) & 0xFFCF) |
667                               0x0010);
668         }
669         b43_radio_write16(dev, 0x007A,
670                           b43_radio_read16(dev, 0x007A) | 0x0080);
671         udelay(20);
672
673         nrssi0 = (s16) ((b43_phy_read(dev, 0x047F) >> 8) & 0x003F);
674         if (nrssi0 >= 0x0020)
675                 nrssi0 -= 0x0040;
676
677         b43_radio_write16(dev, 0x007A,
678                           b43_radio_read16(dev, 0x007A) & 0x007F);
679         if (phy->rev >= 2) {
680                 b43_phy_write(dev, 0x0003, (b43_phy_read(dev, 0x0003)
681                                             & 0xFF9F) | 0x0040);
682         }
683
684         b43_write16(dev, B43_MMIO_CHANNEL_EXT,
685                     b43_read16(dev, B43_MMIO_CHANNEL_EXT)
686                     | 0x2000);
687         b43_radio_write16(dev, 0x007A,
688                           b43_radio_read16(dev, 0x007A) | 0x000F);
689         b43_phy_write(dev, 0x0015, 0xF330);
690         if (phy->rev >= 2) {
691                 b43_phy_write(dev, 0x0812,
692                               (b43_phy_read(dev, 0x0812) & 0xFFCF) |
693                               0x0020);
694                 b43_phy_write(dev, 0x0811,
695                               (b43_phy_read(dev, 0x0811) & 0xFFCF) |
696                               0x0020);
697         }
698
699         b43_set_all_gains(dev, 3, 0, 1);
700         if (phy->radio_rev == 8) {
701                 b43_radio_write16(dev, 0x0043, 0x001F);
702         } else {
703                 tmp = b43_radio_read16(dev, 0x0052) & 0xFF0F;
704                 b43_radio_write16(dev, 0x0052, tmp | 0x0060);
705                 tmp = b43_radio_read16(dev, 0x0043) & 0xFFF0;
706                 b43_radio_write16(dev, 0x0043, tmp | 0x0009);
707         }
708         b43_phy_write(dev, 0x005A, 0x0480);
709         b43_phy_write(dev, 0x0059, 0x0810);
710         b43_phy_write(dev, 0x0058, 0x000D);
711         udelay(20);
712         nrssi1 = (s16) ((b43_phy_read(dev, 0x047F) >> 8) & 0x003F);
713         if (nrssi1 >= 0x0020)
714                 nrssi1 -= 0x0040;
715         if (nrssi0 == nrssi1)
716                 gphy->nrssislope = 0x00010000;
717         else
718                 gphy->nrssislope = 0x00400000 / (nrssi0 - nrssi1);
719         if (nrssi0 >= -4) {
720                 gphy->nrssi[0] = nrssi1;
721                 gphy->nrssi[1] = nrssi0;
722         }
723         if (phy->rev >= 3) {
724                 b43_phy_write(dev, 0x002E, backup[10]);
725                 b43_phy_write(dev, 0x002F, backup[11]);
726                 b43_phy_write(dev, 0x080F, backup[12]);
727                 b43_phy_write(dev, B43_PHY_G_LO_CONTROL, backup[13]);
728         }
729         if (phy->rev >= 2) {
730                 b43_phy_write(dev, 0x0812,
731                               b43_phy_read(dev, 0x0812) & 0xFFCF);
732                 b43_phy_write(dev, 0x0811,
733                               b43_phy_read(dev, 0x0811) & 0xFFCF);
734         }
735
736         b43_radio_write16(dev, 0x007A, backup[0]);
737         b43_radio_write16(dev, 0x0052, backup[1]);
738         b43_radio_write16(dev, 0x0043, backup[2]);
739         b43_write16(dev, 0x03E2, backup[7]);
740         b43_write16(dev, 0x03E6, backup[8]);
741         b43_write16(dev, B43_MMIO_CHANNEL_EXT, backup[9]);
742         b43_phy_write(dev, 0x0015, backup[3]);
743         b43_phy_write(dev, 0x005A, backup[4]);
744         b43_phy_write(dev, 0x0059, backup[5]);
745         b43_phy_write(dev, 0x0058, backup[6]);
746         b43_synth_pu_workaround(dev, phy->channel);
747         b43_phy_write(dev, 0x0802,
748                       b43_phy_read(dev, 0x0802) | (0x0001 | 0x0002));
749         b43_set_original_gains(dev);
750         b43_phy_write(dev, B43_PHY_G_CRS,
751                       b43_phy_read(dev, B43_PHY_G_CRS) | 0x8000);
752         if (phy->rev >= 3) {
753                 b43_phy_write(dev, 0x0801, backup[14]);
754                 b43_phy_write(dev, 0x0060, backup[15]);
755                 b43_phy_write(dev, 0x0014, backup[16]);
756                 b43_phy_write(dev, 0x0478, backup[17]);
757         }
758         b43_nrssi_mem_update(dev);
759         b43_calc_nrssi_threshold(dev);
760 }
761
762 static void b43_calc_nrssi_threshold(struct b43_wldev *dev)
763 {
764         struct b43_phy *phy = &dev->phy;
765         struct b43_phy_g *gphy = phy->g;
766         s32 a, b;
767         s16 tmp16;
768         u16 tmp_u16;
769
770         B43_WARN_ON(phy->type != B43_PHYTYPE_G);
771
772         if (!phy->gmode ||
773             !(dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) {
774                 tmp16 = b43_nrssi_hw_read(dev, 0x20);
775                 if (tmp16 >= 0x20)
776                         tmp16 -= 0x40;
777                 if (tmp16 < 3) {
778                         b43_phy_write(dev, 0x048A,
779                                       (b43_phy_read(dev, 0x048A)
780                                        & 0xF000) | 0x09EB);
781                 } else {
782                         b43_phy_write(dev, 0x048A,
783                                       (b43_phy_read(dev, 0x048A)
784                                        & 0xF000) | 0x0AED);
785                 }
786         } else {
787                 if (gphy->interfmode == B43_INTERFMODE_NONWLAN) {
788                         a = 0xE;
789                         b = 0xA;
790                 } else if (!gphy->aci_wlan_automatic && gphy->aci_enable) {
791                         a = 0x13;
792                         b = 0x12;
793                 } else {
794                         a = 0xE;
795                         b = 0x11;
796                 }
797
798                 a = a * (gphy->nrssi[1] - gphy->nrssi[0]);
799                 a += (gphy->nrssi[0] << 6);
800                 if (a < 32)
801                         a += 31;
802                 else
803                         a += 32;
804                 a = a >> 6;
805                 a = clamp_val(a, -31, 31);
806
807                 b = b * (gphy->nrssi[1] - gphy->nrssi[0]);
808                 b += (gphy->nrssi[0] << 6);
809                 if (b < 32)
810                         b += 31;
811                 else
812                         b += 32;
813                 b = b >> 6;
814                 b = clamp_val(b, -31, 31);
815
816                 tmp_u16 = b43_phy_read(dev, 0x048A) & 0xF000;
817                 tmp_u16 |= ((u32) b & 0x0000003F);
818                 tmp_u16 |= (((u32) a & 0x0000003F) << 6);
819                 b43_phy_write(dev, 0x048A, tmp_u16);
820         }
821 }
822
823 /* Stack implementation to save/restore values from the
824  * interference mitigation code.
825  * It is save to restore values in random order.
826  */
827 static void _stack_save(u32 * _stackptr, size_t * stackidx,
828                         u8 id, u16 offset, u16 value)
829 {
830         u32 *stackptr = &(_stackptr[*stackidx]);
831
832         B43_WARN_ON(offset & 0xF000);
833         B43_WARN_ON(id & 0xF0);
834         *stackptr = offset;
835         *stackptr |= ((u32) id) << 12;
836         *stackptr |= ((u32) value) << 16;
837         (*stackidx)++;
838         B43_WARN_ON(*stackidx >= B43_INTERFSTACK_SIZE);
839 }
840
841 static u16 _stack_restore(u32 * stackptr, u8 id, u16 offset)
842 {
843         size_t i;
844
845         B43_WARN_ON(offset & 0xF000);
846         B43_WARN_ON(id & 0xF0);
847         for (i = 0; i < B43_INTERFSTACK_SIZE; i++, stackptr++) {
848                 if ((*stackptr & 0x00000FFF) != offset)
849                         continue;
850                 if (((*stackptr & 0x0000F000) >> 12) != id)
851                         continue;
852                 return ((*stackptr & 0xFFFF0000) >> 16);
853         }
854         B43_WARN_ON(1);
855
856         return 0;
857 }
858
859 #define phy_stacksave(offset)                                   \
860         do {                                                    \
861                 _stack_save(stack, &stackidx, 0x1, (offset),    \
862                             b43_phy_read(dev, (offset)));       \
863         } while (0)
864 #define phy_stackrestore(offset)                                \
865         do {                                                    \
866                 b43_phy_write(dev, (offset),            \
867                                   _stack_restore(stack, 0x1,    \
868                                                  (offset)));    \
869         } while (0)
870 #define radio_stacksave(offset)                                         \
871         do {                                                            \
872                 _stack_save(stack, &stackidx, 0x2, (offset),            \
873                             b43_radio_read16(dev, (offset)));   \
874         } while (0)
875 #define radio_stackrestore(offset)                                      \
876         do {                                                            \
877                 b43_radio_write16(dev, (offset),                        \
878                                       _stack_restore(stack, 0x2,        \
879                                                      (offset)));        \
880         } while (0)
881 #define ofdmtab_stacksave(table, offset)                        \
882         do {                                                    \
883                 _stack_save(stack, &stackidx, 0x3, (offset)|(table),    \
884                             b43_ofdmtab_read16(dev, (table), (offset)));        \
885         } while (0)
886 #define ofdmtab_stackrestore(table, offset)                     \
887         do {                                                    \
888                 b43_ofdmtab_write16(dev, (table),       (offset),       \
889                                   _stack_restore(stack, 0x3,    \
890                                                  (offset)|(table)));    \
891         } while (0)
892
893 static void
894 b43_radio_interference_mitigation_enable(struct b43_wldev *dev, int mode)
895 {
896         struct b43_phy *phy = &dev->phy;
897         struct b43_phy_g *gphy = phy->g;
898         u16 tmp, flipped;
899         size_t stackidx = 0;
900         u32 *stack = gphy->interfstack;
901
902         switch (mode) {
903         case B43_INTERFMODE_NONWLAN:
904                 if (phy->rev != 1) {
905                         b43_phy_write(dev, 0x042B,
906                                       b43_phy_read(dev, 0x042B) | 0x0800);
907                         b43_phy_write(dev, B43_PHY_G_CRS,
908                                       b43_phy_read(dev,
909                                                    B43_PHY_G_CRS) & ~0x4000);
910                         break;
911                 }
912                 radio_stacksave(0x0078);
913                 tmp = (b43_radio_read16(dev, 0x0078) & 0x001E);
914                 B43_WARN_ON(tmp > 15);
915                 flipped = bitrev4(tmp);
916                 if (flipped < 10 && flipped >= 8)
917                         flipped = 7;
918                 else if (flipped >= 10)
919                         flipped -= 3;
920                 flipped = (bitrev4(flipped) << 1) | 0x0020;
921                 b43_radio_write16(dev, 0x0078, flipped);
922
923                 b43_calc_nrssi_threshold(dev);
924
925                 phy_stacksave(0x0406);
926                 b43_phy_write(dev, 0x0406, 0x7E28);
927
928                 b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B) | 0x0800);
929                 b43_phy_write(dev, B43_PHY_RADIO_BITFIELD,
930                               b43_phy_read(dev,
931                                            B43_PHY_RADIO_BITFIELD) | 0x1000);
932
933                 phy_stacksave(0x04A0);
934                 b43_phy_write(dev, 0x04A0,
935                               (b43_phy_read(dev, 0x04A0) & 0xC0C0) | 0x0008);
936                 phy_stacksave(0x04A1);
937                 b43_phy_write(dev, 0x04A1,
938                               (b43_phy_read(dev, 0x04A1) & 0xC0C0) | 0x0605);
939                 phy_stacksave(0x04A2);
940                 b43_phy_write(dev, 0x04A2,
941                               (b43_phy_read(dev, 0x04A2) & 0xC0C0) | 0x0204);
942                 phy_stacksave(0x04A8);
943                 b43_phy_write(dev, 0x04A8,
944                               (b43_phy_read(dev, 0x04A8) & 0xC0C0) | 0x0803);
945                 phy_stacksave(0x04AB);
946                 b43_phy_write(dev, 0x04AB,
947                               (b43_phy_read(dev, 0x04AB) & 0xC0C0) | 0x0605);
948
949                 phy_stacksave(0x04A7);
950                 b43_phy_write(dev, 0x04A7, 0x0002);
951                 phy_stacksave(0x04A3);
952                 b43_phy_write(dev, 0x04A3, 0x287A);
953                 phy_stacksave(0x04A9);
954                 b43_phy_write(dev, 0x04A9, 0x2027);
955                 phy_stacksave(0x0493);
956                 b43_phy_write(dev, 0x0493, 0x32F5);
957                 phy_stacksave(0x04AA);
958                 b43_phy_write(dev, 0x04AA, 0x2027);
959                 phy_stacksave(0x04AC);
960                 b43_phy_write(dev, 0x04AC, 0x32F5);
961                 break;
962         case B43_INTERFMODE_MANUALWLAN:
963                 if (b43_phy_read(dev, 0x0033) & 0x0800)
964                         break;
965
966                 gphy->aci_enable = 1;
967
968                 phy_stacksave(B43_PHY_RADIO_BITFIELD);
969                 phy_stacksave(B43_PHY_G_CRS);
970                 if (phy->rev < 2) {
971                         phy_stacksave(0x0406);
972                 } else {
973                         phy_stacksave(0x04C0);
974                         phy_stacksave(0x04C1);
975                 }
976                 phy_stacksave(0x0033);
977                 phy_stacksave(0x04A7);
978                 phy_stacksave(0x04A3);
979                 phy_stacksave(0x04A9);
980                 phy_stacksave(0x04AA);
981                 phy_stacksave(0x04AC);
982                 phy_stacksave(0x0493);
983                 phy_stacksave(0x04A1);
984                 phy_stacksave(0x04A0);
985                 phy_stacksave(0x04A2);
986                 phy_stacksave(0x048A);
987                 phy_stacksave(0x04A8);
988                 phy_stacksave(0x04AB);
989                 if (phy->rev == 2) {
990                         phy_stacksave(0x04AD);
991                         phy_stacksave(0x04AE);
992                 } else if (phy->rev >= 3) {
993                         phy_stacksave(0x04AD);
994                         phy_stacksave(0x0415);
995                         phy_stacksave(0x0416);
996                         phy_stacksave(0x0417);
997                         ofdmtab_stacksave(0x1A00, 0x2);
998                         ofdmtab_stacksave(0x1A00, 0x3);
999                 }
1000                 phy_stacksave(0x042B);
1001                 phy_stacksave(0x048C);
1002
1003                 b43_phy_write(dev, B43_PHY_RADIO_BITFIELD,
1004                               b43_phy_read(dev, B43_PHY_RADIO_BITFIELD)
1005                               & ~0x1000);
1006                 b43_phy_write(dev, B43_PHY_G_CRS,
1007                               (b43_phy_read(dev, B43_PHY_G_CRS)
1008                                & 0xFFFC) | 0x0002);
1009
1010                 b43_phy_write(dev, 0x0033, 0x0800);
1011                 b43_phy_write(dev, 0x04A3, 0x2027);
1012                 b43_phy_write(dev, 0x04A9, 0x1CA8);
1013                 b43_phy_write(dev, 0x0493, 0x287A);
1014                 b43_phy_write(dev, 0x04AA, 0x1CA8);
1015                 b43_phy_write(dev, 0x04AC, 0x287A);
1016
1017                 b43_phy_write(dev, 0x04A0, (b43_phy_read(dev, 0x04A0)
1018                                             & 0xFFC0) | 0x001A);
1019                 b43_phy_write(dev, 0x04A7, 0x000D);
1020
1021                 if (phy->rev < 2) {
1022                         b43_phy_write(dev, 0x0406, 0xFF0D);
1023                 } else if (phy->rev == 2) {
1024                         b43_phy_write(dev, 0x04C0, 0xFFFF);
1025                         b43_phy_write(dev, 0x04C1, 0x00A9);
1026                 } else {
1027                         b43_phy_write(dev, 0x04C0, 0x00C1);
1028                         b43_phy_write(dev, 0x04C1, 0x0059);
1029                 }
1030
1031                 b43_phy_write(dev, 0x04A1, (b43_phy_read(dev, 0x04A1)
1032                                             & 0xC0FF) | 0x1800);
1033                 b43_phy_write(dev, 0x04A1, (b43_phy_read(dev, 0x04A1)
1034                                             & 0xFFC0) | 0x0015);
1035                 b43_phy_write(dev, 0x04A8, (b43_phy_read(dev, 0x04A8)
1036                                             & 0xCFFF) | 0x1000);
1037                 b43_phy_write(dev, 0x04A8, (b43_phy_read(dev, 0x04A8)
1038                                             & 0xF0FF) | 0x0A00);
1039                 b43_phy_write(dev, 0x04AB, (b43_phy_read(dev, 0x04AB)
1040                                             & 0xCFFF) | 0x1000);
1041                 b43_phy_write(dev, 0x04AB, (b43_phy_read(dev, 0x04AB)
1042                                             & 0xF0FF) | 0x0800);
1043                 b43_phy_write(dev, 0x04AB, (b43_phy_read(dev, 0x04AB)
1044                                             & 0xFFCF) | 0x0010);
1045                 b43_phy_write(dev, 0x04AB, (b43_phy_read(dev, 0x04AB)
1046                                             & 0xFFF0) | 0x0005);
1047                 b43_phy_write(dev, 0x04A8, (b43_phy_read(dev, 0x04A8)
1048                                             & 0xFFCF) | 0x0010);
1049                 b43_phy_write(dev, 0x04A8, (b43_phy_read(dev, 0x04A8)
1050                                             & 0xFFF0) | 0x0006);
1051                 b43_phy_write(dev, 0x04A2, (b43_phy_read(dev, 0x04A2)
1052                                             & 0xF0FF) | 0x0800);
1053                 b43_phy_write(dev, 0x04A0, (b43_phy_read(dev, 0x04A0)
1054                                             & 0xF0FF) | 0x0500);
1055                 b43_phy_write(dev, 0x04A2, (b43_phy_read(dev, 0x04A2)
1056                                             & 0xFFF0) | 0x000B);
1057
1058                 if (phy->rev >= 3) {
1059                         b43_phy_write(dev, 0x048A, b43_phy_read(dev, 0x048A)
1060                                       & ~0x8000);
1061                         b43_phy_write(dev, 0x0415, (b43_phy_read(dev, 0x0415)
1062                                                     & 0x8000) | 0x36D8);
1063                         b43_phy_write(dev, 0x0416, (b43_phy_read(dev, 0x0416)
1064                                                     & 0x8000) | 0x36D8);
1065                         b43_phy_write(dev, 0x0417, (b43_phy_read(dev, 0x0417)
1066                                                     & 0xFE00) | 0x016D);
1067                 } else {
1068                         b43_phy_write(dev, 0x048A, b43_phy_read(dev, 0x048A)
1069                                       | 0x1000);
1070                         b43_phy_write(dev, 0x048A, (b43_phy_read(dev, 0x048A)
1071                                                     & 0x9FFF) | 0x2000);
1072                         b43_hf_write(dev, b43_hf_read(dev) | B43_HF_ACIW);
1073                 }
1074                 if (phy->rev >= 2) {
1075                         b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B)
1076                                       | 0x0800);
1077                 }
1078                 b43_phy_write(dev, 0x048C, (b43_phy_read(dev, 0x048C)
1079                                             & 0xF0FF) | 0x0200);
1080                 if (phy->rev == 2) {
1081                         b43_phy_write(dev, 0x04AE, (b43_phy_read(dev, 0x04AE)
1082                                                     & 0xFF00) | 0x007F);
1083                         b43_phy_write(dev, 0x04AD, (b43_phy_read(dev, 0x04AD)
1084                                                     & 0x00FF) | 0x1300);
1085                 } else if (phy->rev >= 6) {
1086                         b43_ofdmtab_write16(dev, 0x1A00, 0x3, 0x007F);
1087                         b43_ofdmtab_write16(dev, 0x1A00, 0x2, 0x007F);
1088                         b43_phy_write(dev, 0x04AD, b43_phy_read(dev, 0x04AD)
1089                                       & 0x00FF);
1090                 }
1091                 b43_calc_nrssi_slope(dev);
1092                 break;
1093         default:
1094                 B43_WARN_ON(1);
1095         }
1096 }
1097
1098 static void
1099 b43_radio_interference_mitigation_disable(struct b43_wldev *dev, int mode)
1100 {
1101         struct b43_phy *phy = &dev->phy;
1102         struct b43_phy_g *gphy = phy->g;
1103         u32 *stack = gphy->interfstack;
1104
1105         switch (mode) {
1106         case B43_INTERFMODE_NONWLAN:
1107                 if (phy->rev != 1) {
1108                         b43_phy_write(dev, 0x042B,
1109                                       b43_phy_read(dev, 0x042B) & ~0x0800);
1110                         b43_phy_write(dev, B43_PHY_G_CRS,
1111                                       b43_phy_read(dev,
1112                                                    B43_PHY_G_CRS) | 0x4000);
1113                         break;
1114                 }
1115                 radio_stackrestore(0x0078);
1116                 b43_calc_nrssi_threshold(dev);
1117                 phy_stackrestore(0x0406);
1118                 b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B) & ~0x0800);
1119                 if (!dev->bad_frames_preempt) {
1120                         b43_phy_write(dev, B43_PHY_RADIO_BITFIELD,
1121                                       b43_phy_read(dev, B43_PHY_RADIO_BITFIELD)
1122                                       & ~(1 << 11));
1123                 }
1124                 b43_phy_write(dev, B43_PHY_G_CRS,
1125                               b43_phy_read(dev, B43_PHY_G_CRS) | 0x4000);
1126                 phy_stackrestore(0x04A0);
1127                 phy_stackrestore(0x04A1);
1128                 phy_stackrestore(0x04A2);
1129                 phy_stackrestore(0x04A8);
1130                 phy_stackrestore(0x04AB);
1131                 phy_stackrestore(0x04A7);
1132                 phy_stackrestore(0x04A3);
1133                 phy_stackrestore(0x04A9);
1134                 phy_stackrestore(0x0493);
1135                 phy_stackrestore(0x04AA);
1136                 phy_stackrestore(0x04AC);
1137                 break;
1138         case B43_INTERFMODE_MANUALWLAN:
1139                 if (!(b43_phy_read(dev, 0x0033) & 0x0800))
1140                         break;
1141
1142                 gphy->aci_enable = 0;
1143
1144                 phy_stackrestore(B43_PHY_RADIO_BITFIELD);
1145                 phy_stackrestore(B43_PHY_G_CRS);
1146                 phy_stackrestore(0x0033);
1147                 phy_stackrestore(0x04A3);
1148                 phy_stackrestore(0x04A9);
1149                 phy_stackrestore(0x0493);
1150                 phy_stackrestore(0x04AA);
1151                 phy_stackrestore(0x04AC);
1152                 phy_stackrestore(0x04A0);
1153                 phy_stackrestore(0x04A7);
1154                 if (phy->rev >= 2) {
1155                         phy_stackrestore(0x04C0);
1156                         phy_stackrestore(0x04C1);
1157                 } else
1158                         phy_stackrestore(0x0406);
1159                 phy_stackrestore(0x04A1);
1160                 phy_stackrestore(0x04AB);
1161                 phy_stackrestore(0x04A8);
1162                 if (phy->rev == 2) {
1163                         phy_stackrestore(0x04AD);
1164                         phy_stackrestore(0x04AE);
1165                 } else if (phy->rev >= 3) {
1166                         phy_stackrestore(0x04AD);
1167                         phy_stackrestore(0x0415);
1168                         phy_stackrestore(0x0416);
1169                         phy_stackrestore(0x0417);
1170                         ofdmtab_stackrestore(0x1A00, 0x2);
1171                         ofdmtab_stackrestore(0x1A00, 0x3);
1172                 }
1173                 phy_stackrestore(0x04A2);
1174                 phy_stackrestore(0x048A);
1175                 phy_stackrestore(0x042B);
1176                 phy_stackrestore(0x048C);
1177                 b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_ACIW);
1178                 b43_calc_nrssi_slope(dev);
1179                 break;
1180         default:
1181                 B43_WARN_ON(1);
1182         }
1183 }
1184
1185 #undef phy_stacksave
1186 #undef phy_stackrestore
1187 #undef radio_stacksave
1188 #undef radio_stackrestore
1189 #undef ofdmtab_stacksave
1190 #undef ofdmtab_stackrestore
1191
1192 static u16 b43_radio_core_calibration_value(struct b43_wldev *dev)
1193 {
1194         u16 reg, index, ret;
1195
1196         static const u8 rcc_table[] = {
1197                 0x02, 0x03, 0x01, 0x0F,
1198                 0x06, 0x07, 0x05, 0x0F,
1199                 0x0A, 0x0B, 0x09, 0x0F,
1200                 0x0E, 0x0F, 0x0D, 0x0F,
1201         };
1202
1203         reg = b43_radio_read16(dev, 0x60);
1204         index = (reg & 0x001E) >> 1;
1205         ret = rcc_table[index] << 1;
1206         ret |= (reg & 0x0001);
1207         ret |= 0x0020;
1208
1209         return ret;
1210 }
1211
1212 #define LPD(L, P, D)    (((L) << 2) | ((P) << 1) | ((D) << 0))
1213 static u16 radio2050_rfover_val(struct b43_wldev *dev,
1214                                 u16 phy_register, unsigned int lpd)
1215 {
1216         struct b43_phy *phy = &dev->phy;
1217         struct b43_phy_g *gphy = phy->g;
1218         struct ssb_sprom *sprom = &(dev->dev->bus->sprom);
1219
1220         if (!phy->gmode)
1221                 return 0;
1222
1223         if (has_loopback_gain(phy)) {
1224                 int max_lb_gain = gphy->max_lb_gain;
1225                 u16 extlna;
1226                 u16 i;
1227
1228                 if (phy->radio_rev == 8)
1229                         max_lb_gain += 0x3E;
1230                 else
1231                         max_lb_gain += 0x26;
1232                 if (max_lb_gain >= 0x46) {
1233                         extlna = 0x3000;
1234                         max_lb_gain -= 0x46;
1235                 } else if (max_lb_gain >= 0x3A) {
1236                         extlna = 0x1000;
1237                         max_lb_gain -= 0x3A;
1238                 } else if (max_lb_gain >= 0x2E) {
1239                         extlna = 0x2000;
1240                         max_lb_gain -= 0x2E;
1241                 } else {
1242                         extlna = 0;
1243                         max_lb_gain -= 0x10;
1244                 }
1245
1246                 for (i = 0; i < 16; i++) {
1247                         max_lb_gain -= (i * 6);
1248                         if (max_lb_gain < 6)
1249                                 break;
1250                 }
1251
1252                 if ((phy->rev < 7) ||
1253                     !(sprom->boardflags_lo & B43_BFL_EXTLNA)) {
1254                         if (phy_register == B43_PHY_RFOVER) {
1255                                 return 0x1B3;
1256                         } else if (phy_register == B43_PHY_RFOVERVAL) {
1257                                 extlna |= (i << 8);
1258                                 switch (lpd) {
1259                                 case LPD(0, 1, 1):
1260                                         return 0x0F92;
1261                                 case LPD(0, 0, 1):
1262                                 case LPD(1, 0, 1):
1263                                         return (0x0092 | extlna);
1264                                 case LPD(1, 0, 0):
1265                                         return (0x0093 | extlna);
1266                                 }
1267                                 B43_WARN_ON(1);
1268                         }
1269                         B43_WARN_ON(1);
1270                 } else {
1271                         if (phy_register == B43_PHY_RFOVER) {
1272                                 return 0x9B3;
1273                         } else if (phy_register == B43_PHY_RFOVERVAL) {
1274                                 if (extlna)
1275                                         extlna |= 0x8000;
1276                                 extlna |= (i << 8);
1277                                 switch (lpd) {
1278                                 case LPD(0, 1, 1):
1279                                         return 0x8F92;
1280                                 case LPD(0, 0, 1):
1281                                         return (0x8092 | extlna);
1282                                 case LPD(1, 0, 1):
1283                                         return (0x2092 | extlna);
1284                                 case LPD(1, 0, 0):
1285                                         return (0x2093 | extlna);
1286                                 }
1287                                 B43_WARN_ON(1);
1288                         }
1289                         B43_WARN_ON(1);
1290                 }
1291         } else {
1292                 if ((phy->rev < 7) ||
1293                     !(sprom->boardflags_lo & B43_BFL_EXTLNA)) {
1294                         if (phy_register == B43_PHY_RFOVER) {
1295                                 return 0x1B3;
1296                         } else if (phy_register == B43_PHY_RFOVERVAL) {
1297                                 switch (lpd) {
1298                                 case LPD(0, 1, 1):
1299                                         return 0x0FB2;
1300                                 case LPD(0, 0, 1):
1301                                         return 0x00B2;
1302                                 case LPD(1, 0, 1):
1303                                         return 0x30B2;
1304                                 case LPD(1, 0, 0):
1305                                         return 0x30B3;
1306                                 }
1307                                 B43_WARN_ON(1);
1308                         }
1309                         B43_WARN_ON(1);
1310                 } else {
1311                         if (phy_register == B43_PHY_RFOVER) {
1312                                 return 0x9B3;
1313                         } else if (phy_register == B43_PHY_RFOVERVAL) {
1314                                 switch (lpd) {
1315                                 case LPD(0, 1, 1):
1316                                         return 0x8FB2;
1317                                 case LPD(0, 0, 1):
1318                                         return 0x80B2;
1319                                 case LPD(1, 0, 1):
1320                                         return 0x20B2;
1321                                 case LPD(1, 0, 0):
1322                                         return 0x20B3;
1323                                 }
1324                                 B43_WARN_ON(1);
1325                         }
1326                         B43_WARN_ON(1);
1327                 }
1328         }
1329         return 0;
1330 }
1331
1332 struct init2050_saved_values {
1333         /* Core registers */
1334         u16 reg_3EC;
1335         u16 reg_3E6;
1336         u16 reg_3F4;
1337         /* Radio registers */
1338         u16 radio_43;
1339         u16 radio_51;
1340         u16 radio_52;
1341         /* PHY registers */
1342         u16 phy_pgactl;
1343         u16 phy_cck_5A;
1344         u16 phy_cck_59;
1345         u16 phy_cck_58;
1346         u16 phy_cck_30;
1347         u16 phy_rfover;
1348         u16 phy_rfoverval;
1349         u16 phy_analogover;
1350         u16 phy_analogoverval;
1351         u16 phy_crs0;
1352         u16 phy_classctl;
1353         u16 phy_lo_mask;
1354         u16 phy_lo_ctl;
1355         u16 phy_syncctl;
1356 };
1357
1358 u16 b43_radio_init2050(struct b43_wldev *dev)
1359 {
1360         struct b43_phy *phy = &dev->phy;
1361         struct init2050_saved_values sav;
1362         u16 rcc;
1363         u16 radio78;
1364         u16 ret;
1365         u16 i, j;
1366         u32 tmp1 = 0, tmp2 = 0;
1367
1368         memset(&sav, 0, sizeof(sav));   /* get rid of "may be used uninitialized..." */
1369
1370         sav.radio_43 = b43_radio_read16(dev, 0x43);
1371         sav.radio_51 = b43_radio_read16(dev, 0x51);
1372         sav.radio_52 = b43_radio_read16(dev, 0x52);
1373         sav.phy_pgactl = b43_phy_read(dev, B43_PHY_PGACTL);
1374         sav.phy_cck_5A = b43_phy_read(dev, B43_PHY_CCK(0x5A));
1375         sav.phy_cck_59 = b43_phy_read(dev, B43_PHY_CCK(0x59));
1376         sav.phy_cck_58 = b43_phy_read(dev, B43_PHY_CCK(0x58));
1377
1378         if (phy->type == B43_PHYTYPE_B) {
1379                 sav.phy_cck_30 = b43_phy_read(dev, B43_PHY_CCK(0x30));
1380                 sav.reg_3EC = b43_read16(dev, 0x3EC);
1381
1382                 b43_phy_write(dev, B43_PHY_CCK(0x30), 0xFF);
1383                 b43_write16(dev, 0x3EC, 0x3F3F);
1384         } else if (phy->gmode || phy->rev >= 2) {
1385                 sav.phy_rfover = b43_phy_read(dev, B43_PHY_RFOVER);
1386                 sav.phy_rfoverval = b43_phy_read(dev, B43_PHY_RFOVERVAL);
1387                 sav.phy_analogover = b43_phy_read(dev, B43_PHY_ANALOGOVER);
1388                 sav.phy_analogoverval =
1389                     b43_phy_read(dev, B43_PHY_ANALOGOVERVAL);
1390                 sav.phy_crs0 = b43_phy_read(dev, B43_PHY_CRS0);
1391                 sav.phy_classctl = b43_phy_read(dev, B43_PHY_CLASSCTL);
1392
1393                 b43_phy_write(dev, B43_PHY_ANALOGOVER,
1394                               b43_phy_read(dev, B43_PHY_ANALOGOVER)
1395                               | 0x0003);
1396                 b43_phy_write(dev, B43_PHY_ANALOGOVERVAL,
1397                               b43_phy_read(dev, B43_PHY_ANALOGOVERVAL)
1398                               & 0xFFFC);
1399                 b43_phy_write(dev, B43_PHY_CRS0, b43_phy_read(dev, B43_PHY_CRS0)
1400                               & 0x7FFF);
1401                 b43_phy_write(dev, B43_PHY_CLASSCTL,
1402                               b43_phy_read(dev, B43_PHY_CLASSCTL)
1403                               & 0xFFFC);
1404                 if (has_loopback_gain(phy)) {
1405                         sav.phy_lo_mask = b43_phy_read(dev, B43_PHY_LO_MASK);
1406                         sav.phy_lo_ctl = b43_phy_read(dev, B43_PHY_LO_CTL);
1407
1408                         if (phy->rev >= 3)
1409                                 b43_phy_write(dev, B43_PHY_LO_MASK, 0xC020);
1410                         else
1411                                 b43_phy_write(dev, B43_PHY_LO_MASK, 0x8020);
1412                         b43_phy_write(dev, B43_PHY_LO_CTL, 0);
1413                 }
1414
1415                 b43_phy_write(dev, B43_PHY_RFOVERVAL,
1416                               radio2050_rfover_val(dev, B43_PHY_RFOVERVAL,
1417                                                    LPD(0, 1, 1)));
1418                 b43_phy_write(dev, B43_PHY_RFOVER,
1419                               radio2050_rfover_val(dev, B43_PHY_RFOVER, 0));
1420         }
1421         b43_write16(dev, 0x3E2, b43_read16(dev, 0x3E2) | 0x8000);
1422
1423         sav.phy_syncctl = b43_phy_read(dev, B43_PHY_SYNCCTL);
1424         b43_phy_write(dev, B43_PHY_SYNCCTL, b43_phy_read(dev, B43_PHY_SYNCCTL)
1425                       & 0xFF7F);
1426         sav.reg_3E6 = b43_read16(dev, 0x3E6);
1427         sav.reg_3F4 = b43_read16(dev, 0x3F4);
1428
1429         if (phy->analog == 0) {
1430                 b43_write16(dev, 0x03E6, 0x0122);
1431         } else {
1432                 if (phy->analog >= 2) {
1433                         b43_phy_write(dev, B43_PHY_CCK(0x03),
1434                                       (b43_phy_read(dev, B43_PHY_CCK(0x03))
1435                                        & 0xFFBF) | 0x40);
1436                 }
1437                 b43_write16(dev, B43_MMIO_CHANNEL_EXT,
1438                             (b43_read16(dev, B43_MMIO_CHANNEL_EXT) | 0x2000));
1439         }
1440
1441         rcc = b43_radio_core_calibration_value(dev);
1442
1443         if (phy->type == B43_PHYTYPE_B)
1444                 b43_radio_write16(dev, 0x78, 0x26);
1445         if (phy->gmode || phy->rev >= 2) {
1446                 b43_phy_write(dev, B43_PHY_RFOVERVAL,
1447                               radio2050_rfover_val(dev, B43_PHY_RFOVERVAL,
1448                                                    LPD(0, 1, 1)));
1449         }
1450         b43_phy_write(dev, B43_PHY_PGACTL, 0xBFAF);
1451         b43_phy_write(dev, B43_PHY_CCK(0x2B), 0x1403);
1452         if (phy->gmode || phy->rev >= 2) {
1453                 b43_phy_write(dev, B43_PHY_RFOVERVAL,
1454                               radio2050_rfover_val(dev, B43_PHY_RFOVERVAL,
1455                                                    LPD(0, 0, 1)));
1456         }
1457         b43_phy_write(dev, B43_PHY_PGACTL, 0xBFA0);
1458         b43_radio_write16(dev, 0x51, b43_radio_read16(dev, 0x51)
1459                           | 0x0004);
1460         if (phy->radio_rev == 8) {
1461                 b43_radio_write16(dev, 0x43, 0x1F);
1462         } else {
1463                 b43_radio_write16(dev, 0x52, 0);
1464                 b43_radio_write16(dev, 0x43, (b43_radio_read16(dev, 0x43)
1465                                               & 0xFFF0) | 0x0009);
1466         }
1467         b43_phy_write(dev, B43_PHY_CCK(0x58), 0);
1468
1469         for (i = 0; i < 16; i++) {
1470                 b43_phy_write(dev, B43_PHY_CCK(0x5A), 0x0480);
1471                 b43_phy_write(dev, B43_PHY_CCK(0x59), 0xC810);
1472                 b43_phy_write(dev, B43_PHY_CCK(0x58), 0x000D);
1473                 if (phy->gmode || phy->rev >= 2) {
1474                         b43_phy_write(dev, B43_PHY_RFOVERVAL,
1475                                       radio2050_rfover_val(dev,
1476                                                            B43_PHY_RFOVERVAL,
1477                                                            LPD(1, 0, 1)));
1478                 }
1479                 b43_phy_write(dev, B43_PHY_PGACTL, 0xAFB0);
1480                 udelay(10);
1481                 if (phy->gmode || phy->rev >= 2) {
1482                         b43_phy_write(dev, B43_PHY_RFOVERVAL,
1483                                       radio2050_rfover_val(dev,
1484                                                            B43_PHY_RFOVERVAL,
1485                                                            LPD(1, 0, 1)));
1486                 }
1487                 b43_phy_write(dev, B43_PHY_PGACTL, 0xEFB0);
1488                 udelay(10);
1489                 if (phy->gmode || phy->rev >= 2) {
1490                         b43_phy_write(dev, B43_PHY_RFOVERVAL,
1491                                       radio2050_rfover_val(dev,
1492                                                            B43_PHY_RFOVERVAL,
1493                                                            LPD(1, 0, 0)));
1494                 }
1495                 b43_phy_write(dev, B43_PHY_PGACTL, 0xFFF0);
1496                 udelay(20);
1497                 tmp1 += b43_phy_read(dev, B43_PHY_LO_LEAKAGE);
1498                 b43_phy_write(dev, B43_PHY_CCK(0x58), 0);
1499                 if (phy->gmode || phy->rev >= 2) {
1500                         b43_phy_write(dev, B43_PHY_RFOVERVAL,
1501                                       radio2050_rfover_val(dev,
1502                                                            B43_PHY_RFOVERVAL,
1503                                                            LPD(1, 0, 1)));
1504                 }
1505                 b43_phy_write(dev, B43_PHY_PGACTL, 0xAFB0);
1506         }
1507         udelay(10);
1508
1509         b43_phy_write(dev, B43_PHY_CCK(0x58), 0);
1510         tmp1++;
1511         tmp1 >>= 9;
1512
1513         for (i = 0; i < 16; i++) {
1514                 radio78 = (bitrev4(i) << 1) | 0x0020;
1515                 b43_radio_write16(dev, 0x78, radio78);
1516                 udelay(10);
1517                 for (j = 0; j < 16; j++) {
1518                         b43_phy_write(dev, B43_PHY_CCK(0x5A), 0x0D80);
1519                         b43_phy_write(dev, B43_PHY_CCK(0x59), 0xC810);
1520                         b43_phy_write(dev, B43_PHY_CCK(0x58), 0x000D);
1521                         if (phy->gmode || phy->rev >= 2) {
1522                                 b43_phy_write(dev, B43_PHY_RFOVERVAL,
1523                                               radio2050_rfover_val(dev,
1524                                                                    B43_PHY_RFOVERVAL,
1525                                                                    LPD(1, 0,
1526                                                                        1)));
1527                         }
1528                         b43_phy_write(dev, B43_PHY_PGACTL, 0xAFB0);
1529                         udelay(10);
1530                         if (phy->gmode || phy->rev >= 2) {
1531                                 b43_phy_write(dev, B43_PHY_RFOVERVAL,
1532                                               radio2050_rfover_val(dev,
1533                                                                    B43_PHY_RFOVERVAL,
1534                                                                    LPD(1, 0,
1535                                                                        1)));
1536                         }
1537                         b43_phy_write(dev, B43_PHY_PGACTL, 0xEFB0);
1538                         udelay(10);
1539                         if (phy->gmode || phy->rev >= 2) {
1540                                 b43_phy_write(dev, B43_PHY_RFOVERVAL,
1541                                               radio2050_rfover_val(dev,
1542                                                                    B43_PHY_RFOVERVAL,
1543                                                                    LPD(1, 0,
1544                                                                        0)));
1545                         }
1546                         b43_phy_write(dev, B43_PHY_PGACTL, 0xFFF0);
1547                         udelay(10);
1548                         tmp2 += b43_phy_read(dev, B43_PHY_LO_LEAKAGE);
1549                         b43_phy_write(dev, B43_PHY_CCK(0x58), 0);
1550                         if (phy->gmode || phy->rev >= 2) {
1551                                 b43_phy_write(dev, B43_PHY_RFOVERVAL,
1552                                               radio2050_rfover_val(dev,
1553                                                                    B43_PHY_RFOVERVAL,
1554                                                                    LPD(1, 0,
1555                                                                        1)));
1556                         }
1557                         b43_phy_write(dev, B43_PHY_PGACTL, 0xAFB0);
1558                 }
1559                 tmp2++;
1560                 tmp2 >>= 8;
1561                 if (tmp1 < tmp2)
1562                         break;
1563         }
1564
1565         /* Restore the registers */
1566         b43_phy_write(dev, B43_PHY_PGACTL, sav.phy_pgactl);
1567         b43_radio_write16(dev, 0x51, sav.radio_51);
1568         b43_radio_write16(dev, 0x52, sav.radio_52);
1569         b43_radio_write16(dev, 0x43, sav.radio_43);
1570         b43_phy_write(dev, B43_PHY_CCK(0x5A), sav.phy_cck_5A);
1571         b43_phy_write(dev, B43_PHY_CCK(0x59), sav.phy_cck_59);
1572         b43_phy_write(dev, B43_PHY_CCK(0x58), sav.phy_cck_58);
1573         b43_write16(dev, 0x3E6, sav.reg_3E6);
1574         if (phy->analog != 0)
1575                 b43_write16(dev, 0x3F4, sav.reg_3F4);
1576         b43_phy_write(dev, B43_PHY_SYNCCTL, sav.phy_syncctl);
1577         b43_synth_pu_workaround(dev, phy->channel);
1578         if (phy->type == B43_PHYTYPE_B) {
1579                 b43_phy_write(dev, B43_PHY_CCK(0x30), sav.phy_cck_30);
1580                 b43_write16(dev, 0x3EC, sav.reg_3EC);
1581         } else if (phy->gmode) {
1582                 b43_write16(dev, B43_MMIO_PHY_RADIO,
1583                             b43_read16(dev, B43_MMIO_PHY_RADIO)
1584                             & 0x7FFF);
1585                 b43_phy_write(dev, B43_PHY_RFOVER, sav.phy_rfover);
1586                 b43_phy_write(dev, B43_PHY_RFOVERVAL, sav.phy_rfoverval);
1587                 b43_phy_write(dev, B43_PHY_ANALOGOVER, sav.phy_analogover);
1588                 b43_phy_write(dev, B43_PHY_ANALOGOVERVAL,
1589                               sav.phy_analogoverval);
1590                 b43_phy_write(dev, B43_PHY_CRS0, sav.phy_crs0);
1591                 b43_phy_write(dev, B43_PHY_CLASSCTL, sav.phy_classctl);
1592                 if (has_loopback_gain(phy)) {
1593                         b43_phy_write(dev, B43_PHY_LO_MASK, sav.phy_lo_mask);
1594                         b43_phy_write(dev, B43_PHY_LO_CTL, sav.phy_lo_ctl);
1595                 }
1596         }
1597         if (i > 15)
1598                 ret = radio78;
1599         else
1600                 ret = rcc;
1601
1602         return ret;
1603 }
1604
1605 static void b43_phy_initb5(struct b43_wldev *dev)
1606 {
1607         struct ssb_bus *bus = dev->dev->bus;
1608         struct b43_phy *phy = &dev->phy;
1609         struct b43_phy_g *gphy = phy->g;
1610         u16 offset, value;
1611         u8 old_channel;
1612
1613         if (phy->analog == 1) {
1614                 b43_radio_write16(dev, 0x007A, b43_radio_read16(dev, 0x007A)
1615                                   | 0x0050);
1616         }
1617         if ((bus->boardinfo.vendor != SSB_BOARDVENDOR_BCM) &&
1618             (bus->boardinfo.type != SSB_BOARD_BU4306)) {
1619                 value = 0x2120;
1620                 for (offset = 0x00A8; offset < 0x00C7; offset++) {
1621                         b43_phy_write(dev, offset, value);
1622                         value += 0x202;
1623                 }
1624         }
1625         b43_phy_write(dev, 0x0035, (b43_phy_read(dev, 0x0035) & 0xF0FF)
1626                       | 0x0700);
1627         if (phy->radio_ver == 0x2050)
1628                 b43_phy_write(dev, 0x0038, 0x0667);
1629
1630         if (phy->gmode || phy->rev >= 2) {
1631                 if (phy->radio_ver == 0x2050) {
1632                         b43_radio_write16(dev, 0x007A,
1633                                           b43_radio_read16(dev, 0x007A)
1634                                           | 0x0020);
1635                         b43_radio_write16(dev, 0x0051,
1636                                           b43_radio_read16(dev, 0x0051)
1637                                           | 0x0004);
1638                 }
1639                 b43_write16(dev, B43_MMIO_PHY_RADIO, 0x0000);
1640
1641                 b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) | 0x0100);
1642                 b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B) | 0x2000);
1643
1644                 b43_phy_write(dev, 0x001C, 0x186A);
1645
1646                 b43_phy_write(dev, 0x0013,
1647                               (b43_phy_read(dev, 0x0013) & 0x00FF) | 0x1900);
1648                 b43_phy_write(dev, 0x0035,
1649                               (b43_phy_read(dev, 0x0035) & 0xFFC0) | 0x0064);
1650                 b43_phy_write(dev, 0x005D,
1651                               (b43_phy_read(dev, 0x005D) & 0xFF80) | 0x000A);
1652         }
1653
1654         if (dev->bad_frames_preempt) {
1655                 b43_phy_write(dev, B43_PHY_RADIO_BITFIELD,
1656                               b43_phy_read(dev,
1657                                            B43_PHY_RADIO_BITFIELD) | (1 << 11));
1658         }
1659
1660         if (phy->analog == 1) {
1661                 b43_phy_write(dev, 0x0026, 0xCE00);
1662                 b43_phy_write(dev, 0x0021, 0x3763);
1663                 b43_phy_write(dev, 0x0022, 0x1BC3);
1664                 b43_phy_write(dev, 0x0023, 0x06F9);
1665                 b43_phy_write(dev, 0x0024, 0x037E);
1666         } else
1667                 b43_phy_write(dev, 0x0026, 0xCC00);
1668         b43_phy_write(dev, 0x0030, 0x00C6);
1669         b43_write16(dev, 0x03EC, 0x3F22);
1670
1671         if (phy->analog == 1)
1672                 b43_phy_write(dev, 0x0020, 0x3E1C);
1673         else
1674                 b43_phy_write(dev, 0x0020, 0x301C);
1675
1676         if (phy->analog == 0)
1677                 b43_write16(dev, 0x03E4, 0x3000);
1678
1679         old_channel = phy->channel;
1680         /* Force to channel 7, even if not supported. */
1681         b43_gphy_channel_switch(dev, 7, 0);
1682
1683         if (phy->radio_ver != 0x2050) {
1684                 b43_radio_write16(dev, 0x0075, 0x0080);
1685                 b43_radio_write16(dev, 0x0079, 0x0081);
1686         }
1687
1688         b43_radio_write16(dev, 0x0050, 0x0020);
1689         b43_radio_write16(dev, 0x0050, 0x0023);
1690
1691         if (phy->radio_ver == 0x2050) {
1692                 b43_radio_write16(dev, 0x0050, 0x0020);
1693                 b43_radio_write16(dev, 0x005A, 0x0070);
1694         }
1695
1696         b43_radio_write16(dev, 0x005B, 0x007B);
1697         b43_radio_write16(dev, 0x005C, 0x00B0);
1698
1699         b43_radio_write16(dev, 0x007A, b43_radio_read16(dev, 0x007A) | 0x0007);
1700
1701         b43_gphy_channel_switch(dev, old_channel, 0);
1702
1703         b43_phy_write(dev, 0x0014, 0x0080);
1704         b43_phy_write(dev, 0x0032, 0x00CA);
1705         b43_phy_write(dev, 0x002A, 0x88A3);
1706
1707         b43_set_txpower_g(dev, &gphy->bbatt, &gphy->rfatt, gphy->tx_control);
1708
1709         if (phy->radio_ver == 0x2050)
1710                 b43_radio_write16(dev, 0x005D, 0x000D);
1711
1712         b43_write16(dev, 0x03E4, (b43_read16(dev, 0x03E4) & 0xFFC0) | 0x0004);
1713 }
1714
1715 static void b43_phy_initb6(struct b43_wldev *dev)
1716 {
1717         struct b43_phy *phy = &dev->phy;
1718         struct b43_phy_g *gphy = phy->g;
1719         u16 offset, val;
1720         u8 old_channel;
1721
1722         b43_phy_write(dev, 0x003E, 0x817A);
1723         b43_radio_write16(dev, 0x007A,
1724                           (b43_radio_read16(dev, 0x007A) | 0x0058));
1725         if (phy->radio_rev == 4 || phy->radio_rev == 5) {
1726                 b43_radio_write16(dev, 0x51, 0x37);
1727                 b43_radio_write16(dev, 0x52, 0x70);
1728                 b43_radio_write16(dev, 0x53, 0xB3);
1729                 b43_radio_write16(dev, 0x54, 0x9B);
1730                 b43_radio_write16(dev, 0x5A, 0x88);
1731                 b43_radio_write16(dev, 0x5B, 0x88);
1732                 b43_radio_write16(dev, 0x5D, 0x88);
1733                 b43_radio_write16(dev, 0x5E, 0x88);
1734                 b43_radio_write16(dev, 0x7D, 0x88);
1735                 b43_hf_write(dev, b43_hf_read(dev)
1736                              | B43_HF_TSSIRPSMW);
1737         }
1738         B43_WARN_ON(phy->radio_rev == 6 || phy->radio_rev == 7);        /* We had code for these revs here... */
1739         if (phy->radio_rev == 8) {
1740                 b43_radio_write16(dev, 0x51, 0);
1741                 b43_radio_write16(dev, 0x52, 0x40);
1742                 b43_radio_write16(dev, 0x53, 0xB7);
1743                 b43_radio_write16(dev, 0x54, 0x98);
1744                 b43_radio_write16(dev, 0x5A, 0x88);
1745                 b43_radio_write16(dev, 0x5B, 0x6B);
1746                 b43_radio_write16(dev, 0x5C, 0x0F);
1747                 if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_ALTIQ) {
1748                         b43_radio_write16(dev, 0x5D, 0xFA);
1749                         b43_radio_write16(dev, 0x5E, 0xD8);
1750                 } else {
1751                         b43_radio_write16(dev, 0x5D, 0xF5);
1752                         b43_radio_write16(dev, 0x5E, 0xB8);
1753                 }
1754                 b43_radio_write16(dev, 0x0073, 0x0003);
1755                 b43_radio_write16(dev, 0x007D, 0x00A8);
1756                 b43_radio_write16(dev, 0x007C, 0x0001);
1757                 b43_radio_write16(dev, 0x007E, 0x0008);
1758         }
1759         val = 0x1E1F;
1760         for (offset = 0x0088; offset < 0x0098; offset++) {
1761                 b43_phy_write(dev, offset, val);
1762                 val -= 0x0202;
1763         }
1764         val = 0x3E3F;
1765         for (offset = 0x0098; offset < 0x00A8; offset++) {
1766                 b43_phy_write(dev, offset, val);
1767                 val -= 0x0202;
1768         }
1769         val = 0x2120;
1770         for (offset = 0x00A8; offset < 0x00C8; offset++) {
1771                 b43_phy_write(dev, offset, (val & 0x3F3F));
1772                 val += 0x0202;
1773         }
1774         if (phy->type == B43_PHYTYPE_G) {
1775                 b43_radio_write16(dev, 0x007A,
1776                                   b43_radio_read16(dev, 0x007A) | 0x0020);
1777                 b43_radio_write16(dev, 0x0051,
1778                                   b43_radio_read16(dev, 0x0051) | 0x0004);
1779                 b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) | 0x0100);
1780                 b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B) | 0x2000);
1781                 b43_phy_write(dev, 0x5B, 0);
1782                 b43_phy_write(dev, 0x5C, 0);
1783         }
1784
1785         old_channel = phy->channel;
1786         if (old_channel >= 8)
1787                 b43_gphy_channel_switch(dev, 1, 0);
1788         else
1789                 b43_gphy_channel_switch(dev, 13, 0);
1790
1791         b43_radio_write16(dev, 0x0050, 0x0020);
1792         b43_radio_write16(dev, 0x0050, 0x0023);
1793         udelay(40);
1794         if (phy->radio_rev < 6 || phy->radio_rev == 8) {
1795                 b43_radio_write16(dev, 0x7C, (b43_radio_read16(dev, 0x7C)
1796                                               | 0x0002));
1797                 b43_radio_write16(dev, 0x50, 0x20);
1798         }
1799         if (phy->radio_rev <= 2) {
1800                 b43_radio_write16(dev, 0x7C, 0x20);
1801                 b43_radio_write16(dev, 0x5A, 0x70);
1802                 b43_radio_write16(dev, 0x5B, 0x7B);
1803                 b43_radio_write16(dev, 0x5C, 0xB0);
1804         }
1805         b43_radio_write16(dev, 0x007A,
1806                           (b43_radio_read16(dev, 0x007A) & 0x00F8) | 0x0007);
1807
1808         b43_gphy_channel_switch(dev, old_channel, 0);
1809
1810         b43_phy_write(dev, 0x0014, 0x0200);
1811         if (phy->radio_rev >= 6)
1812                 b43_phy_write(dev, 0x2A, 0x88C2);
1813         else
1814                 b43_phy_write(dev, 0x2A, 0x8AC0);
1815         b43_phy_write(dev, 0x0038, 0x0668);
1816         b43_set_txpower_g(dev, &gphy->bbatt, &gphy->rfatt, gphy->tx_control);
1817         if (phy->radio_rev <= 5) {
1818                 b43_phy_write(dev, 0x5D, (b43_phy_read(dev, 0x5D)
1819                                           & 0xFF80) | 0x0003);
1820         }
1821         if (phy->radio_rev <= 2)
1822                 b43_radio_write16(dev, 0x005D, 0x000D);
1823
1824         if (phy->analog == 4) {
1825                 b43_write16(dev, 0x3E4, 9);
1826                 b43_phy_write(dev, 0x61, b43_phy_read(dev, 0x61)
1827                               & 0x0FFF);
1828         } else {
1829                 b43_phy_write(dev, 0x0002, (b43_phy_read(dev, 0x0002) & 0xFFC0)
1830                               | 0x0004);
1831         }
1832         if (phy->type == B43_PHYTYPE_B)
1833                 B43_WARN_ON(1);
1834         else if (phy->type == B43_PHYTYPE_G)
1835                 b43_write16(dev, 0x03E6, 0x0);
1836 }
1837
1838 static void b43_calc_loopback_gain(struct b43_wldev *dev)
1839 {
1840         struct b43_phy *phy = &dev->phy;
1841         struct b43_phy_g *gphy = phy->g;
1842         u16 backup_phy[16] = { 0 };
1843         u16 backup_radio[3];
1844         u16 backup_bband;
1845         u16 i, j, loop_i_max;
1846         u16 trsw_rx;
1847         u16 loop1_outer_done, loop1_inner_done;
1848
1849         backup_phy[0] = b43_phy_read(dev, B43_PHY_CRS0);
1850         backup_phy[1] = b43_phy_read(dev, B43_PHY_CCKBBANDCFG);
1851         backup_phy[2] = b43_phy_read(dev, B43_PHY_RFOVER);
1852         backup_phy[3] = b43_phy_read(dev, B43_PHY_RFOVERVAL);
1853         if (phy->rev != 1) {    /* Not in specs, but needed to prevent PPC machine check */
1854                 backup_phy[4] = b43_phy_read(dev, B43_PHY_ANALOGOVER);
1855                 backup_phy[5] = b43_phy_read(dev, B43_PHY_ANALOGOVERVAL);
1856         }
1857         backup_phy[6] = b43_phy_read(dev, B43_PHY_CCK(0x5A));
1858         backup_phy[7] = b43_phy_read(dev, B43_PHY_CCK(0x59));
1859         backup_phy[8] = b43_phy_read(dev, B43_PHY_CCK(0x58));
1860         backup_phy[9] = b43_phy_read(dev, B43_PHY_CCK(0x0A));
1861         backup_phy[10] = b43_phy_read(dev, B43_PHY_CCK(0x03));
1862         backup_phy[11] = b43_phy_read(dev, B43_PHY_LO_MASK);
1863         backup_phy[12] = b43_phy_read(dev, B43_PHY_LO_CTL);
1864         backup_phy[13] = b43_phy_read(dev, B43_PHY_CCK(0x2B));
1865         backup_phy[14] = b43_phy_read(dev, B43_PHY_PGACTL);
1866         backup_phy[15] = b43_phy_read(dev, B43_PHY_LO_LEAKAGE);
1867         backup_bband = gphy->bbatt.att;
1868         backup_radio[0] = b43_radio_read16(dev, 0x52);
1869         backup_radio[1] = b43_radio_read16(dev, 0x43);
1870         backup_radio[2] = b43_radio_read16(dev, 0x7A);
1871
1872         b43_phy_write(dev, B43_PHY_CRS0,
1873                       b43_phy_read(dev, B43_PHY_CRS0) & 0x3FFF);
1874         b43_phy_write(dev, B43_PHY_CCKBBANDCFG,
1875                       b43_phy_read(dev, B43_PHY_CCKBBANDCFG) | 0x8000);
1876         b43_phy_write(dev, B43_PHY_RFOVER,
1877                       b43_phy_read(dev, B43_PHY_RFOVER) | 0x0002);
1878         b43_phy_write(dev, B43_PHY_RFOVERVAL,
1879                       b43_phy_read(dev, B43_PHY_RFOVERVAL) & 0xFFFD);
1880         b43_phy_write(dev, B43_PHY_RFOVER,
1881                       b43_phy_read(dev, B43_PHY_RFOVER) | 0x0001);
1882         b43_phy_write(dev, B43_PHY_RFOVERVAL,
1883                       b43_phy_read(dev, B43_PHY_RFOVERVAL) & 0xFFFE);
1884         if (phy->rev != 1) {    /* Not in specs, but needed to prevent PPC machine check */
1885                 b43_phy_write(dev, B43_PHY_ANALOGOVER,
1886                               b43_phy_read(dev, B43_PHY_ANALOGOVER) | 0x0001);
1887                 b43_phy_write(dev, B43_PHY_ANALOGOVERVAL,
1888                               b43_phy_read(dev,
1889                                            B43_PHY_ANALOGOVERVAL) & 0xFFFE);
1890                 b43_phy_write(dev, B43_PHY_ANALOGOVER,
1891                               b43_phy_read(dev, B43_PHY_ANALOGOVER) | 0x0002);
1892                 b43_phy_write(dev, B43_PHY_ANALOGOVERVAL,
1893                               b43_phy_read(dev,
1894                                            B43_PHY_ANALOGOVERVAL) & 0xFFFD);
1895         }
1896         b43_phy_write(dev, B43_PHY_RFOVER,
1897                       b43_phy_read(dev, B43_PHY_RFOVER) | 0x000C);
1898         b43_phy_write(dev, B43_PHY_RFOVERVAL,
1899                       b43_phy_read(dev, B43_PHY_RFOVERVAL) | 0x000C);
1900         b43_phy_write(dev, B43_PHY_RFOVER,
1901                       b43_phy_read(dev, B43_PHY_RFOVER) | 0x0030);
1902         b43_phy_write(dev, B43_PHY_RFOVERVAL,
1903                       (b43_phy_read(dev, B43_PHY_RFOVERVAL)
1904                        & 0xFFCF) | 0x10);
1905
1906         b43_phy_write(dev, B43_PHY_CCK(0x5A), 0x0780);
1907         b43_phy_write(dev, B43_PHY_CCK(0x59), 0xC810);
1908         b43_phy_write(dev, B43_PHY_CCK(0x58), 0x000D);
1909
1910         b43_phy_write(dev, B43_PHY_CCK(0x0A),
1911                       b43_phy_read(dev, B43_PHY_CCK(0x0A)) | 0x2000);
1912         if (phy->rev != 1) {    /* Not in specs, but needed to prevent PPC machine check */
1913                 b43_phy_write(dev, B43_PHY_ANALOGOVER,
1914                               b43_phy_read(dev, B43_PHY_ANALOGOVER) | 0x0004);
1915                 b43_phy_write(dev, B43_PHY_ANALOGOVERVAL,
1916                               b43_phy_read(dev,
1917                                            B43_PHY_ANALOGOVERVAL) & 0xFFFB);
1918         }
1919         b43_phy_write(dev, B43_PHY_CCK(0x03),
1920                       (b43_phy_read(dev, B43_PHY_CCK(0x03))
1921                        & 0xFF9F) | 0x40);
1922
1923         if (phy->radio_rev == 8) {
1924                 b43_radio_write16(dev, 0x43, 0x000F);
1925         } else {
1926                 b43_radio_write16(dev, 0x52, 0);
1927                 b43_radio_write16(dev, 0x43, (b43_radio_read16(dev, 0x43)
1928                                               & 0xFFF0) | 0x9);
1929         }
1930         b43_gphy_set_baseband_attenuation(dev, 11);
1931
1932         if (phy->rev >= 3)
1933                 b43_phy_write(dev, B43_PHY_LO_MASK, 0xC020);
1934         else
1935                 b43_phy_write(dev, B43_PHY_LO_MASK, 0x8020);
1936         b43_phy_write(dev, B43_PHY_LO_CTL, 0);
1937
1938         b43_phy_write(dev, B43_PHY_CCK(0x2B),
1939                       (b43_phy_read(dev, B43_PHY_CCK(0x2B))
1940                        & 0xFFC0) | 0x01);
1941         b43_phy_write(dev, B43_PHY_CCK(0x2B),
1942                       (b43_phy_read(dev, B43_PHY_CCK(0x2B))
1943                        & 0xC0FF) | 0x800);
1944
1945         b43_phy_write(dev, B43_PHY_RFOVER,
1946                       b43_phy_read(dev, B43_PHY_RFOVER) | 0x0100);
1947         b43_phy_write(dev, B43_PHY_RFOVERVAL,
1948                       b43_phy_read(dev, B43_PHY_RFOVERVAL) & 0xCFFF);
1949
1950         if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA) {
1951                 if (phy->rev >= 7) {
1952                         b43_phy_write(dev, B43_PHY_RFOVER,
1953                                       b43_phy_read(dev, B43_PHY_RFOVER)
1954                                       | 0x0800);
1955                         b43_phy_write(dev, B43_PHY_RFOVERVAL,
1956                                       b43_phy_read(dev, B43_PHY_RFOVERVAL)
1957                                       | 0x8000);
1958                 }
1959         }
1960         b43_radio_write16(dev, 0x7A, b43_radio_read16(dev, 0x7A)
1961                           & 0x00F7);
1962
1963         j = 0;
1964         loop_i_max = (phy->radio_rev == 8) ? 15 : 9;
1965         for (i = 0; i < loop_i_max; i++) {
1966                 for (j = 0; j < 16; j++) {
1967                         b43_radio_write16(dev, 0x43, i);
1968                         b43_phy_write(dev, B43_PHY_RFOVERVAL,
1969                                       (b43_phy_read(dev, B43_PHY_RFOVERVAL)
1970                                        & 0xF0FF) | (j << 8));
1971                         b43_phy_write(dev, B43_PHY_PGACTL,
1972                                       (b43_phy_read(dev, B43_PHY_PGACTL)
1973                                        & 0x0FFF) | 0xA000);
1974                         b43_phy_write(dev, B43_PHY_PGACTL,
1975                                       b43_phy_read(dev, B43_PHY_PGACTL)
1976                                       | 0xF000);
1977                         udelay(20);
1978                         if (b43_phy_read(dev, B43_PHY_LO_LEAKAGE) >= 0xDFC)
1979                                 goto exit_loop1;
1980                 }
1981         }
1982       exit_loop1:
1983         loop1_outer_done = i;
1984         loop1_inner_done = j;
1985         if (j >= 8) {
1986                 b43_phy_write(dev, B43_PHY_RFOVERVAL,
1987                               b43_phy_read(dev, B43_PHY_RFOVERVAL)
1988                               | 0x30);
1989                 trsw_rx = 0x1B;
1990                 for (j = j - 8; j < 16; j++) {
1991                         b43_phy_write(dev, B43_PHY_RFOVERVAL,
1992                                       (b43_phy_read(dev, B43_PHY_RFOVERVAL)
1993                                        & 0xF0FF) | (j << 8));
1994                         b43_phy_write(dev, B43_PHY_PGACTL,
1995                                       (b43_phy_read(dev, B43_PHY_PGACTL)
1996                                        & 0x0FFF) | 0xA000);
1997                         b43_phy_write(dev, B43_PHY_PGACTL,
1998                                       b43_phy_read(dev, B43_PHY_PGACTL)
1999                                       | 0xF000);
2000                         udelay(20);
2001                         trsw_rx -= 3;
2002                         if (b43_phy_read(dev, B43_PHY_LO_LEAKAGE) >= 0xDFC)
2003                                 goto exit_loop2;
2004                 }
2005         } else
2006                 trsw_rx = 0x18;
2007       exit_loop2:
2008
2009         if (phy->rev != 1) {    /* Not in specs, but needed to prevent PPC machine check */
2010                 b43_phy_write(dev, B43_PHY_ANALOGOVER, backup_phy[4]);
2011                 b43_phy_write(dev, B43_PHY_ANALOGOVERVAL, backup_phy[5]);
2012         }
2013         b43_phy_write(dev, B43_PHY_CCK(0x5A), backup_phy[6]);
2014         b43_phy_write(dev, B43_PHY_CCK(0x59), backup_phy[7]);
2015         b43_phy_write(dev, B43_PHY_CCK(0x58), backup_phy[8]);
2016         b43_phy_write(dev, B43_PHY_CCK(0x0A), backup_phy[9]);
2017         b43_phy_write(dev, B43_PHY_CCK(0x03), backup_phy[10]);
2018         b43_phy_write(dev, B43_PHY_LO_MASK, backup_phy[11]);
2019         b43_phy_write(dev, B43_PHY_LO_CTL, backup_phy[12]);
2020         b43_phy_write(dev, B43_PHY_CCK(0x2B), backup_phy[13]);
2021         b43_phy_write(dev, B43_PHY_PGACTL, backup_phy[14]);
2022
2023         b43_gphy_set_baseband_attenuation(dev, backup_bband);
2024
2025         b43_radio_write16(dev, 0x52, backup_radio[0]);
2026         b43_radio_write16(dev, 0x43, backup_radio[1]);
2027         b43_radio_write16(dev, 0x7A, backup_radio[2]);
2028
2029         b43_phy_write(dev, B43_PHY_RFOVER, backup_phy[2] | 0x0003);
2030         udelay(10);
2031         b43_phy_write(dev, B43_PHY_RFOVER, backup_phy[2]);
2032         b43_phy_write(dev, B43_PHY_RFOVERVAL, backup_phy[3]);
2033         b43_phy_write(dev, B43_PHY_CRS0, backup_phy[0]);
2034         b43_phy_write(dev, B43_PHY_CCKBBANDCFG, backup_phy[1]);
2035
2036         gphy->max_lb_gain =
2037             ((loop1_inner_done * 6) - (loop1_outer_done * 4)) - 11;
2038         gphy->trsw_rx_gain = trsw_rx * 2;
2039 }
2040
2041 static void b43_hardware_pctl_early_init(struct b43_wldev *dev)
2042 {
2043         struct b43_phy *phy = &dev->phy;
2044
2045         if (!b43_has_hardware_pctl(dev)) {
2046                 b43_phy_write(dev, 0x047A, 0xC111);
2047                 return;
2048         }
2049
2050         b43_phy_write(dev, 0x0036, b43_phy_read(dev, 0x0036) & 0xFEFF);
2051         b43_phy_write(dev, 0x002F, 0x0202);
2052         b43_phy_write(dev, 0x047C, b43_phy_read(dev, 0x047C) | 0x0002);
2053         b43_phy_write(dev, 0x047A, b43_phy_read(dev, 0x047A) | 0xF000);
2054         if (phy->radio_ver == 0x2050 && phy->radio_rev == 8) {
2055                 b43_phy_write(dev, 0x047A, (b43_phy_read(dev, 0x047A)
2056                                             & 0xFF0F) | 0x0010);
2057                 b43_phy_write(dev, 0x005D, b43_phy_read(dev, 0x005D)
2058                               | 0x8000);
2059                 b43_phy_write(dev, 0x004E, (b43_phy_read(dev, 0x004E)
2060                                             & 0xFFC0) | 0x0010);
2061                 b43_phy_write(dev, 0x002E, 0xC07F);
2062                 b43_phy_write(dev, 0x0036, b43_phy_read(dev, 0x0036)
2063                               | 0x0400);
2064         } else {
2065                 b43_phy_write(dev, 0x0036, b43_phy_read(dev, 0x0036)
2066                               | 0x0200);
2067                 b43_phy_write(dev, 0x0036, b43_phy_read(dev, 0x0036)
2068                               | 0x0400);
2069                 b43_phy_write(dev, 0x005D, b43_phy_read(dev, 0x005D)
2070                               & 0x7FFF);
2071                 b43_phy_write(dev, 0x004F, b43_phy_read(dev, 0x004F)
2072                               & 0xFFFE);
2073                 b43_phy_write(dev, 0x004E, (b43_phy_read(dev, 0x004E)
2074                                             & 0xFFC0) | 0x0010);
2075                 b43_phy_write(dev, 0x002E, 0xC07F);
2076                 b43_phy_write(dev, 0x047A, (b43_phy_read(dev, 0x047A)
2077                                             & 0xFF0F) | 0x0010);
2078         }
2079 }
2080
2081 /* Hardware power control for G-PHY */
2082 static void b43_hardware_pctl_init_gphy(struct b43_wldev *dev)
2083 {
2084         struct b43_phy *phy = &dev->phy;
2085         struct b43_phy_g *gphy = phy->g;
2086
2087         if (!b43_has_hardware_pctl(dev)) {
2088                 /* No hardware power control */
2089                 b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_HWPCTL);
2090                 return;
2091         }
2092
2093         b43_phy_write(dev, 0x0036, (b43_phy_read(dev, 0x0036) & 0xFFC0)
2094                       | (gphy->tgt_idle_tssi - gphy->cur_idle_tssi));
2095         b43_phy_write(dev, 0x0478, (b43_phy_read(dev, 0x0478) & 0xFF00)
2096                       | (gphy->tgt_idle_tssi - gphy->cur_idle_tssi));
2097         b43_gphy_tssi_power_lt_init(dev);
2098         b43_gphy_gain_lt_init(dev);
2099         b43_phy_write(dev, 0x0060, b43_phy_read(dev, 0x0060) & 0xFFBF);
2100         b43_phy_write(dev, 0x0014, 0x0000);
2101
2102         B43_WARN_ON(phy->rev < 6);
2103         b43_phy_write(dev, 0x0478, b43_phy_read(dev, 0x0478)
2104                       | 0x0800);
2105         b43_phy_write(dev, 0x0478, b43_phy_read(dev, 0x0478)
2106                       & 0xFEFF);
2107         b43_phy_write(dev, 0x0801, b43_phy_read(dev, 0x0801)
2108                       & 0xFFBF);
2109
2110         b43_gphy_dc_lt_init(dev, 1);
2111
2112         /* Enable hardware pctl in firmware. */
2113         b43_hf_write(dev, b43_hf_read(dev) | B43_HF_HWPCTL);
2114 }
2115
2116 /* Intialize B/G PHY power control */
2117 static void b43_phy_init_pctl(struct b43_wldev *dev)
2118 {
2119         struct ssb_bus *bus = dev->dev->bus;
2120         struct b43_phy *phy = &dev->phy;
2121         struct b43_phy_g *gphy = phy->g;
2122         struct b43_rfatt old_rfatt;
2123         struct b43_bbatt old_bbatt;
2124         u8 old_tx_control = 0;
2125
2126         B43_WARN_ON(phy->type != B43_PHYTYPE_G);
2127
2128         if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) &&
2129             (bus->boardinfo.type == SSB_BOARD_BU4306))
2130                 return;
2131
2132         b43_phy_write(dev, 0x0028, 0x8018);
2133
2134         /* This does something with the Analog... */
2135         b43_write16(dev, B43_MMIO_PHY0, b43_read16(dev, B43_MMIO_PHY0)
2136                     & 0xFFDF);
2137
2138         if (!phy->gmode)
2139                 return;
2140         b43_hardware_pctl_early_init(dev);
2141         if (gphy->cur_idle_tssi == 0) {
2142                 if (phy->radio_ver == 0x2050 && phy->analog == 0) {
2143                         b43_radio_write16(dev, 0x0076,
2144                                           (b43_radio_read16(dev, 0x0076)
2145                                            & 0x00F7) | 0x0084);
2146                 } else {
2147                         struct b43_rfatt rfatt;
2148                         struct b43_bbatt bbatt;
2149
2150                         memcpy(&old_rfatt, &gphy->rfatt, sizeof(old_rfatt));
2151                         memcpy(&old_bbatt, &gphy->bbatt, sizeof(old_bbatt));
2152                         old_tx_control = gphy->tx_control;
2153
2154                         bbatt.att = 11;
2155                         if (phy->radio_rev == 8) {
2156                                 rfatt.att = 15;
2157                                 rfatt.with_padmix = 1;
2158                         } else {
2159                                 rfatt.att = 9;
2160                                 rfatt.with_padmix = 0;
2161                         }
2162                         b43_set_txpower_g(dev, &bbatt, &rfatt, 0);
2163                 }
2164                 b43_dummy_transmission(dev);
2165                 gphy->cur_idle_tssi = b43_phy_read(dev, B43_PHY_ITSSI);
2166                 if (B43_DEBUG) {
2167                         /* Current-Idle-TSSI sanity check. */
2168                         if (abs(gphy->cur_idle_tssi - gphy->tgt_idle_tssi) >= 20) {
2169                                 b43dbg(dev->wl,
2170                                        "!WARNING! Idle-TSSI phy->cur_idle_tssi "
2171                                        "measuring failed. (cur=%d, tgt=%d). Disabling TX power "
2172                                        "adjustment.\n", gphy->cur_idle_tssi,
2173                                        gphy->tgt_idle_tssi);
2174                                 gphy->cur_idle_tssi = 0;
2175                         }
2176                 }
2177                 if (phy->radio_ver == 0x2050 && phy->analog == 0) {
2178                         b43_radio_write16(dev, 0x0076,
2179                                           b43_radio_read16(dev, 0x0076)
2180                                           & 0xFF7B);
2181                 } else {
2182                         b43_set_txpower_g(dev, &old_bbatt,
2183                                           &old_rfatt, old_tx_control);
2184                 }
2185         }
2186         b43_hardware_pctl_init_gphy(dev);
2187         b43_shm_clear_tssi(dev);
2188 }
2189
2190 static void b43_phy_initg(struct b43_wldev *dev)
2191 {
2192         struct b43_phy *phy = &dev->phy;
2193         struct b43_phy_g *gphy = phy->g;
2194         u16 tmp;
2195
2196         if (phy->rev == 1)
2197                 b43_phy_initb5(dev);
2198         else
2199                 b43_phy_initb6(dev);
2200
2201         if (phy->rev >= 2 || phy->gmode)
2202                 b43_phy_inita(dev);
2203
2204         if (phy->rev >= 2) {
2205                 b43_phy_write(dev, B43_PHY_ANALOGOVER, 0);
2206                 b43_phy_write(dev, B43_PHY_ANALOGOVERVAL, 0);
2207         }
2208         if (phy->rev == 2) {
2209                 b43_phy_write(dev, B43_PHY_RFOVER, 0);
2210                 b43_phy_write(dev, B43_PHY_PGACTL, 0xC0);
2211         }
2212         if (phy->rev > 5) {
2213                 b43_phy_write(dev, B43_PHY_RFOVER, 0x400);
2214                 b43_phy_write(dev, B43_PHY_PGACTL, 0xC0);
2215         }
2216         if (phy->gmode || phy->rev >= 2) {
2217                 tmp = b43_phy_read(dev, B43_PHY_VERSION_OFDM);
2218                 tmp &= B43_PHYVER_VERSION;
2219                 if (tmp == 3 || tmp == 5) {
2220                         b43_phy_write(dev, B43_PHY_OFDM(0xC2), 0x1816);
2221                         b43_phy_write(dev, B43_PHY_OFDM(0xC3), 0x8006);
2222                 }
2223                 if (tmp == 5) {
2224                         b43_phy_write(dev, B43_PHY_OFDM(0xCC),
2225                                       (b43_phy_read(dev, B43_PHY_OFDM(0xCC))
2226                                        & 0x00FF) | 0x1F00);
2227                 }
2228         }
2229         if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2)
2230                 b43_phy_write(dev, B43_PHY_OFDM(0x7E), 0x78);
2231         if (phy->radio_rev == 8) {
2232                 b43_phy_write(dev, B43_PHY_EXTG(0x01),
2233                               b43_phy_read(dev, B43_PHY_EXTG(0x01))
2234                               | 0x80);
2235                 b43_phy_write(dev, B43_PHY_OFDM(0x3E),
2236                               b43_phy_read(dev, B43_PHY_OFDM(0x3E))
2237                               | 0x4);
2238         }
2239         if (has_loopback_gain(phy))
2240                 b43_calc_loopback_gain(dev);
2241
2242         if (phy->radio_rev != 8) {
2243                 if (gphy->initval == 0xFFFF)
2244                         gphy->initval = b43_radio_init2050(dev);
2245                 else
2246                         b43_radio_write16(dev, 0x0078, gphy->initval);
2247         }
2248         b43_lo_g_init(dev);
2249         if (has_tx_magnification(phy)) {
2250                 b43_radio_write16(dev, 0x52,
2251                                   (b43_radio_read16(dev, 0x52) & 0xFF00)
2252                                   | gphy->lo_control->tx_bias | gphy->
2253                                   lo_control->tx_magn);
2254         } else {
2255                 b43_radio_write16(dev, 0x52,
2256                                   (b43_radio_read16(dev, 0x52) & 0xFFF0)
2257                                   | gphy->lo_control->tx_bias);
2258         }
2259         if (phy->rev >= 6) {
2260                 b43_phy_write(dev, B43_PHY_CCK(0x36),
2261                               (b43_phy_read(dev, B43_PHY_CCK(0x36))
2262                                & 0x0FFF) | (gphy->lo_control->
2263                                             tx_bias << 12));
2264         }
2265         if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)
2266                 b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x8075);
2267         else
2268                 b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x807F);
2269         if (phy->rev < 2)
2270                 b43_phy_write(dev, B43_PHY_CCK(0x2F), 0x101);
2271         else
2272                 b43_phy_write(dev, B43_PHY_CCK(0x2F), 0x202);
2273         if (phy->gmode || phy->rev >= 2) {
2274                 b43_lo_g_adjust(dev);
2275                 b43_phy_write(dev, B43_PHY_LO_MASK, 0x8078);
2276         }
2277
2278         if (!(dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) {
2279                 /* The specs state to update the NRSSI LT with
2280                  * the value 0x7FFFFFFF here. I think that is some weird
2281                  * compiler optimization in the original driver.
2282                  * Essentially, what we do here is resetting all NRSSI LT
2283                  * entries to -32 (see the clamp_val() in nrssi_hw_update())
2284                  */
2285                 b43_nrssi_hw_update(dev, 0xFFFF);       //FIXME?
2286                 b43_calc_nrssi_threshold(dev);
2287         } else if (phy->gmode || phy->rev >= 2) {
2288                 if (gphy->nrssi[0] == -1000) {
2289                         B43_WARN_ON(gphy->nrssi[1] != -1000);
2290                         b43_calc_nrssi_slope(dev);
2291                 } else
2292                         b43_calc_nrssi_threshold(dev);
2293         }
2294         if (phy->radio_rev == 8)
2295                 b43_phy_write(dev, B43_PHY_EXTG(0x05), 0x3230);
2296         b43_phy_init_pctl(dev);
2297         /* FIXME: The spec says in the following if, the 0 should be replaced
2298            'if OFDM may not be used in the current locale'
2299            but OFDM is legal everywhere */
2300         if ((dev->dev->bus->chip_id == 0x4306
2301              && dev->dev->bus->chip_package == 2) || 0) {
2302                 b43_phy_write(dev, B43_PHY_CRS0, b43_phy_read(dev, B43_PHY_CRS0)
2303                               & 0xBFFF);
2304                 b43_phy_write(dev, B43_PHY_OFDM(0xC3),
2305                               b43_phy_read(dev, B43_PHY_OFDM(0xC3))
2306                               & 0x7FFF);
2307         }
2308 }
2309
2310 void b43_gphy_channel_switch(struct b43_wldev *dev,
2311                              unsigned int channel,
2312                              bool synthetic_pu_workaround)
2313 {
2314         if (synthetic_pu_workaround)
2315                 b43_synth_pu_workaround(dev, channel);
2316
2317         b43_write16(dev, B43_MMIO_CHANNEL, channel2freq_bg(channel));
2318
2319         if (channel == 14) {
2320                 if (dev->dev->bus->sprom.country_code ==
2321                     SSB_SPROM1CCODE_JAPAN)
2322                         b43_hf_write(dev,
2323                                      b43_hf_read(dev) & ~B43_HF_ACPR);
2324                 else
2325                         b43_hf_write(dev,
2326                                      b43_hf_read(dev) | B43_HF_ACPR);
2327                 b43_write16(dev, B43_MMIO_CHANNEL_EXT,
2328                             b43_read16(dev, B43_MMIO_CHANNEL_EXT)
2329                             | (1 << 11));
2330         } else {
2331                 b43_write16(dev, B43_MMIO_CHANNEL_EXT,
2332                             b43_read16(dev, B43_MMIO_CHANNEL_EXT)
2333                             & 0xF7BF);
2334         }
2335 }
2336
2337 static void default_baseband_attenuation(struct b43_wldev *dev,
2338                                          struct b43_bbatt *bb)
2339 {
2340         struct b43_phy *phy = &dev->phy;
2341
2342         if (phy->radio_ver == 0x2050 && phy->radio_rev < 6)
2343                 bb->att = 0;
2344         else
2345                 bb->att = 2;
2346 }
2347
2348 static void default_radio_attenuation(struct b43_wldev *dev,
2349                                       struct b43_rfatt *rf)
2350 {
2351         struct ssb_bus *bus = dev->dev->bus;
2352         struct b43_phy *phy = &dev->phy;
2353
2354         rf->with_padmix = 0;
2355
2356         if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM &&
2357             bus->boardinfo.type == SSB_BOARD_BCM4309G) {
2358                 if (bus->boardinfo.rev < 0x43) {
2359                         rf->att = 2;
2360                         return;
2361                 } else if (bus->boardinfo.rev < 0x51) {
2362                         rf->att = 3;
2363                         return;
2364                 }
2365         }
2366
2367         if (phy->type == B43_PHYTYPE_A) {
2368                 rf->att = 0x60;
2369                 return;
2370         }
2371
2372         switch (phy->radio_ver) {
2373         case 0x2053:
2374                 switch (phy->radio_rev) {
2375                 case 1:
2376                         rf->att = 6;
2377                         return;
2378                 }
2379                 break;
2380         case 0x2050:
2381                 switch (phy->radio_rev) {
2382                 case 0:
2383                         rf->att = 5;
2384                         return;
2385                 case 1:
2386                         if (phy->type == B43_PHYTYPE_G) {
2387                                 if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM
2388                                     && bus->boardinfo.type == SSB_BOARD_BCM4309G
2389                                     && bus->boardinfo.rev >= 30)
2390                                         rf->att = 3;
2391                                 else if (bus->boardinfo.vendor ==
2392                                          SSB_BOARDVENDOR_BCM
2393                                          && bus->boardinfo.type ==
2394                                          SSB_BOARD_BU4306)
2395                                         rf->att = 3;
2396                                 else
2397                                         rf->att = 1;
2398                         } else {
2399                                 if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM
2400                                     && bus->boardinfo.type == SSB_BOARD_BCM4309G
2401                                     && bus->boardinfo.rev >= 30)
2402                                         rf->att = 7;
2403                                 else
2404                                         rf->att = 6;
2405                         }
2406                         return;
2407                 case 2:
2408                         if (phy->type == B43_PHYTYPE_G) {
2409                                 if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM
2410                                     && bus->boardinfo.type == SSB_BOARD_BCM4309G
2411                                     && bus->boardinfo.rev >= 30)
2412                                         rf->att = 3;
2413                                 else if (bus->boardinfo.vendor ==
2414                                          SSB_BOARDVENDOR_BCM
2415                                          && bus->boardinfo.type ==
2416                                          SSB_BOARD_BU4306)
2417                                         rf->att = 5;
2418                                 else if (bus->chip_id == 0x4320)
2419                                         rf->att = 4;
2420                                 else
2421                                         rf->att = 3;
2422                         } else
2423                                 rf->att = 6;
2424                         return;
2425                 case 3:
2426                         rf->att = 5;
2427                         return;
2428                 case 4:
2429                 case 5:
2430                         rf->att = 1;
2431                         return;
2432                 case 6:
2433                 case 7:
2434                         rf->att = 5;
2435                         return;
2436                 case 8:
2437                         rf->att = 0xA;
2438                         rf->with_padmix = 1;
2439                         return;
2440                 case 9:
2441                 default:
2442                         rf->att = 5;
2443                         return;
2444                 }
2445         }
2446         rf->att = 5;
2447 }
2448
2449 static u16 default_tx_control(struct b43_wldev *dev)
2450 {
2451         struct b43_phy *phy = &dev->phy;
2452
2453         if (phy->radio_ver != 0x2050)
2454                 return 0;
2455         if (phy->radio_rev == 1)
2456                 return B43_TXCTL_PA2DB | B43_TXCTL_TXMIX;
2457         if (phy->radio_rev < 6)
2458                 return B43_TXCTL_PA2DB;
2459         if (phy->radio_rev == 8)
2460                 return B43_TXCTL_TXMIX;
2461         return 0;
2462 }
2463
2464 static u8 b43_gphy_aci_detect(struct b43_wldev *dev, u8 channel)
2465 {
2466         struct b43_phy *phy = &dev->phy;
2467         struct b43_phy_g *gphy = phy->g;
2468         u8 ret = 0;
2469         u16 saved, rssi, temp;
2470         int i, j = 0;
2471
2472         saved = b43_phy_read(dev, 0x0403);
2473         b43_switch_channel(dev, channel);
2474         b43_phy_write(dev, 0x0403, (saved & 0xFFF8) | 5);
2475         if (gphy->aci_hw_rssi)
2476                 rssi = b43_phy_read(dev, 0x048A) & 0x3F;
2477         else
2478                 rssi = saved & 0x3F;
2479         /* clamp temp to signed 5bit */
2480         if (rssi > 32)
2481                 rssi -= 64;
2482         for (i = 0; i < 100; i++) {
2483                 temp = (b43_phy_read(dev, 0x047F) >> 8) & 0x3F;
2484                 if (temp > 32)
2485                         temp -= 64;
2486                 if (temp < rssi)
2487                         j++;
2488                 if (j >= 20)
2489                         ret = 1;
2490         }
2491         b43_phy_write(dev, 0x0403, saved);
2492
2493         return ret;
2494 }
2495
2496 static u8 b43_gphy_aci_scan(struct b43_wldev *dev)
2497 {
2498         struct b43_phy *phy = &dev->phy;
2499         u8 ret[13];
2500         unsigned int channel = phy->channel;
2501         unsigned int i, j, start, end;
2502
2503         if (!((phy->type == B43_PHYTYPE_G) && (phy->rev > 0)))
2504                 return 0;
2505
2506         b43_phy_lock(dev);
2507         b43_radio_lock(dev);
2508         b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) & 0xFFFC);
2509         b43_phy_write(dev, B43_PHY_G_CRS,
2510                       b43_phy_read(dev, B43_PHY_G_CRS) & 0x7FFF);
2511         b43_set_all_gains(dev, 3, 8, 1);
2512
2513         start = (channel - 5 > 0) ? channel - 5 : 1;
2514         end = (channel + 5 < 14) ? channel + 5 : 13;
2515
2516         for (i = start; i <= end; i++) {
2517                 if (abs(channel - i) > 2)
2518                         ret[i - 1] = b43_gphy_aci_detect(dev, i);
2519         }
2520         b43_switch_channel(dev, channel);
2521         b43_phy_write(dev, 0x0802,
2522                       (b43_phy_read(dev, 0x0802) & 0xFFFC) | 0x0003);
2523         b43_phy_write(dev, 0x0403, b43_phy_read(dev, 0x0403) & 0xFFF8);
2524         b43_phy_write(dev, B43_PHY_G_CRS,
2525                       b43_phy_read(dev, B43_PHY_G_CRS) | 0x8000);
2526         b43_set_original_gains(dev);
2527         for (i = 0; i < 13; i++) {
2528                 if (!ret[i])
2529                         continue;
2530                 end = (i + 5 < 13) ? i + 5 : 13;
2531                 for (j = i; j < end; j++)
2532                         ret[j] = 1;
2533         }
2534         b43_radio_unlock(dev);
2535         b43_phy_unlock(dev);
2536
2537         return ret[channel - 1];
2538 }
2539
2540 static s32 b43_tssi2dbm_ad(s32 num, s32 den)
2541 {
2542         if (num < 0)
2543                 return num / den;
2544         else
2545                 return (num + den / 2) / den;
2546 }
2547
2548 static s8 b43_tssi2dbm_entry(s8 entry[], u8 index,
2549                              s16 pab0, s16 pab1, s16 pab2)
2550 {
2551         s32 m1, m2, f = 256, q, delta;
2552         s8 i = 0;
2553
2554         m1 = b43_tssi2dbm_ad(16 * pab0 + index * pab1, 32);
2555         m2 = max(b43_tssi2dbm_ad(32768 + index * pab2, 256), 1);
2556         do {
2557                 if (i > 15)
2558                         return -EINVAL;
2559                 q = b43_tssi2dbm_ad(f * 4096 -
2560                                     b43_tssi2dbm_ad(m2 * f, 16) * f, 2048);
2561                 delta = abs(q - f);
2562                 f = q;
2563                 i++;
2564         } while (delta >= 2);
2565         entry[index] = clamp_val(b43_tssi2dbm_ad(m1 * f, 8192), -127, 128);
2566         return 0;
2567 }
2568
2569 u8 * b43_generate_dyn_tssi2dbm_tab(struct b43_wldev *dev,
2570                                    s16 pab0, s16 pab1, s16 pab2)
2571 {
2572         unsigned int i;
2573         u8 *tab;
2574         int err;
2575
2576         tab = kmalloc(64, GFP_KERNEL);
2577         if (!tab) {
2578                 b43err(dev->wl, "Could not allocate memory "
2579                        "for tssi2dbm table\n");
2580                 return NULL;
2581         }
2582         for (i = 0; i < 64; i++) {
2583                 err = b43_tssi2dbm_entry(tab, i, pab0, pab1, pab2);
2584                 if (err) {
2585                         b43err(dev->wl, "Could not generate "
2586                                "tssi2dBm table\n");
2587                         kfree(tab);
2588                         return NULL;
2589                 }
2590         }
2591
2592         return tab;
2593 }
2594
2595 /* Initialise the TSSI->dBm lookup table */
2596 static int b43_gphy_init_tssi2dbm_table(struct b43_wldev *dev)
2597 {
2598         struct b43_phy *phy = &dev->phy;
2599         struct b43_phy_g *gphy = phy->g;
2600         s16 pab0, pab1, pab2;
2601
2602         pab0 = (s16) (dev->dev->bus->sprom.pa0b0);
2603         pab1 = (s16) (dev->dev->bus->sprom.pa0b1);
2604         pab2 = (s16) (dev->dev->bus->sprom.pa0b2);
2605
2606         B43_WARN_ON((dev->dev->bus->chip_id == 0x4301) &&
2607                     (phy->radio_ver != 0x2050)); /* Not supported anymore */
2608
2609         gphy->dyn_tssi_tbl = 0;
2610
2611         if (pab0 != 0 && pab1 != 0 && pab2 != 0 &&
2612             pab0 != -1 && pab1 != -1 && pab2 != -1) {
2613                 /* The pabX values are set in SPROM. Use them. */
2614                 if ((s8) dev->dev->bus->sprom.itssi_bg != 0 &&
2615                     (s8) dev->dev->bus->sprom.itssi_bg != -1) {
2616                         gphy->tgt_idle_tssi =
2617                                 (s8) (dev->dev->bus->sprom.itssi_bg);
2618                 } else
2619                         gphy->tgt_idle_tssi = 62;
2620                 gphy->tssi2dbm = b43_generate_dyn_tssi2dbm_tab(dev, pab0,
2621                                                                pab1, pab2);
2622                 if (!gphy->tssi2dbm)
2623                         return -ENOMEM;
2624                 gphy->dyn_tssi_tbl = 1;
2625         } else {
2626                 /* pabX values not set in SPROM. */
2627                 gphy->tgt_idle_tssi = 52;
2628                 gphy->tssi2dbm = b43_tssi2dbm_g_table;
2629         }
2630
2631         return 0;
2632 }
2633
2634 static int b43_gphy_op_allocate(struct b43_wldev *dev)
2635 {
2636         struct b43_phy_g *gphy;
2637         struct b43_txpower_lo_control *lo;
2638         int err, i;
2639
2640         gphy = kzalloc(sizeof(*gphy), GFP_KERNEL);
2641         if (!gphy) {
2642                 err = -ENOMEM;
2643                 goto error;
2644         }
2645         dev->phy.g = gphy;
2646
2647         memset(gphy->minlowsig, 0xFF, sizeof(gphy->minlowsig));
2648
2649         /* NRSSI */
2650         for (i = 0; i < ARRAY_SIZE(gphy->nrssi); i++)
2651                 gphy->nrssi[i] = -1000;
2652         for (i = 0; i < ARRAY_SIZE(gphy->nrssi_lt); i++)
2653                 gphy->nrssi_lt[i] = i;
2654
2655         gphy->lofcal = 0xFFFF;
2656         gphy->initval = 0xFFFF;
2657
2658         gphy->interfmode = B43_INTERFMODE_NONE;
2659
2660         /* OFDM-table address caching. */
2661         gphy->ofdmtab_addr_direction = B43_OFDMTAB_DIRECTION_UNKNOWN;
2662
2663         gphy->average_tssi = 0xFF;
2664
2665         lo = kzalloc(sizeof(*lo), GFP_KERNEL);
2666         if (!lo) {
2667                 err = -ENOMEM;
2668                 goto err_free_gphy;
2669         }
2670         gphy->lo_control = lo;
2671
2672         lo->tx_bias = 0xFF;
2673         INIT_LIST_HEAD(&lo->calib_list);
2674
2675         err = b43_gphy_init_tssi2dbm_table(dev);
2676         if (err)
2677                 goto err_free_lo;
2678
2679         return 0;
2680
2681 err_free_lo:
2682         kfree(lo);
2683 err_free_gphy:
2684         kfree(gphy);
2685 error:
2686         return err;
2687 }
2688
2689 static int b43_gphy_op_prepare(struct b43_wldev *dev)
2690 {
2691         struct b43_phy *phy = &dev->phy;
2692         struct b43_phy_g *gphy = phy->g;
2693         struct b43_txpower_lo_control *lo = gphy->lo_control;
2694
2695         B43_WARN_ON(phy->type != B43_PHYTYPE_G);
2696
2697         default_baseband_attenuation(dev, &gphy->bbatt);
2698         default_radio_attenuation(dev, &gphy->rfatt);
2699         gphy->tx_control = (default_tx_control(dev) << 4);
2700         generate_rfatt_list(dev, &lo->rfatt_list);
2701         generate_bbatt_list(dev, &lo->bbatt_list);
2702
2703         /* Commit previous writes */
2704         b43_read32(dev, B43_MMIO_MACCTL);
2705
2706         if (phy->rev == 1) {
2707                 /* Workaround: Temporarly disable gmode through the early init
2708                  * phase, as the gmode stuff is not needed for phy rev 1 */
2709                 phy->gmode = 0;
2710                 b43_wireless_core_reset(dev, 0);
2711                 b43_phy_initg(dev);
2712                 phy->gmode = 1;
2713                 b43_wireless_core_reset(dev, B43_TMSLOW_GMODE);
2714         }
2715
2716         return 0;
2717 }
2718
2719 static int b43_gphy_op_init(struct b43_wldev *dev)
2720 {
2721         struct b43_phy_g *gphy = dev->phy.g;
2722
2723         b43_phy_initg(dev);
2724         gphy->initialised = 1;
2725
2726         return 0;
2727 }
2728
2729 static void b43_gphy_op_exit(struct b43_wldev *dev)
2730 {
2731         struct b43_phy_g *gphy = dev->phy.g;
2732
2733         if (gphy->initialised) {
2734                 //TODO
2735                 gphy->initialised = 0;
2736         }
2737         b43_lo_g_cleanup(dev);
2738         kfree(gphy->lo_control);
2739         if (gphy->dyn_tssi_tbl)
2740                 kfree(gphy->tssi2dbm);
2741         kfree(gphy);
2742         dev->phy.g = NULL;
2743 }
2744
2745 static u16 b43_gphy_op_read(struct b43_wldev *dev, u16 reg)
2746 {
2747         b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
2748         return b43_read16(dev, B43_MMIO_PHY_DATA);
2749 }
2750
2751 static void b43_gphy_op_write(struct b43_wldev *dev, u16 reg, u16 value)
2752 {
2753         b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
2754         b43_write16(dev, B43_MMIO_PHY_DATA, value);
2755 }
2756
2757 static u16 b43_gphy_op_radio_read(struct b43_wldev *dev, u16 reg)
2758 {
2759         /* Register 1 is a 32-bit register. */
2760         B43_WARN_ON(reg == 1);
2761         /* G-PHY needs 0x80 for read access. */
2762         reg |= 0x80;
2763
2764         b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
2765         return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
2766 }
2767
2768 static void b43_gphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
2769 {
2770         /* Register 1 is a 32-bit register. */
2771         B43_WARN_ON(reg == 1);
2772
2773         b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
2774         b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
2775 }
2776
2777 static bool b43_gphy_op_supports_hwpctl(struct b43_wldev *dev)
2778 {
2779         return (dev->phy.rev >= 6);
2780 }
2781
2782 static void b43_gphy_op_software_rfkill(struct b43_wldev *dev,
2783                                         enum rfkill_state state)
2784 {
2785         struct b43_phy *phy = &dev->phy;
2786         struct b43_phy_g *gphy = phy->g;
2787         unsigned int channel;
2788
2789         might_sleep();
2790
2791         if (state == RFKILL_STATE_UNBLOCKED) {
2792                 /* Turn radio ON */
2793                 if (phy->radio_on)
2794                         return;
2795
2796                 b43_phy_write(dev, 0x0015, 0x8000);
2797                 b43_phy_write(dev, 0x0015, 0xCC00);
2798                 b43_phy_write(dev, 0x0015, (phy->gmode ? 0x00C0 : 0x0000));
2799                 if (gphy->radio_off_context.valid) {
2800                         /* Restore the RFover values. */
2801                         b43_phy_write(dev, B43_PHY_RFOVER,
2802                                       gphy->radio_off_context.rfover);
2803                         b43_phy_write(dev, B43_PHY_RFOVERVAL,
2804                                       gphy->radio_off_context.rfoverval);
2805                         gphy->radio_off_context.valid = 0;
2806                 }
2807                 channel = phy->channel;
2808                 b43_gphy_channel_switch(dev, 6, 1);
2809                 b43_gphy_channel_switch(dev, channel, 0);
2810         } else {
2811                 /* Turn radio OFF */
2812                 u16 rfover, rfoverval;
2813
2814                 rfover = b43_phy_read(dev, B43_PHY_RFOVER);
2815                 rfoverval = b43_phy_read(dev, B43_PHY_RFOVERVAL);
2816                 gphy->radio_off_context.rfover = rfover;
2817                 gphy->radio_off_context.rfoverval = rfoverval;
2818                 gphy->radio_off_context.valid = 1;
2819                 b43_phy_write(dev, B43_PHY_RFOVER, rfover | 0x008C);
2820                 b43_phy_write(dev, B43_PHY_RFOVERVAL, rfoverval & 0xFF73);
2821         }
2822 }
2823
2824 static int b43_gphy_op_switch_channel(struct b43_wldev *dev,
2825                                       unsigned int new_channel)
2826 {
2827         if ((new_channel < 1) || (new_channel > 14))
2828                 return -EINVAL;
2829         b43_gphy_channel_switch(dev, new_channel, 0);
2830
2831         return 0;
2832 }
2833
2834 static unsigned int b43_gphy_op_get_default_chan(struct b43_wldev *dev)
2835 {
2836         return 1; /* Default to channel 1 */
2837 }
2838
2839 static void b43_gphy_op_set_rx_antenna(struct b43_wldev *dev, int antenna)
2840 {
2841         struct b43_phy *phy = &dev->phy;
2842         u64 hf;
2843         u16 tmp;
2844         int autodiv = 0;
2845
2846         if (antenna == B43_ANTENNA_AUTO0 || antenna == B43_ANTENNA_AUTO1)
2847                 autodiv = 1;
2848
2849         hf = b43_hf_read(dev);
2850         hf &= ~B43_HF_ANTDIVHELP;
2851         b43_hf_write(dev, hf);
2852
2853         tmp = b43_phy_read(dev, B43_PHY_BBANDCFG);
2854         tmp &= ~B43_PHY_BBANDCFG_RXANT;
2855         tmp |= (autodiv ? B43_ANTENNA_AUTO0 : antenna)
2856                         << B43_PHY_BBANDCFG_RXANT_SHIFT;
2857         b43_phy_write(dev, B43_PHY_BBANDCFG, tmp);
2858
2859         if (autodiv) {
2860                 tmp = b43_phy_read(dev, B43_PHY_ANTDWELL);
2861                 if (antenna == B43_ANTENNA_AUTO0)
2862                         tmp &= ~B43_PHY_ANTDWELL_AUTODIV1;
2863                 else
2864                         tmp |= B43_PHY_ANTDWELL_AUTODIV1;
2865                 b43_phy_write(dev, B43_PHY_ANTDWELL, tmp);
2866         }
2867         tmp = b43_phy_read(dev, B43_PHY_ANTWRSETT);
2868         if (autodiv)
2869                 tmp |= B43_PHY_ANTWRSETT_ARXDIV;
2870         else
2871                 tmp &= ~B43_PHY_ANTWRSETT_ARXDIV;
2872         b43_phy_write(dev, B43_PHY_ANTWRSETT, tmp);
2873         if (phy->rev >= 2) {
2874                 tmp = b43_phy_read(dev, B43_PHY_OFDM61);
2875                 tmp |= B43_PHY_OFDM61_10;
2876                 b43_phy_write(dev, B43_PHY_OFDM61, tmp);
2877
2878                 tmp =
2879                     b43_phy_read(dev, B43_PHY_DIVSRCHGAINBACK);
2880                 tmp = (tmp & 0xFF00) | 0x15;
2881                 b43_phy_write(dev, B43_PHY_DIVSRCHGAINBACK,
2882                               tmp);
2883
2884                 if (phy->rev == 2) {
2885                         b43_phy_write(dev, B43_PHY_ADIVRELATED,
2886                                       8);
2887                 } else {
2888                         tmp =
2889                             b43_phy_read(dev,
2890                                          B43_PHY_ADIVRELATED);
2891                         tmp = (tmp & 0xFF00) | 8;
2892                         b43_phy_write(dev, B43_PHY_ADIVRELATED,
2893                                       tmp);
2894                 }
2895         }
2896         if (phy->rev >= 6)
2897                 b43_phy_write(dev, B43_PHY_OFDM9B, 0xDC);
2898
2899         hf |= B43_HF_ANTDIVHELP;
2900         b43_hf_write(dev, hf);
2901 }
2902
2903 static int b43_gphy_op_interf_mitigation(struct b43_wldev *dev,
2904                                          enum b43_interference_mitigation mode)
2905 {
2906         struct b43_phy *phy = &dev->phy;
2907         struct b43_phy_g *gphy = phy->g;
2908         int currentmode;
2909
2910         B43_WARN_ON(phy->type != B43_PHYTYPE_G);
2911         if ((phy->rev == 0) || (!phy->gmode))
2912                 return -ENODEV;
2913
2914         gphy->aci_wlan_automatic = 0;
2915         switch (mode) {
2916         case B43_INTERFMODE_AUTOWLAN:
2917                 gphy->aci_wlan_automatic = 1;
2918                 if (gphy->aci_enable)
2919                         mode = B43_INTERFMODE_MANUALWLAN;
2920                 else
2921                         mode = B43_INTERFMODE_NONE;
2922                 break;
2923         case B43_INTERFMODE_NONE:
2924         case B43_INTERFMODE_NONWLAN:
2925         case B43_INTERFMODE_MANUALWLAN:
2926                 break;
2927         default:
2928                 return -EINVAL;
2929         }
2930
2931         currentmode = gphy->interfmode;
2932         if (currentmode == mode)
2933                 return 0;
2934         if (currentmode != B43_INTERFMODE_NONE)
2935                 b43_radio_interference_mitigation_disable(dev, currentmode);
2936
2937         if (mode == B43_INTERFMODE_NONE) {
2938                 gphy->aci_enable = 0;
2939                 gphy->aci_hw_rssi = 0;
2940         } else
2941                 b43_radio_interference_mitigation_enable(dev, mode);
2942         gphy->interfmode = mode;
2943
2944         return 0;
2945 }
2946
2947 /* http://bcm-specs.sipsolutions.net/EstimatePowerOut
2948  * This function converts a TSSI value to dBm in Q5.2
2949  */
2950 static s8 b43_gphy_estimate_power_out(struct b43_wldev *dev, s8 tssi)
2951 {
2952         struct b43_phy_g *gphy = dev->phy.g;
2953         s8 dbm;
2954         s32 tmp;
2955
2956         tmp = (gphy->tgt_idle_tssi - gphy->cur_idle_tssi + tssi);
2957         tmp = clamp_val(tmp, 0x00, 0x3F);
2958         dbm = gphy->tssi2dbm[tmp];
2959
2960         return dbm;
2961 }
2962
2963 static void b43_put_attenuation_into_ranges(struct b43_wldev *dev,
2964                                             int *_bbatt, int *_rfatt)
2965 {
2966         int rfatt = *_rfatt;
2967         int bbatt = *_bbatt;
2968         struct b43_txpower_lo_control *lo = dev->phy.g->lo_control;
2969
2970         /* Get baseband and radio attenuation values into their permitted ranges.
2971          * Radio attenuation affects power level 4 times as much as baseband. */
2972
2973         /* Range constants */
2974         const int rf_min = lo->rfatt_list.min_val;
2975         const int rf_max = lo->rfatt_list.max_val;
2976         const int bb_min = lo->bbatt_list.min_val;
2977         const int bb_max = lo->bbatt_list.max_val;
2978
2979         while (1) {
2980                 if (rfatt > rf_max && bbatt > bb_max - 4)
2981                         break;  /* Can not get it into ranges */
2982                 if (rfatt < rf_min && bbatt < bb_min + 4)
2983                         break;  /* Can not get it into ranges */
2984                 if (bbatt > bb_max && rfatt > rf_max - 1)
2985                         break;  /* Can not get it into ranges */
2986                 if (bbatt < bb_min && rfatt < rf_min + 1)
2987                         break;  /* Can not get it into ranges */
2988
2989                 if (bbatt > bb_max) {
2990                         bbatt -= 4;
2991                         rfatt += 1;
2992                         continue;
2993                 }
2994                 if (bbatt < bb_min) {
2995                         bbatt += 4;
2996                         rfatt -= 1;
2997                         continue;
2998                 }
2999                 if (rfatt > rf_max) {
3000                         rfatt -= 1;
3001                         bbatt += 4;
3002                         continue;
3003                 }
3004                 if (rfatt < rf_min) {
3005                         rfatt += 1;
3006                         bbatt -= 4;
3007                         continue;
3008                 }
3009                 break;
3010         }
3011
3012         *_rfatt = clamp_val(rfatt, rf_min, rf_max);
3013         *_bbatt = clamp_val(bbatt, bb_min, bb_max);
3014 }
3015
3016 static void b43_gphy_op_adjust_txpower(struct b43_wldev *dev)
3017 {
3018         struct b43_phy *phy = &dev->phy;
3019         struct b43_phy_g *gphy = phy->g;
3020         int rfatt, bbatt;
3021         u8 tx_control;
3022
3023         spin_lock_irq(&dev->wl->irq_lock);
3024
3025         /* Calculate the new attenuation values. */
3026         bbatt = gphy->bbatt.att;
3027         bbatt += gphy->bbatt_delta;
3028         rfatt = gphy->rfatt.att;
3029         rfatt += gphy->rfatt_delta;
3030
3031         b43_put_attenuation_into_ranges(dev, &bbatt, &rfatt);
3032         tx_control = gphy->tx_control;
3033         if ((phy->radio_ver == 0x2050) && (phy->radio_rev == 2)) {
3034                 if (rfatt <= 1) {
3035                         if (tx_control == 0) {
3036                                 tx_control =
3037                                     B43_TXCTL_PA2DB |
3038                                     B43_TXCTL_TXMIX;
3039                                 rfatt += 2;
3040                                 bbatt += 2;
3041                         } else if (dev->dev->bus->sprom.
3042                                    boardflags_lo &
3043                                    B43_BFL_PACTRL) {
3044                                 bbatt += 4 * (rfatt - 2);
3045                                 rfatt = 2;
3046                         }
3047                 } else if (rfatt > 4 && tx_control) {
3048                         tx_control = 0;
3049                         if (bbatt < 3) {
3050                                 rfatt -= 3;
3051                                 bbatt += 2;
3052                         } else {
3053                                 rfatt -= 2;
3054                                 bbatt -= 2;
3055                         }
3056                 }
3057         }
3058         /* Save the control values */
3059         gphy->tx_control = tx_control;
3060         b43_put_attenuation_into_ranges(dev, &bbatt, &rfatt);
3061         gphy->rfatt.att = rfatt;
3062         gphy->bbatt.att = bbatt;
3063
3064         /* We drop the lock early, so we can sleep during hardware
3065          * adjustment. Possible races with op_recalc_txpower are harmless,
3066          * as we will be called once again in case we raced. */
3067         spin_unlock_irq(&dev->wl->irq_lock);
3068
3069         if (b43_debug(dev, B43_DBG_XMITPOWER))
3070                 b43dbg(dev->wl, "Adjusting TX power\n");
3071
3072         /* Adjust the hardware */
3073         b43_phy_lock(dev);
3074         b43_radio_lock(dev);
3075         b43_set_txpower_g(dev, &gphy->bbatt, &gphy->rfatt,
3076                           gphy->tx_control);
3077         b43_radio_unlock(dev);
3078         b43_phy_unlock(dev);
3079 }
3080
3081 static enum b43_txpwr_result b43_gphy_op_recalc_txpower(struct b43_wldev *dev,
3082                                                         bool ignore_tssi)
3083 {
3084         struct b43_phy *phy = &dev->phy;
3085         struct b43_phy_g *gphy = phy->g;
3086         unsigned int average_tssi;
3087         int cck_result, ofdm_result;
3088         int estimated_pwr, desired_pwr, pwr_adjust;
3089         int rfatt_delta, bbatt_delta;
3090         unsigned int max_pwr;
3091
3092         /* First get the average TSSI */
3093         cck_result = b43_phy_shm_tssi_read(dev, B43_SHM_SH_TSSI_CCK);
3094         ofdm_result = b43_phy_shm_tssi_read(dev, B43_SHM_SH_TSSI_OFDM_G);
3095         if ((cck_result < 0) && (ofdm_result < 0)) {
3096                 /* No TSSI information available */
3097                 if (!ignore_tssi)
3098                         goto no_adjustment_needed;
3099                 cck_result = 0;
3100                 ofdm_result = 0;
3101         }
3102         if (cck_result < 0)
3103                 average_tssi = ofdm_result;
3104         else if (ofdm_result < 0)
3105                 average_tssi = cck_result;
3106         else
3107                 average_tssi = (cck_result + ofdm_result) / 2;
3108         /* Merge the average with the stored value. */
3109         if (likely(gphy->average_tssi != 0xFF))
3110                 average_tssi = (average_tssi + gphy->average_tssi) / 2;
3111         gphy->average_tssi = average_tssi;
3112         B43_WARN_ON(average_tssi >= B43_TSSI_MAX);
3113
3114         /* Estimate the TX power emission based on the TSSI */
3115         estimated_pwr = b43_gphy_estimate_power_out(dev, average_tssi);
3116
3117         B43_WARN_ON(phy->type != B43_PHYTYPE_G);
3118         max_pwr = dev->dev->bus->sprom.maxpwr_bg;
3119         if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)
3120                 max_pwr -= 3; /* minus 0.75 */
3121         if (unlikely(max_pwr >= INT_TO_Q52(30/*dBm*/))) {
3122                 b43warn(dev->wl,
3123                         "Invalid max-TX-power value in SPROM.\n");
3124                 max_pwr = INT_TO_Q52(20); /* fake it */
3125                 dev->dev->bus->sprom.maxpwr_bg = max_pwr;
3126         }
3127
3128         /* Get desired power (in Q5.2) */
3129         if (phy->desired_txpower < 0)
3130                 desired_pwr = INT_TO_Q52(0);
3131         else
3132                 desired_pwr = INT_TO_Q52(phy->desired_txpower);
3133         /* And limit it. max_pwr already is Q5.2 */
3134         desired_pwr = clamp_val(desired_pwr, 0, max_pwr);
3135         if (b43_debug(dev, B43_DBG_XMITPOWER)) {
3136                 b43dbg(dev->wl,
3137                        "[TX power]  current = " Q52_FMT
3138                        " dBm,  desired = " Q52_FMT
3139                        " dBm,  max = " Q52_FMT "\n",
3140                        Q52_ARG(estimated_pwr),
3141                        Q52_ARG(desired_pwr),
3142                        Q52_ARG(max_pwr));
3143         }
3144
3145         /* Calculate the adjustment delta. */
3146         pwr_adjust = desired_pwr - estimated_pwr;
3147         if (pwr_adjust == 0)
3148                 goto no_adjustment_needed;
3149
3150         /* RF attenuation delta. */
3151         rfatt_delta = ((pwr_adjust + 7) / 8);
3152         /* Lower attenuation => Bigger power output. Negate it. */
3153         rfatt_delta = -rfatt_delta;
3154
3155         /* Baseband attenuation delta. */
3156         bbatt_delta = pwr_adjust / 2;
3157         /* Lower attenuation => Bigger power output. Negate it. */
3158         bbatt_delta = -bbatt_delta;
3159         /* RF att affects power level 4 times as much as
3160          * Baseband attennuation. Subtract it. */
3161         bbatt_delta -= 4 * rfatt_delta;
3162
3163         if (b43_debug(dev, B43_DBG_XMITPOWER)) {
3164                 int dbm = pwr_adjust < 0 ? -pwr_adjust : pwr_adjust;
3165                 b43dbg(dev->wl,
3166                        "[TX power deltas]  %s" Q52_FMT " dBm   =>   "
3167                        "bbatt-delta = %d,  rfatt-delta = %d\n",
3168                        (pwr_adjust < 0 ? "-" : ""), Q52_ARG(dbm),
3169                        bbatt_delta, rfatt_delta);
3170         }
3171         /* So do we finally need to adjust something in hardware? */
3172         if ((rfatt_delta == 0) && (bbatt_delta == 0))
3173                 goto no_adjustment_needed;
3174
3175         /* Save the deltas for later when we adjust the power. */
3176         gphy->bbatt_delta = bbatt_delta;
3177         gphy->rfatt_delta = rfatt_delta;
3178
3179         /* We need to adjust the TX power on the device. */
3180         return B43_TXPWR_RES_NEED_ADJUST;
3181
3182 no_adjustment_needed:
3183         return B43_TXPWR_RES_DONE;
3184 }
3185
3186 static void b43_gphy_op_pwork_15sec(struct b43_wldev *dev)
3187 {
3188         struct b43_phy *phy = &dev->phy;
3189         struct b43_phy_g *gphy = phy->g;
3190
3191         //TODO: update_aci_moving_average
3192         if (gphy->aci_enable && gphy->aci_wlan_automatic) {
3193                 b43_mac_suspend(dev);
3194                 if (!gphy->aci_enable && 1 /*TODO: not scanning? */ ) {
3195                         if (0 /*TODO: bunch of conditions */ ) {
3196                                 phy->ops->interf_mitigation(dev,
3197                                         B43_INTERFMODE_MANUALWLAN);
3198                         }
3199                 } else if (0 /*TODO*/) {
3200                            if (/*(aci_average > 1000) &&*/ !b43_gphy_aci_scan(dev))
3201                                 phy->ops->interf_mitigation(dev, B43_INTERFMODE_NONE);
3202                 }
3203                 b43_mac_enable(dev);
3204         } else if (gphy->interfmode == B43_INTERFMODE_NONWLAN &&
3205                    phy->rev == 1) {
3206                 //TODO: implement rev1 workaround
3207         }
3208         b43_lo_g_maintanance_work(dev);
3209 }
3210
3211 static void b43_gphy_op_pwork_60sec(struct b43_wldev *dev)
3212 {
3213         struct b43_phy *phy = &dev->phy;
3214
3215         if (!(dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI))
3216                 return;
3217
3218         b43_mac_suspend(dev);
3219         b43_calc_nrssi_slope(dev);
3220         if ((phy->radio_ver == 0x2050) && (phy->radio_rev == 8)) {
3221                 u8 old_chan = phy->channel;
3222
3223                 /* VCO Calibration */
3224                 if (old_chan >= 8)
3225                         b43_switch_channel(dev, 1);
3226                 else
3227                         b43_switch_channel(dev, 13);
3228                 b43_switch_channel(dev, old_chan);
3229         }
3230         b43_mac_enable(dev);
3231 }
3232
3233 const struct b43_phy_operations b43_phyops_g = {
3234         .allocate               = b43_gphy_op_allocate,
3235         .prepare                = b43_gphy_op_prepare,
3236         .init                   = b43_gphy_op_init,
3237         .exit                   = b43_gphy_op_exit,
3238         .phy_read               = b43_gphy_op_read,
3239         .phy_write              = b43_gphy_op_write,
3240         .radio_read             = b43_gphy_op_radio_read,
3241         .radio_write            = b43_gphy_op_radio_write,
3242         .supports_hwpctl        = b43_gphy_op_supports_hwpctl,
3243         .software_rfkill        = b43_gphy_op_software_rfkill,
3244         .switch_channel         = b43_gphy_op_switch_channel,
3245         .get_default_chan       = b43_gphy_op_get_default_chan,
3246         .set_rx_antenna         = b43_gphy_op_set_rx_antenna,
3247         .interf_mitigation      = b43_gphy_op_interf_mitigation,
3248         .recalc_txpower         = b43_gphy_op_recalc_txpower,
3249         .adjust_txpower         = b43_gphy_op_adjust_txpower,
3250         .pwork_15sec            = b43_gphy_op_pwork_15sec,
3251         .pwork_60sec            = b43_gphy_op_pwork_60sec,
3252 };