aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43/phy_n.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/b43/phy_n.c')
-rw-r--r--drivers/net/wireless/b43/phy_n.c1014
1 files changed, 760 insertions, 254 deletions
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 5a725703770c..05960ddde24e 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -29,6 +29,8 @@
29#include "b43.h" 29#include "b43.h"
30#include "phy_n.h" 30#include "phy_n.h"
31#include "tables_nphy.h" 31#include "tables_nphy.h"
32#include "radio_2055.h"
33#include "radio_2056.h"
32#include "main.h" 34#include "main.h"
33 35
34struct nphy_txgains { 36struct nphy_txgains {
@@ -65,6 +67,18 @@ enum b43_nphy_rf_sequence {
65 B43_RFSEQ_UPDATE_GAINU, 67 B43_RFSEQ_UPDATE_GAINU,
66}; 68};
67 69
70enum b43_nphy_rssi_type {
71 B43_NPHY_RSSI_X = 0,
72 B43_NPHY_RSSI_Y,
73 B43_NPHY_RSSI_Z,
74 B43_NPHY_RSSI_PWRDET,
75 B43_NPHY_RSSI_TSSI_I,
76 B43_NPHY_RSSI_TSSI_Q,
77 B43_NPHY_RSSI_TBD,
78};
79
80static void b43_nphy_stay_in_carrier_search(struct b43_wldev *dev,
81 bool enable);
68static void b43_nphy_set_rf_sequence(struct b43_wldev *dev, u8 cmd, 82static void b43_nphy_set_rf_sequence(struct b43_wldev *dev, u8 cmd,
69 u8 *events, u8 *delays, u8 length); 83 u8 *events, u8 *delays, u8 length);
70static void b43_nphy_force_rf_sequence(struct b43_wldev *dev, 84static void b43_nphy_force_rf_sequence(struct b43_wldev *dev,
@@ -73,22 +87,6 @@ static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field,
73 u16 value, u8 core, bool off); 87 u16 value, u8 core, bool off);
74static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, 88static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field,
75 u16 value, u8 core); 89 u16 value, u8 core);
76static int nphy_channel_switch(struct b43_wldev *dev, unsigned int channel);
77
78static inline bool b43_empty_chanspec(struct b43_chanspec *chanspec)
79{
80 return !chanspec->channel && !chanspec->sideband &&
81 !chanspec->b_width && !chanspec->b_freq;
82}
83
84static inline bool b43_eq_chanspecs(struct b43_chanspec *chanspec1,
85 struct b43_chanspec *chanspec2)
86{
87 return (chanspec1->channel == chanspec2->channel &&
88 chanspec1->sideband == chanspec2->sideband &&
89 chanspec1->b_width == chanspec2->b_width &&
90 chanspec1->b_freq == chanspec2->b_freq);
91}
92 90
93void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna) 91void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna)
94{//TODO 92{//TODO
@@ -141,6 +139,99 @@ static void b43_chantab_radio_upload(struct b43_wldev *dev,
141 b43_radio_write(dev, B2055_C2_TX_MXBGTRIM, e->radio_c2_tx_mxbgtrim); 139 b43_radio_write(dev, B2055_C2_TX_MXBGTRIM, e->radio_c2_tx_mxbgtrim);
142} 140}
143 141
142static void b43_chantab_radio_2056_upload(struct b43_wldev *dev,
143 const struct b43_nphy_channeltab_entry_rev3 *e)
144{
145 b43_radio_write(dev, B2056_SYN_PLL_VCOCAL1, e->radio_syn_pll_vcocal1);
146 b43_radio_write(dev, B2056_SYN_PLL_VCOCAL2, e->radio_syn_pll_vcocal2);
147 b43_radio_write(dev, B2056_SYN_PLL_REFDIV, e->radio_syn_pll_refdiv);
148 b43_radio_write(dev, B2056_SYN_PLL_MMD2, e->radio_syn_pll_mmd2);
149 b43_radio_write(dev, B2056_SYN_PLL_MMD1, e->radio_syn_pll_mmd1);
150 b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER1,
151 e->radio_syn_pll_loopfilter1);
152 b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER2,
153 e->radio_syn_pll_loopfilter2);
154 b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER3,
155 e->radio_syn_pll_loopfilter3);
156 b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER4,
157 e->radio_syn_pll_loopfilter4);
158 b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER5,
159 e->radio_syn_pll_loopfilter5);
160 b43_radio_write(dev, B2056_SYN_RESERVED_ADDR27,
161 e->radio_syn_reserved_addr27);
162 b43_radio_write(dev, B2056_SYN_RESERVED_ADDR28,
163 e->radio_syn_reserved_addr28);
164 b43_radio_write(dev, B2056_SYN_RESERVED_ADDR29,
165 e->radio_syn_reserved_addr29);
166 b43_radio_write(dev, B2056_SYN_LOGEN_VCOBUF1,
167 e->radio_syn_logen_vcobuf1);
168 b43_radio_write(dev, B2056_SYN_LOGEN_MIXER2, e->radio_syn_logen_mixer2);
169 b43_radio_write(dev, B2056_SYN_LOGEN_BUF3, e->radio_syn_logen_buf3);
170 b43_radio_write(dev, B2056_SYN_LOGEN_BUF4, e->radio_syn_logen_buf4);
171
172 b43_radio_write(dev, B2056_RX0 | B2056_RX_LNAA_TUNE,
173 e->radio_rx0_lnaa_tune);
174 b43_radio_write(dev, B2056_RX0 | B2056_RX_LNAG_TUNE,
175 e->radio_rx0_lnag_tune);
176
177 b43_radio_write(dev, B2056_TX0 | B2056_TX_INTPAA_BOOST_TUNE,
178 e->radio_tx0_intpaa_boost_tune);
179 b43_radio_write(dev, B2056_TX0 | B2056_TX_INTPAG_BOOST_TUNE,
180 e->radio_tx0_intpag_boost_tune);
181 b43_radio_write(dev, B2056_TX0 | B2056_TX_PADA_BOOST_TUNE,
182 e->radio_tx0_pada_boost_tune);
183 b43_radio_write(dev, B2056_TX0 | B2056_TX_PADG_BOOST_TUNE,
184 e->radio_tx0_padg_boost_tune);
185 b43_radio_write(dev, B2056_TX0 | B2056_TX_PGAA_BOOST_TUNE,
186 e->radio_tx0_pgaa_boost_tune);
187 b43_radio_write(dev, B2056_TX0 | B2056_TX_PGAG_BOOST_TUNE,
188 e->radio_tx0_pgag_boost_tune);
189 b43_radio_write(dev, B2056_TX0 | B2056_TX_MIXA_BOOST_TUNE,
190 e->radio_tx0_mixa_boost_tune);
191 b43_radio_write(dev, B2056_TX0 | B2056_TX_MIXG_BOOST_TUNE,
192 e->radio_tx0_mixg_boost_tune);
193
194 b43_radio_write(dev, B2056_RX1 | B2056_RX_LNAA_TUNE,
195 e->radio_rx1_lnaa_tune);
196 b43_radio_write(dev, B2056_RX1 | B2056_RX_LNAG_TUNE,
197 e->radio_rx1_lnag_tune);
198
199 b43_radio_write(dev, B2056_TX1 | B2056_TX_INTPAA_BOOST_TUNE,
200 e->radio_tx1_intpaa_boost_tune);
201 b43_radio_write(dev, B2056_TX1 | B2056_TX_INTPAG_BOOST_TUNE,
202 e->radio_tx1_intpag_boost_tune);
203 b43_radio_write(dev, B2056_TX1 | B2056_TX_PADA_BOOST_TUNE,
204 e->radio_tx1_pada_boost_tune);
205 b43_radio_write(dev, B2056_TX1 | B2056_TX_PADG_BOOST_TUNE,
206 e->radio_tx1_padg_boost_tune);
207 b43_radio_write(dev, B2056_TX1 | B2056_TX_PGAA_BOOST_TUNE,
208 e->radio_tx1_pgaa_boost_tune);
209 b43_radio_write(dev, B2056_TX1 | B2056_TX_PGAG_BOOST_TUNE,
210 e->radio_tx1_pgag_boost_tune);
211 b43_radio_write(dev, B2056_TX1 | B2056_TX_MIXA_BOOST_TUNE,
212 e->radio_tx1_mixa_boost_tune);
213 b43_radio_write(dev, B2056_TX1 | B2056_TX_MIXG_BOOST_TUNE,
214 e->radio_tx1_mixg_boost_tune);
215}
216
217/* http://bcm-v4.sipsolutions.net/802.11/PHY/Radio/2056Setup */
218static void b43_radio_2056_setup(struct b43_wldev *dev,
219 const struct b43_nphy_channeltab_entry_rev3 *e)
220{
221 B43_WARN_ON(dev->phy.rev < 3);
222
223 b43_chantab_radio_2056_upload(dev, e);
224 /* TODO */
225 udelay(50);
226 /* VCO calibration */
227 b43_radio_write(dev, B2056_SYN_PLL_VCOCAL12, 0x00);
228 b43_radio_write(dev, B2056_TX_INTPAA_PA_MISC, 0x38);
229 b43_radio_write(dev, B2056_TX_INTPAA_PA_MISC, 0x18);
230 b43_radio_write(dev, B2056_TX_INTPAA_PA_MISC, 0x38);
231 b43_radio_write(dev, B2056_TX_INTPAA_PA_MISC, 0x39);
232 udelay(300);
233}
234
144static void b43_chantab_phy_upload(struct b43_wldev *dev, 235static void b43_chantab_phy_upload(struct b43_wldev *dev,
145 const struct b43_phy_n_sfo_cfg *e) 236 const struct b43_phy_n_sfo_cfg *e)
146{ 237{
@@ -152,9 +243,154 @@ static void b43_chantab_phy_upload(struct b43_wldev *dev,
152 b43_phy_write(dev, B43_NPHY_BW6, e->phy_bw6); 243 b43_phy_write(dev, B43_NPHY_BW6, e->phy_bw6);
153} 244}
154 245
246/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlEnable */
247static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable)
248{
249 struct b43_phy_n *nphy = dev->phy.n;
250 u8 i;
251 u16 tmp;
252
253 if (nphy->hang_avoid)
254 b43_nphy_stay_in_carrier_search(dev, 1);
255
256 nphy->txpwrctrl = enable;
257 if (!enable) {
258 if (dev->phy.rev >= 3)
259 ; /* TODO */
260
261 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x6840);
262 for (i = 0; i < 84; i++)
263 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0);
264
265 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x6C40);
266 for (i = 0; i < 84; i++)
267 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0);
268
269 tmp = B43_NPHY_TXPCTL_CMD_COEFF | B43_NPHY_TXPCTL_CMD_HWPCTLEN;
270 if (dev->phy.rev >= 3)
271 tmp |= B43_NPHY_TXPCTL_CMD_PCTLEN;
272 b43_phy_mask(dev, B43_NPHY_TXPCTL_CMD, ~tmp);
273
274 if (dev->phy.rev >= 3) {
275 b43_phy_set(dev, B43_NPHY_AFECTL_OVER1, 0x0100);
276 b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x0100);
277 } else {
278 b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x4000);
279 }
280
281 if (dev->phy.rev == 2)
282 b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3,
283 ~B43_NPHY_BPHY_CTL3_SCALE, 0x53);
284 else if (dev->phy.rev < 2)
285 b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3,
286 ~B43_NPHY_BPHY_CTL3_SCALE, 0x5A);
287
288 if (dev->phy.rev < 2 && 0)
289 ; /* TODO */
290 } else {
291 b43err(dev->wl, "enabling tx pwr ctrl not implemented yet\n");
292 }
293
294 if (nphy->hang_avoid)
295 b43_nphy_stay_in_carrier_search(dev, 0);
296}
297
298/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrFix */
155static void b43_nphy_tx_power_fix(struct b43_wldev *dev) 299static void b43_nphy_tx_power_fix(struct b43_wldev *dev)
156{ 300{
157 //TODO 301 struct b43_phy_n *nphy = dev->phy.n;
302 struct ssb_sprom *sprom = &(dev->sdev->bus->sprom);
303
304 u8 txpi[2], bbmult, i;
305 u16 tmp, radio_gain, dac_gain;
306 u16 freq = dev->phy.channel_freq;
307 u32 txgain;
308 /* u32 gaintbl; rev3+ */
309
310 if (nphy->hang_avoid)
311 b43_nphy_stay_in_carrier_search(dev, 1);
312
313 if (dev->phy.rev >= 3) {
314 txpi[0] = 40;
315 txpi[1] = 40;
316 } else if (sprom->revision < 4) {
317 txpi[0] = 72;
318 txpi[1] = 72;
319 } else {
320 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
321 txpi[0] = sprom->txpid2g[0];
322 txpi[1] = sprom->txpid2g[1];
323 } else if (freq >= 4900 && freq < 5100) {
324 txpi[0] = sprom->txpid5gl[0];
325 txpi[1] = sprom->txpid5gl[1];
326 } else if (freq >= 5100 && freq < 5500) {
327 txpi[0] = sprom->txpid5g[0];
328 txpi[1] = sprom->txpid5g[1];
329 } else if (freq >= 5500) {
330 txpi[0] = sprom->txpid5gh[0];
331 txpi[1] = sprom->txpid5gh[1];
332 } else {
333 txpi[0] = 91;
334 txpi[1] = 91;
335 }
336 }
337
338 /*
339 for (i = 0; i < 2; i++) {
340 nphy->txpwrindex[i].index_internal = txpi[i];
341 nphy->txpwrindex[i].index_internal_save = txpi[i];
342 }
343 */
344
345 for (i = 0; i < 2; i++) {
346 if (dev->phy.rev >= 3) {
347 /* FIXME: support 5GHz */
348 txgain = b43_ntab_tx_gain_rev3plus_2ghz[txpi[i]];
349 radio_gain = (txgain >> 16) & 0x1FFFF;
350 } else {
351 txgain = b43_ntab_tx_gain_rev0_1_2[txpi[i]];
352 radio_gain = (txgain >> 16) & 0x1FFF;
353 }
354
355 dac_gain = (txgain >> 8) & 0x3F;
356 bbmult = txgain & 0xFF;
357
358 if (dev->phy.rev >= 3) {
359 if (i == 0)
360 b43_phy_set(dev, B43_NPHY_AFECTL_OVER1, 0x0100);
361 else
362 b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x0100);
363 } else {
364 b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x4000);
365 }
366
367 if (i == 0)
368 b43_phy_write(dev, B43_NPHY_AFECTL_DACGAIN1, dac_gain);
369 else
370 b43_phy_write(dev, B43_NPHY_AFECTL_DACGAIN2, dac_gain);
371
372 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D10 + i);
373 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, radio_gain);
374
375 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x3C57);
376 tmp = b43_phy_read(dev, B43_NPHY_TABLE_DATALO);
377
378 if (i == 0)
379 tmp = (tmp & 0x00FF) | (bbmult << 8);
380 else
381 tmp = (tmp & 0xFF00) | bbmult;
382
383 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x3C57);
384 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, tmp);
385
386 if (0)
387 ; /* TODO */
388 }
389
390 b43_phy_mask(dev, B43_NPHY_BPHY_CTL2, ~B43_NPHY_BPHY_CTL2_LUT);
391
392 if (nphy->hang_avoid)
393 b43_nphy_stay_in_carrier_search(dev, 0);
158} 394}
159 395
160 396
@@ -187,18 +423,19 @@ static void b43_radio_init2055_pre(struct b43_wldev *dev)
187static void b43_radio_init2055_post(struct b43_wldev *dev) 423static void b43_radio_init2055_post(struct b43_wldev *dev)
188{ 424{
189 struct b43_phy_n *nphy = dev->phy.n; 425 struct b43_phy_n *nphy = dev->phy.n;
190 struct ssb_sprom *sprom = &(dev->dev->bus->sprom); 426 struct ssb_sprom *sprom = &(dev->sdev->bus->sprom);
191 struct ssb_boardinfo *binfo = &(dev->dev->bus->boardinfo); 427 struct ssb_boardinfo *binfo = &(dev->sdev->bus->boardinfo);
192 int i; 428 int i;
193 u16 val; 429 u16 val;
194 bool workaround = false; 430 bool workaround = false;
195 431
196 if (sprom->revision < 4) 432 if (sprom->revision < 4)
197 workaround = (binfo->vendor != PCI_VENDOR_ID_BROADCOM || 433 workaround = (binfo->vendor != PCI_VENDOR_ID_BROADCOM &&
198 binfo->type != 0x46D || 434 binfo->type == 0x46D &&
199 binfo->rev < 0x41); 435 binfo->rev >= 0x41);
200 else 436 else
201 workaround = ((sprom->boardflags_hi & B43_BFH_NOPA) == 0); 437 workaround =
438 !(sprom->boardflags2_lo & B43_BFL2_RXBB_INT_REG_DIS);
202 439
203 b43_radio_mask(dev, B2055_MASTER1, 0xFFF3); 440 b43_radio_mask(dev, B2055_MASTER1, 0xFFF3);
204 if (workaround) { 441 if (workaround) {
@@ -223,7 +460,7 @@ static void b43_radio_init2055_post(struct b43_wldev *dev)
223 if (i) 460 if (i)
224 b43err(dev->wl, "radio post init timeout\n"); 461 b43err(dev->wl, "radio post init timeout\n");
225 b43_radio_mask(dev, B2055_CAL_LPOCTL, 0xFF7F); 462 b43_radio_mask(dev, B2055_CAL_LPOCTL, 0xFF7F);
226 nphy_channel_switch(dev, dev->phy.channel); 463 b43_switch_channel(dev, dev->phy.channel);
227 b43_radio_write(dev, B2055_C1_RX_BB_LPF, 0x9); 464 b43_radio_write(dev, B2055_C1_RX_BB_LPF, 0x9);
228 b43_radio_write(dev, B2055_C2_RX_BB_LPF, 0x9); 465 b43_radio_write(dev, B2055_C2_RX_BB_LPF, 0x9);
229 b43_radio_write(dev, B2055_C1_RX_BB_MIDACHP, 0x83); 466 b43_radio_write(dev, B2055_C1_RX_BB_MIDACHP, 0x83);
@@ -247,23 +484,55 @@ static void b43_radio_init2055_post(struct b43_wldev *dev)
247static void b43_radio_init2055(struct b43_wldev *dev) 484static void b43_radio_init2055(struct b43_wldev *dev)
248{ 485{
249 b43_radio_init2055_pre(dev); 486 b43_radio_init2055_pre(dev);
250 if (b43_status(dev) < B43_STAT_INITIALIZED) 487 if (b43_status(dev) < B43_STAT_INITIALIZED) {
251 b2055_upload_inittab(dev, 0, 1); 488 /* Follow wl, not specs. Do not force uploading all regs */
252 else 489 b2055_upload_inittab(dev, 0, 0);
253 b2055_upload_inittab(dev, 0/*FIXME on 5ghz band*/, 0); 490 } else {
491 bool ghz5 = b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ;
492 b2055_upload_inittab(dev, ghz5, 0);
493 }
254 b43_radio_init2055_post(dev); 494 b43_radio_init2055_post(dev);
255} 495}
256 496
497static void b43_radio_init2056_pre(struct b43_wldev *dev)
498{
499 b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
500 ~B43_NPHY_RFCTL_CMD_CHIP0PU);
501 /* Maybe wl meant to reset and set (order?) RFCTL_CMD_OEPORFORCE? */
502 b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
503 B43_NPHY_RFCTL_CMD_OEPORFORCE);
504 b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
505 ~B43_NPHY_RFCTL_CMD_OEPORFORCE);
506 b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
507 B43_NPHY_RFCTL_CMD_CHIP0PU);
508}
509
510static void b43_radio_init2056_post(struct b43_wldev *dev)
511{
512 b43_radio_set(dev, B2056_SYN_COM_CTRL, 0xB);
513 b43_radio_set(dev, B2056_SYN_COM_PU, 0x2);
514 b43_radio_set(dev, B2056_SYN_COM_RESET, 0x2);
515 msleep(1);
516 b43_radio_mask(dev, B2056_SYN_COM_RESET, ~0x2);
517 b43_radio_mask(dev, B2056_SYN_PLL_MAST2, ~0xFC);
518 b43_radio_mask(dev, B2056_SYN_RCCAL_CTRL0, ~0x1);
519 /*
520 if (nphy->init_por)
521 Call Radio 2056 Recalibrate
522 */
523}
524
257/* 525/*
258 * Initialize a Broadcom 2056 N-radio 526 * Initialize a Broadcom 2056 N-radio
259 * http://bcm-v4.sipsolutions.net/802.11/Radio/2056/Init 527 * http://bcm-v4.sipsolutions.net/802.11/Radio/2056/Init
260 */ 528 */
261static void b43_radio_init2056(struct b43_wldev *dev) 529static void b43_radio_init2056(struct b43_wldev *dev)
262{ 530{
263 /* TODO */ 531 b43_radio_init2056_pre(dev);
532 b2056_upload_inittabs(dev, 0, 0);
533 b43_radio_init2056_post(dev);
264} 534}
265 535
266
267/* 536/*
268 * Upload the N-PHY tables. 537 * Upload the N-PHY tables.
269 * http://bcm-v4.sipsolutions.net/802.11/PHY/N/InitTables 538 * http://bcm-v4.sipsolutions.net/802.11/PHY/N/InitTables
@@ -340,12 +609,12 @@ static void b43_nphy_bmac_clock_fgc(struct b43_wldev *dev, bool force)
340 if (dev->phy.type != B43_PHYTYPE_N) 609 if (dev->phy.type != B43_PHYTYPE_N)
341 return; 610 return;
342 611
343 tmslow = ssb_read32(dev->dev, SSB_TMSLOW); 612 tmslow = ssb_read32(dev->sdev, SSB_TMSLOW);
344 if (force) 613 if (force)
345 tmslow |= SSB_TMSLOW_FGC; 614 tmslow |= SSB_TMSLOW_FGC;
346 else 615 else
347 tmslow &= ~SSB_TMSLOW_FGC; 616 tmslow &= ~SSB_TMSLOW_FGC;
348 ssb_write32(dev->dev, SSB_TMSLOW, tmslow); 617 ssb_write32(dev->sdev, SSB_TMSLOW, tmslow);
349} 618}
350 619
351/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CCA */ 620/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CCA */
@@ -460,6 +729,8 @@ static void b43_nphy_rx_iq_coeffs(struct b43_wldev *dev, bool write,
460 } 729 }
461} 730}
462 731
732#if 0
733/* Ready but not used anywhere */
463/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCalPhyCleanup */ 734/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCalPhyCleanup */
464static void b43_nphy_rx_cal_phy_cleanup(struct b43_wldev *dev, u8 core) 735static void b43_nphy_rx_cal_phy_cleanup(struct b43_wldev *dev, u8 core)
465{ 736{
@@ -541,6 +812,7 @@ static void b43_nphy_rx_cal_phy_setup(struct b43_wldev *dev, u8 core)
541 b43_nphy_rf_control_intc_override(dev, 1, rxval, (core + 1)); 812 b43_nphy_rf_control_intc_override(dev, 1, rxval, (core + 1));
542 b43_nphy_rf_control_intc_override(dev, 1, txval, (2 - core)); 813 b43_nphy_rf_control_intc_override(dev, 1, txval, (2 - core));
543} 814}
815#endif
544 816
545/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalcRxIqComp */ 817/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalcRxIqComp */
546static void b43_nphy_calc_rx_iq_comp(struct b43_wldev *dev, u8 mask) 818static void b43_nphy_calc_rx_iq_comp(struct b43_wldev *dev, u8 mask)
@@ -576,7 +848,6 @@ static void b43_nphy_calc_rx_iq_comp(struct b43_wldev *dev, u8 mask)
576 ii = est.i1_pwr; 848 ii = est.i1_pwr;
577 qq = est.q1_pwr; 849 qq = est.q1_pwr;
578 } else { 850 } else {
579 B43_WARN_ON(1);
580 continue; 851 continue;
581 } 852 }
582 853
@@ -658,7 +929,8 @@ static void b43_nphy_tx_iq_workaround(struct b43_wldev *dev)
658} 929}
659 930
660/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/clip-detection */ 931/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/clip-detection */
661static void b43_nphy_write_clip_detection(struct b43_wldev *dev, u16 *clip_st) 932static void b43_nphy_write_clip_detection(struct b43_wldev *dev,
933 const u16 *clip_st)
662{ 934{
663 b43_phy_write(dev, B43_NPHY_C1_CLIP1THRES, clip_st[0]); 935 b43_phy_write(dev, B43_NPHY_C1_CLIP1THRES, clip_st[0]);
664 b43_phy_write(dev, B43_NPHY_C2_CLIP1THRES, clip_st[1]); 936 b43_phy_write(dev, B43_NPHY_C2_CLIP1THRES, clip_st[1]);
@@ -687,7 +959,7 @@ static void b43_nphy_superswitch_init(struct b43_wldev *dev, bool init)
687 b43_phy_write(dev, B43_NPHY_GPIO_LOOEN, 0); 959 b43_phy_write(dev, B43_NPHY_GPIO_LOOEN, 0);
688 b43_phy_write(dev, B43_NPHY_GPIO_HIOEN, 0); 960 b43_phy_write(dev, B43_NPHY_GPIO_HIOEN, 0);
689 961
690 ssb_chipco_gpio_control(&dev->dev->bus->chipco, 0xFC00, 962 ssb_chipco_gpio_control(&dev->sdev->bus->chipco, 0xFC00,
691 0xFC00); 963 0xFC00);
692 b43_write32(dev, B43_MMIO_MACCTL, 964 b43_write32(dev, B43_MMIO_MACCTL,
693 b43_read32(dev, B43_MMIO_MACCTL) & 965 b43_read32(dev, B43_MMIO_MACCTL) &
@@ -711,7 +983,7 @@ static u16 b43_nphy_classifier(struct b43_wldev *dev, u16 mask, u16 val)
711{ 983{
712 u16 tmp; 984 u16 tmp;
713 985
714 if (dev->dev->id.revision == 16) 986 if (dev->sdev->id.revision == 16)
715 b43_mac_suspend(dev); 987 b43_mac_suspend(dev);
716 988
717 tmp = b43_phy_read(dev, B43_NPHY_CLASSCTL); 989 tmp = b43_phy_read(dev, B43_NPHY_CLASSCTL);
@@ -721,7 +993,7 @@ static u16 b43_nphy_classifier(struct b43_wldev *dev, u16 mask, u16 val)
721 tmp |= (val & mask); 993 tmp |= (val & mask);
722 b43_phy_maskset(dev, B43_NPHY_CLASSCTL, 0xFFF8, tmp); 994 b43_phy_maskset(dev, B43_NPHY_CLASSCTL, 0xFFF8, tmp);
723 995
724 if (dev->dev->id.revision == 16) 996 if (dev->sdev->id.revision == 16)
725 b43_mac_enable(dev); 997 b43_mac_enable(dev);
726 998
727 return tmp; 999 return tmp;
@@ -734,7 +1006,7 @@ static void b43_nphy_stay_in_carrier_search(struct b43_wldev *dev, bool enable)
734 struct b43_phy_n *nphy = phy->n; 1006 struct b43_phy_n *nphy = phy->n;
735 1007
736 if (enable) { 1008 if (enable) {
737 u16 clip[] = { 0xFFFF, 0xFFFF }; 1009 static const u16 clip[] = { 0xFFFF, 0xFFFF };
738 if (nphy->deaf_count++ == 0) { 1010 if (nphy->deaf_count++ == 0) {
739 nphy->classifier_state = b43_nphy_classifier(dev, 0, 0); 1011 nphy->classifier_state = b43_nphy_classifier(dev, 0, 0);
740 b43_nphy_classifier(dev, 0x7, 0); 1012 b43_nphy_classifier(dev, 0x7, 0);
@@ -782,7 +1054,7 @@ static void b43_nphy_spur_workaround(struct b43_wldev *dev)
782{ 1054{
783 struct b43_phy_n *nphy = dev->phy.n; 1055 struct b43_phy_n *nphy = dev->phy.n;
784 1056
785 u8 channel = nphy->radio_chanspec.channel; 1057 u8 channel = dev->phy.channel;
786 int tone[2] = { 57, 58 }; 1058 int tone[2] = { 57, 58 };
787 u32 noise[2] = { 0x3FF, 0x3FF }; 1059 u32 noise[2] = { 0x3FF, 0x3FF };
788 1060
@@ -846,7 +1118,7 @@ static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev)
846 u16 data[4]; 1118 u16 data[4];
847 s16 gain[2]; 1119 s16 gain[2];
848 u16 minmax[2]; 1120 u16 minmax[2];
849 u16 lna_gain[4] = { -2, 10, 19, 25 }; 1121 static const u16 lna_gain[4] = { -2, 10, 19, 25 };
850 1122
851 if (nphy->hang_avoid) 1123 if (nphy->hang_avoid)
852 b43_nphy_stay_in_carrier_search(dev, 1); 1124 b43_nphy_stay_in_carrier_search(dev, 1);
@@ -856,9 +1128,9 @@ static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev)
856 gain[0] = 6; 1128 gain[0] = 6;
857 gain[1] = 6; 1129 gain[1] = 6;
858 } else { 1130 } else {
859 tmp = 40370 - 315 * nphy->radio_chanspec.channel; 1131 tmp = 40370 - 315 * dev->phy.channel;
860 gain[0] = ((tmp >> 13) + ((tmp >> 12) & 1)); 1132 gain[0] = ((tmp >> 13) + ((tmp >> 12) & 1));
861 tmp = 23242 - 224 * nphy->radio_chanspec.channel; 1133 tmp = 23242 - 224 * dev->phy.channel;
862 gain[1] = ((tmp >> 13) + ((tmp >> 12) & 1)); 1134 gain[1] = ((tmp >> 13) + ((tmp >> 12) & 1));
863 } 1135 }
864 } else { 1136 } else {
@@ -878,7 +1150,7 @@ static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev)
878 data[2] = lna_gain[2] + gain[i]; 1150 data[2] = lna_gain[2] + gain[i];
879 data[3] = lna_gain[3] + gain[i]; 1151 data[3] = lna_gain[3] + gain[i];
880 } 1152 }
881 b43_ntab_write_bulk(dev, B43_NTAB16(10, 8), 4, data); 1153 b43_ntab_write_bulk(dev, B43_NTAB16(i, 8), 4, data);
882 1154
883 minmax[i] = 23 + gain[i]; 1155 minmax[i] = 23 + gain[i];
884 } 1156 }
@@ -893,25 +1165,101 @@ static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev)
893} 1165}
894 1166
895/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */ 1167/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */
896static void b43_nphy_gain_crtl_workarounds(struct b43_wldev *dev) 1168static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev)
897{ 1169{
898 struct b43_phy_n *nphy = dev->phy.n; 1170 struct b43_phy_n *nphy = dev->phy.n;
1171 struct ssb_sprom *sprom = &(dev->sdev->bus->sprom);
1172
1173 /* PHY rev 0, 1, 2 */
899 u8 i, j; 1174 u8 i, j;
900 u8 code; 1175 u8 code;
1176 u16 tmp;
1177 u8 rfseq_events[3] = { 6, 8, 7 };
1178 u8 rfseq_delays[3] = { 10, 30, 1 };
901 1179
902 /* TODO: for PHY >= 3 1180 /* PHY rev >= 3 */
903 s8 *lna1_gain, *lna2_gain; 1181 bool ghz5;
904 u8 *gain_db, *gain_bits; 1182 bool ext_lna;
905 u16 *rfseq_init; 1183 u16 rssi_gain;
1184 struct nphy_gain_ctl_workaround_entry *e;
906 u8 lpf_gain[6] = { 0x00, 0x06, 0x0C, 0x12, 0x12, 0x12 }; 1185 u8 lpf_gain[6] = { 0x00, 0x06, 0x0C, 0x12, 0x12, 0x12 };
907 u8 lpf_bits[6] = { 0, 1, 2, 3, 3, 3 }; 1186 u8 lpf_bits[6] = { 0, 1, 2, 3, 3, 3 };
908 */
909
910 u8 rfseq_events[3] = { 6, 8, 7 };
911 u8 rfseq_delays[3] = { 10, 30, 1 };
912 1187
913 if (dev->phy.rev >= 3) { 1188 if (dev->phy.rev >= 3) {
914 /* TODO */ 1189 /* Prepare values */
1190 ghz5 = b43_phy_read(dev, B43_NPHY_BANDCTL)
1191 & B43_NPHY_BANDCTL_5GHZ;
1192 ext_lna = sprom->boardflags_lo & B43_BFL_EXTLNA;
1193 e = b43_nphy_get_gain_ctl_workaround_ent(dev, ghz5, ext_lna);
1194 if (ghz5 && dev->phy.rev >= 5)
1195 rssi_gain = 0x90;
1196 else
1197 rssi_gain = 0x50;
1198
1199 b43_phy_set(dev, B43_NPHY_RXCTL, 0x0040);
1200
1201 /* Set Clip 2 detect */
1202 b43_phy_set(dev, B43_NPHY_C1_CGAINI,
1203 B43_NPHY_C1_CGAINI_CL2DETECT);
1204 b43_phy_set(dev, B43_NPHY_C2_CGAINI,
1205 B43_NPHY_C2_CGAINI_CL2DETECT);
1206
1207 b43_radio_write(dev, B2056_RX0 | B2056_RX_BIASPOLE_LNAG1_IDAC,
1208 0x17);
1209 b43_radio_write(dev, B2056_RX1 | B2056_RX_BIASPOLE_LNAG1_IDAC,
1210 0x17);
1211 b43_radio_write(dev, B2056_RX0 | B2056_RX_LNAG2_IDAC, 0xF0);
1212 b43_radio_write(dev, B2056_RX1 | B2056_RX_LNAG2_IDAC, 0xF0);
1213 b43_radio_write(dev, B2056_RX0 | B2056_RX_RSSI_POLE, 0x00);
1214 b43_radio_write(dev, B2056_RX1 | B2056_RX_RSSI_POLE, 0x00);
1215 b43_radio_write(dev, B2056_RX0 | B2056_RX_RSSI_GAIN,
1216 rssi_gain);
1217 b43_radio_write(dev, B2056_RX1 | B2056_RX_RSSI_GAIN,
1218 rssi_gain);
1219 b43_radio_write(dev, B2056_RX0 | B2056_RX_BIASPOLE_LNAA1_IDAC,
1220 0x17);
1221 b43_radio_write(dev, B2056_RX1 | B2056_RX_BIASPOLE_LNAA1_IDAC,
1222 0x17);
1223 b43_radio_write(dev, B2056_RX0 | B2056_RX_LNAA2_IDAC, 0xFF);
1224 b43_radio_write(dev, B2056_RX1 | B2056_RX_LNAA2_IDAC, 0xFF);
1225
1226 b43_ntab_write_bulk(dev, B43_NTAB8(0, 8), 4, e->lna1_gain);
1227 b43_ntab_write_bulk(dev, B43_NTAB8(1, 8), 4, e->lna1_gain);
1228 b43_ntab_write_bulk(dev, B43_NTAB8(0, 16), 4, e->lna2_gain);
1229 b43_ntab_write_bulk(dev, B43_NTAB8(1, 16), 4, e->lna2_gain);
1230 b43_ntab_write_bulk(dev, B43_NTAB8(0, 32), 10, e->gain_db);
1231 b43_ntab_write_bulk(dev, B43_NTAB8(1, 32), 10, e->gain_db);
1232 b43_ntab_write_bulk(dev, B43_NTAB8(2, 32), 10, e->gain_bits);
1233 b43_ntab_write_bulk(dev, B43_NTAB8(3, 32), 10, e->gain_bits);
1234 b43_ntab_write_bulk(dev, B43_NTAB8(0, 0x40), 6, lpf_gain);
1235 b43_ntab_write_bulk(dev, B43_NTAB8(1, 0x40), 6, lpf_gain);
1236 b43_ntab_write_bulk(dev, B43_NTAB8(2, 0x40), 6, lpf_bits);
1237 b43_ntab_write_bulk(dev, B43_NTAB8(3, 0x40), 6, lpf_bits);
1238
1239 b43_phy_write(dev, B43_NPHY_C1_INITGAIN, e->init_gain);
1240 b43_phy_write(dev, 0x2A7, e->init_gain);
1241 b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x106), 2,
1242 e->rfseq_init);
1243 b43_phy_write(dev, B43_NPHY_C1_INITGAIN, e->init_gain);
1244
1245 /* TODO: check defines. Do not match variables names */
1246 b43_phy_write(dev, B43_NPHY_C1_CLIP1_MEDGAIN, e->cliphi_gain);
1247 b43_phy_write(dev, 0x2A9, e->cliphi_gain);
1248 b43_phy_write(dev, B43_NPHY_C1_CLIP2_GAIN, e->clipmd_gain);
1249 b43_phy_write(dev, 0x2AB, e->clipmd_gain);
1250 b43_phy_write(dev, B43_NPHY_C2_CLIP1_HIGAIN, e->cliplo_gain);
1251 b43_phy_write(dev, 0x2AD, e->cliplo_gain);
1252
1253 b43_phy_maskset(dev, 0x27D, 0xFF00, e->crsmin);
1254 b43_phy_maskset(dev, 0x280, 0xFF00, e->crsminl);
1255 b43_phy_maskset(dev, 0x283, 0xFF00, e->crsminu);
1256 b43_phy_write(dev, B43_NPHY_C1_NBCLIPTHRES, e->nbclip);
1257 b43_phy_write(dev, B43_NPHY_C2_NBCLIPTHRES, e->nbclip);
1258 b43_phy_maskset(dev, B43_NPHY_C1_CLIPWBTHRES,
1259 ~B43_NPHY_C1_CLIPWBTHRES_CLIP2, e->wlclip);
1260 b43_phy_maskset(dev, B43_NPHY_C2_CLIPWBTHRES,
1261 ~B43_NPHY_C2_CLIPWBTHRES_CLIP2, e->wlclip);
1262 b43_phy_write(dev, B43_NPHY_CCK_SHIFTB_REF, 0x809C);
915 } else { 1263 } else {
916 /* Set Clip 2 detect */ 1264 /* Set Clip 2 detect */
917 b43_phy_set(dev, B43_NPHY_C1_CGAINI, 1265 b43_phy_set(dev, B43_NPHY_C1_CGAINI,
@@ -920,15 +1268,15 @@ static void b43_nphy_gain_crtl_workarounds(struct b43_wldev *dev)
920 B43_NPHY_C2_CGAINI_CL2DETECT); 1268 B43_NPHY_C2_CGAINI_CL2DETECT);
921 1269
922 /* Set narrowband clip threshold */ 1270 /* Set narrowband clip threshold */
923 b43_phy_set(dev, B43_NPHY_C1_NBCLIPTHRES, 0x84); 1271 b43_phy_write(dev, B43_NPHY_C1_NBCLIPTHRES, 0x84);
924 b43_phy_set(dev, B43_NPHY_C2_NBCLIPTHRES, 0x84); 1272 b43_phy_write(dev, B43_NPHY_C2_NBCLIPTHRES, 0x84);
925 1273
926 if (!dev->phy.is_40mhz) { 1274 if (!dev->phy.is_40mhz) {
927 /* Set dwell lengths */ 1275 /* Set dwell lengths */
928 b43_phy_set(dev, B43_NPHY_CLIP1_NBDWELL_LEN, 0x002B); 1276 b43_phy_write(dev, B43_NPHY_CLIP1_NBDWELL_LEN, 0x002B);
929 b43_phy_set(dev, B43_NPHY_CLIP2_NBDWELL_LEN, 0x002B); 1277 b43_phy_write(dev, B43_NPHY_CLIP2_NBDWELL_LEN, 0x002B);
930 b43_phy_set(dev, B43_NPHY_W1CLIP1_DWELL_LEN, 0x0009); 1278 b43_phy_write(dev, B43_NPHY_W1CLIP1_DWELL_LEN, 0x0009);
931 b43_phy_set(dev, B43_NPHY_W1CLIP2_DWELL_LEN, 0x0009); 1279 b43_phy_write(dev, B43_NPHY_W1CLIP2_DWELL_LEN, 0x0009);
932 } 1280 }
933 1281
934 /* Set wideband clip 2 threshold */ 1282 /* Set wideband clip 2 threshold */
@@ -950,7 +1298,7 @@ static void b43_nphy_gain_crtl_workarounds(struct b43_wldev *dev)
950 ~B43_NPHY_C2_CCK_CGAINI_GAINBKOFF, 0x1); 1298 ~B43_NPHY_C2_CCK_CGAINI_GAINBKOFF, 0x1);
951 } 1299 }
952 1300
953 b43_phy_set(dev, B43_NPHY_CCK_SHIFTB_REF, 0x809C); 1301 b43_phy_write(dev, B43_NPHY_CCK_SHIFTB_REF, 0x809C);
954 1302
955 if (nphy->gain_boost) { 1303 if (nphy->gain_boost) {
956 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ && 1304 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ &&
@@ -971,10 +1319,10 @@ static void b43_nphy_gain_crtl_workarounds(struct b43_wldev *dev)
971 code << B43_NPHY_C2_INITGAIN_HPVGA2_SHIFT); 1319 code << B43_NPHY_C2_INITGAIN_HPVGA2_SHIFT);
972 1320
973 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D06); 1321 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D06);
974 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 1322 /* specs say about 2 loops, but wl does 4 */
975 (code << 8 | 0x7C)); 1323 for (i = 0; i < 4; i++)
976 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 1324 b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
977 (code << 8 | 0x7C)); 1325 (code << 8 | 0x7C));
978 1326
979 b43_nphy_adjust_lna_gain_table(dev); 1327 b43_nphy_adjust_lna_gain_table(dev);
980 1328
@@ -992,38 +1340,40 @@ static void b43_nphy_gain_crtl_workarounds(struct b43_wldev *dev)
992 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1); 1340 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1);
993 1341
994 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D06); 1342 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D06);
995 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 1343 /* specs say about 2 loops, but wl does 4 */
996 (code << 8 | 0x74)); 1344 for (i = 0; i < 4; i++)
997 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 1345 b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
998 (code << 8 | 0x74)); 1346 (code << 8 | 0x74));
999 } 1347 }
1000 1348
1001 if (dev->phy.rev == 2) { 1349 if (dev->phy.rev == 2) {
1002 for (i = 0; i < 4; i++) { 1350 for (i = 0; i < 4; i++) {
1003 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 1351 b43_phy_write(dev, B43_NPHY_TABLE_ADDR,
1004 (0x0400 * i) + 0x0020); 1352 (0x0400 * i) + 0x0020);
1005 for (j = 0; j < 21; j++) 1353 for (j = 0; j < 21; j++) {
1354 tmp = j * (i < 2 ? 3 : 1);
1006 b43_phy_write(dev, 1355 b43_phy_write(dev,
1007 B43_NPHY_TABLE_DATALO, 3 * j); 1356 B43_NPHY_TABLE_DATALO, tmp);
1357 }
1008 } 1358 }
1359 }
1009 1360
1010 b43_nphy_set_rf_sequence(dev, 5, 1361 b43_nphy_set_rf_sequence(dev, 5,
1011 rfseq_events, rfseq_delays, 3); 1362 rfseq_events, rfseq_delays, 3);
1012 b43_phy_maskset(dev, B43_NPHY_OVER_DGAIN1, 1363 b43_phy_maskset(dev, B43_NPHY_OVER_DGAIN1,
1013 ~B43_NPHY_OVER_DGAIN_CCKDGECV & 0xFFFF, 1364 ~B43_NPHY_OVER_DGAIN_CCKDGECV & 0xFFFF,
1014 0x5A << B43_NPHY_OVER_DGAIN_CCKDGECV_SHIFT); 1365 0x5A << B43_NPHY_OVER_DGAIN_CCKDGECV_SHIFT);
1015 1366
1016 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) 1367 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
1017 b43_phy_maskset(dev, B43_PHY_N(0xC5D), 1368 b43_phy_maskset(dev, B43_PHY_N(0xC5D),
1018 0xFF80, 4); 1369 0xFF80, 4);
1019 }
1020 } 1370 }
1021} 1371}
1022 1372
1023/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Workarounds */ 1373/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Workarounds */
1024static void b43_nphy_workarounds(struct b43_wldev *dev) 1374static void b43_nphy_workarounds(struct b43_wldev *dev)
1025{ 1375{
1026 struct ssb_bus *bus = dev->dev->bus; 1376 struct ssb_bus *bus = dev->sdev->bus;
1027 struct b43_phy *phy = &dev->phy; 1377 struct b43_phy *phy = &dev->phy;
1028 struct b43_phy_n *nphy = phy->n; 1378 struct b43_phy_n *nphy = phy->n;
1029 1379
@@ -1033,7 +1383,10 @@ static void b43_nphy_workarounds(struct b43_wldev *dev)
1033 u8 events2[7] = { 0x0, 0x3, 0x5, 0x4, 0x2, 0x1, 0x8 }; 1383 u8 events2[7] = { 0x0, 0x3, 0x5, 0x4, 0x2, 0x1, 0x8 };
1034 u8 delays2[7] = { 0x8, 0x6, 0x2, 0x4, 0x4, 0x6, 0x1 }; 1384 u8 delays2[7] = { 0x8, 0x6, 0x2, 0x4, 0x4, 0x6, 0x1 };
1035 1385
1036 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) 1386 u16 tmp16;
1387 u32 tmp32;
1388
1389 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
1037 b43_nphy_classifier(dev, 1, 0); 1390 b43_nphy_classifier(dev, 1, 0);
1038 else 1391 else
1039 b43_nphy_classifier(dev, 1, 1); 1392 b43_nphy_classifier(dev, 1, 1);
@@ -1045,7 +1398,82 @@ static void b43_nphy_workarounds(struct b43_wldev *dev)
1045 B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2); 1398 B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2);
1046 1399
1047 if (dev->phy.rev >= 3) { 1400 if (dev->phy.rev >= 3) {
1401 tmp32 = b43_ntab_read(dev, B43_NTAB32(30, 0));
1402 tmp32 &= 0xffffff;
1403 b43_ntab_write(dev, B43_NTAB32(30, 0), tmp32);
1404
1405 b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x0125);
1406 b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x01B3);
1407 b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x0105);
1408 b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x016E);
1409 b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0x00CD);
1410 b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x0020);
1411
1412 b43_phy_write(dev, B43_NPHY_C2_CLIP1_MEDGAIN, 0x000C);
1413 b43_phy_write(dev, 0x2AE, 0x000C);
1414
1048 /* TODO */ 1415 /* TODO */
1416
1417 tmp16 = (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) ?
1418 0x2 : 0x9C40;
1419 b43_phy_write(dev, B43_NPHY_ENDROP_TLEN, tmp16);
1420
1421 b43_phy_maskset(dev, 0x294, 0xF0FF, 0x0700);
1422
1423 b43_ntab_write(dev, B43_NTAB32(16, 3), 0x18D);
1424 b43_ntab_write(dev, B43_NTAB32(16, 127), 0x18D);
1425
1426 b43_nphy_gain_ctrl_workarounds(dev);
1427
1428 b43_ntab_write(dev, B43_NTAB32(8, 0), 2);
1429 b43_ntab_write(dev, B43_NTAB32(8, 16), 2);
1430
1431 /* TODO */
1432
1433 b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_MAST_BIAS, 0x00);
1434 b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_MAST_BIAS, 0x00);
1435 b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_BIAS_MAIN, 0x06);
1436 b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_BIAS_MAIN, 0x06);
1437 b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_BIAS_AUX, 0x07);
1438 b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_BIAS_AUX, 0x07);
1439 b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_LOB_BIAS, 0x88);
1440 b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_LOB_BIAS, 0x88);
1441 b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXG_CMFB_IDAC, 0x00);
1442 b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXG_CMFB_IDAC, 0x00);
1443
1444 /* N PHY WAR TX Chain Update with hw_phytxchain as argument */
1445
1446 if ((bus->sprom.boardflags2_lo & B43_BFL2_APLL_WAR &&
1447 b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ||
1448 (bus->sprom.boardflags2_lo & B43_BFL2_GPLL_WAR &&
1449 b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ))
1450 tmp32 = 0x00088888;
1451 else
1452 tmp32 = 0x88888888;
1453 b43_ntab_write(dev, B43_NTAB32(30, 1), tmp32);
1454 b43_ntab_write(dev, B43_NTAB32(30, 2), tmp32);
1455 b43_ntab_write(dev, B43_NTAB32(30, 3), tmp32);
1456
1457 if (dev->phy.rev == 4 &&
1458 b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
1459 b43_radio_write(dev, B2056_TX0 | B2056_TX_GMBB_IDAC,
1460 0x70);
1461 b43_radio_write(dev, B2056_TX1 | B2056_TX_GMBB_IDAC,
1462 0x70);
1463 }
1464
1465 b43_phy_write(dev, 0x224, 0x039C);
1466 b43_phy_write(dev, 0x225, 0x0357);
1467 b43_phy_write(dev, 0x226, 0x0317);
1468 b43_phy_write(dev, 0x227, 0x02D7);
1469 b43_phy_write(dev, 0x228, 0x039C);
1470 b43_phy_write(dev, 0x229, 0x0357);
1471 b43_phy_write(dev, 0x22A, 0x0317);
1472 b43_phy_write(dev, 0x22B, 0x02D7);
1473 b43_phy_write(dev, 0x22C, 0x039C);
1474 b43_phy_write(dev, 0x22D, 0x0357);
1475 b43_phy_write(dev, 0x22E, 0x0317);
1476 b43_phy_write(dev, 0x22F, 0x02D7);
1049 } else { 1477 } else {
1050 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ && 1478 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ &&
1051 nphy->band5g_pwrgain) { 1479 nphy->band5g_pwrgain) {
@@ -1056,29 +1484,18 @@ static void b43_nphy_workarounds(struct b43_wldev *dev)
1056 b43_radio_set(dev, B2055_C2_TX_RF_SPARE, 0x8); 1484 b43_radio_set(dev, B2055_C2_TX_RF_SPARE, 0x8);
1057 } 1485 }
1058 1486
1059 /* TODO: convert to b43_ntab_write? */ 1487 b43_ntab_write(dev, B43_NTAB16(8, 0x00), 0x000A);
1060 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2000); 1488 b43_ntab_write(dev, B43_NTAB16(8, 0x10), 0x000A);
1061 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x000A); 1489 b43_ntab_write(dev, B43_NTAB16(8, 0x02), 0xCDAA);
1062 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2010); 1490 b43_ntab_write(dev, B43_NTAB16(8, 0x12), 0xCDAA);
1063 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x000A);
1064 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2002);
1065 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0xCDAA);
1066 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2012);
1067 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0xCDAA);
1068 1491
1069 if (dev->phy.rev < 2) { 1492 if (dev->phy.rev < 2) {
1070 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2008); 1493 b43_ntab_write(dev, B43_NTAB16(8, 0x08), 0x0000);
1071 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0000); 1494 b43_ntab_write(dev, B43_NTAB16(8, 0x18), 0x0000);
1072 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2018); 1495 b43_ntab_write(dev, B43_NTAB16(8, 0x07), 0x7AAB);
1073 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0000); 1496 b43_ntab_write(dev, B43_NTAB16(8, 0x17), 0x7AAB);
1074 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2007); 1497 b43_ntab_write(dev, B43_NTAB16(8, 0x06), 0x0800);
1075 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x7AAB); 1498 b43_ntab_write(dev, B43_NTAB16(8, 0x16), 0x0800);
1076 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2017);
1077 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x7AAB);
1078 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2006);
1079 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0800);
1080 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2016);
1081 b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0800);
1082 } 1499 }
1083 1500
1084 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8); 1501 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8);
@@ -1094,11 +1511,12 @@ static void b43_nphy_workarounds(struct b43_wldev *dev)
1094 b43_nphy_set_rf_sequence(dev, 0, events1, delays1, 7); 1511 b43_nphy_set_rf_sequence(dev, 0, events1, delays1, 7);
1095 b43_nphy_set_rf_sequence(dev, 1, events2, delays2, 7); 1512 b43_nphy_set_rf_sequence(dev, 1, events2, delays2, 7);
1096 1513
1097 b43_nphy_gain_crtl_workarounds(dev); 1514 b43_nphy_gain_ctrl_workarounds(dev);
1098 1515
1099 if (dev->phy.rev < 2) { 1516 if (dev->phy.rev < 2) {
1100 if (b43_phy_read(dev, B43_NPHY_RXCTL) & 0x2) 1517 if (b43_phy_read(dev, B43_NPHY_RXCTL) & 0x2)
1101 ; /*TODO: b43_mhf(dev, 2, 0x0010, 0x0010, 3);*/ 1518 b43_hf_write(dev, b43_hf_read(dev) |
1519 B43_HF_MLADVW);
1102 } else if (dev->phy.rev == 2) { 1520 } else if (dev->phy.rev == 2) {
1103 b43_phy_write(dev, B43_NPHY_CRSCHECK2, 0); 1521 b43_phy_write(dev, B43_NPHY_CRSCHECK2, 0);
1104 b43_phy_write(dev, B43_NPHY_CRSCHECK3, 0); 1522 b43_phy_write(dev, B43_NPHY_CRSCHECK3, 0);
@@ -1182,7 +1600,7 @@ static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max,
1182 len = bw << 1; 1600 len = bw << 1;
1183 } 1601 }
1184 1602
1185 samples = kzalloc(len * sizeof(struct b43_c32), GFP_KERNEL); 1603 samples = kcalloc(len, sizeof(struct b43_c32), GFP_KERNEL);
1186 if (!samples) { 1604 if (!samples) {
1187 b43err(dev->wl, "allocation for samples generation failed\n"); 1605 b43err(dev->wl, "allocation for samples generation failed\n");
1188 return 0; 1606 return 0;
@@ -1571,19 +1989,20 @@ static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field,
1571 } 1989 }
1572} 1990}
1573 1991
1992/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/BPHYInit */
1574static void b43_nphy_bphy_init(struct b43_wldev *dev) 1993static void b43_nphy_bphy_init(struct b43_wldev *dev)
1575{ 1994{
1576 unsigned int i; 1995 unsigned int i;
1577 u16 val; 1996 u16 val;
1578 1997
1579 val = 0x1E1F; 1998 val = 0x1E1F;
1580 for (i = 0; i < 14; i++) { 1999 for (i = 0; i < 16; i++) {
1581 b43_phy_write(dev, B43_PHY_N_BMODE(0x88 + i), val); 2000 b43_phy_write(dev, B43_PHY_N_BMODE(0x88 + i), val);
1582 val -= 0x202; 2001 val -= 0x202;
1583 } 2002 }
1584 val = 0x3E3F; 2003 val = 0x3E3F;
1585 for (i = 0; i < 16; i++) { 2004 for (i = 0; i < 16; i++) {
1586 b43_phy_write(dev, B43_PHY_N_BMODE(0x97 + i), val); 2005 b43_phy_write(dev, B43_PHY_N_BMODE(0x98 + i), val);
1587 val -= 0x202; 2006 val -= 0x202;
1588 } 2007 }
1589 b43_phy_write(dev, B43_PHY_N_BMODE(0x38), 0x668); 2008 b43_phy_write(dev, B43_PHY_N_BMODE(0x38), 0x668);
@@ -1591,7 +2010,8 @@ static void b43_nphy_bphy_init(struct b43_wldev *dev)
1591 2010
1592/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ScaleOffsetRssi */ 2011/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ScaleOffsetRssi */
1593static void b43_nphy_scale_offset_rssi(struct b43_wldev *dev, u16 scale, 2012static void b43_nphy_scale_offset_rssi(struct b43_wldev *dev, u16 scale,
1594 s8 offset, u8 core, u8 rail, u8 type) 2013 s8 offset, u8 core, u8 rail,
2014 enum b43_nphy_rssi_type type)
1595{ 2015{
1596 u16 tmp; 2016 u16 tmp;
1597 bool core1or5 = (core == 1) || (core == 5); 2017 bool core1or5 = (core == 1) || (core == 5);
@@ -1600,53 +2020,59 @@ static void b43_nphy_scale_offset_rssi(struct b43_wldev *dev, u16 scale,
1600 offset = clamp_val(offset, -32, 31); 2020 offset = clamp_val(offset, -32, 31);
1601 tmp = ((scale & 0x3F) << 8) | (offset & 0x3F); 2021 tmp = ((scale & 0x3F) << 8) | (offset & 0x3F);
1602 2022
1603 if (core1or5 && (rail == 0) && (type == 2)) 2023 if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_Z))
1604 b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Z, tmp); 2024 b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Z, tmp);
1605 if (core1or5 && (rail == 1) && (type == 2)) 2025 if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_Z))
1606 b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Z, tmp); 2026 b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Z, tmp);
1607 if (core2or5 && (rail == 0) && (type == 2)) 2027 if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_Z))
1608 b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Z, tmp); 2028 b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Z, tmp);
1609 if (core2or5 && (rail == 1) && (type == 2)) 2029 if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_Z))
1610 b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Z, tmp); 2030 b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Z, tmp);
1611 if (core1or5 && (rail == 0) && (type == 0)) 2031
2032 if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_X))
1612 b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_X, tmp); 2033 b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_X, tmp);
1613 if (core1or5 && (rail == 1) && (type == 0)) 2034 if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_X))
1614 b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_X, tmp); 2035 b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_X, tmp);
1615 if (core2or5 && (rail == 0) && (type == 0)) 2036 if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_X))
1616 b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_X, tmp); 2037 b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_X, tmp);
1617 if (core2or5 && (rail == 1) && (type == 0)) 2038 if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_X))
1618 b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_X, tmp); 2039 b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_X, tmp);
1619 if (core1or5 && (rail == 0) && (type == 1)) 2040
2041 if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_Y))
1620 b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Y, tmp); 2042 b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Y, tmp);
1621 if (core1or5 && (rail == 1) && (type == 1)) 2043 if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_Y))
1622 b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Y, tmp); 2044 b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Y, tmp);
1623 if (core2or5 && (rail == 0) && (type == 1)) 2045 if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_Y))
1624 b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Y, tmp); 2046 b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Y, tmp);
1625 if (core2or5 && (rail == 1) && (type == 1)) 2047 if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_Y))
1626 b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Y, tmp); 2048 b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Y, tmp);
1627 if (core1or5 && (rail == 0) && (type == 6)) 2049
2050 if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_TBD))
1628 b43_phy_write(dev, B43_NPHY_RSSIMC_0I_TBD, tmp); 2051 b43_phy_write(dev, B43_NPHY_RSSIMC_0I_TBD, tmp);
1629 if (core1or5 && (rail == 1) && (type == 6)) 2052 if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_TBD))
1630 b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_TBD, tmp); 2053 b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_TBD, tmp);
1631 if (core2or5 && (rail == 0) && (type == 6)) 2054 if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_TBD))
1632 b43_phy_write(dev, B43_NPHY_RSSIMC_1I_TBD, tmp); 2055 b43_phy_write(dev, B43_NPHY_RSSIMC_1I_TBD, tmp);
1633 if (core2or5 && (rail == 1) && (type == 6)) 2056 if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_TBD))
1634 b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TBD, tmp); 2057 b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TBD, tmp);
1635 if (core1or5 && (rail == 0) && (type == 3)) 2058
2059 if (core1or5 && (rail == 0) && (type == B43_NPHY_RSSI_PWRDET))
1636 b43_phy_write(dev, B43_NPHY_RSSIMC_0I_PWRDET, tmp); 2060 b43_phy_write(dev, B43_NPHY_RSSIMC_0I_PWRDET, tmp);
1637 if (core1or5 && (rail == 1) && (type == 3)) 2061 if (core1or5 && (rail == 1) && (type == B43_NPHY_RSSI_PWRDET))
1638 b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_PWRDET, tmp); 2062 b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_PWRDET, tmp);
1639 if (core2or5 && (rail == 0) && (type == 3)) 2063 if (core2or5 && (rail == 0) && (type == B43_NPHY_RSSI_PWRDET))
1640 b43_phy_write(dev, B43_NPHY_RSSIMC_1I_PWRDET, tmp); 2064 b43_phy_write(dev, B43_NPHY_RSSIMC_1I_PWRDET, tmp);
1641 if (core2or5 && (rail == 1) && (type == 3)) 2065 if (core2or5 && (rail == 1) && (type == B43_NPHY_RSSI_PWRDET))
1642 b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_PWRDET, tmp); 2066 b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_PWRDET, tmp);
1643 if (core1or5 && (type == 4)) 2067
2068 if (core1or5 && (type == B43_NPHY_RSSI_TSSI_I))
1644 b43_phy_write(dev, B43_NPHY_RSSIMC_0I_TSSI, tmp); 2069 b43_phy_write(dev, B43_NPHY_RSSIMC_0I_TSSI, tmp);
1645 if (core2or5 && (type == 4)) 2070 if (core2or5 && (type == B43_NPHY_RSSI_TSSI_I))
1646 b43_phy_write(dev, B43_NPHY_RSSIMC_1I_TSSI, tmp); 2071 b43_phy_write(dev, B43_NPHY_RSSIMC_1I_TSSI, tmp);
1647 if (core1or5 && (type == 5)) 2072
2073 if (core1or5 && (type == B43_NPHY_RSSI_TSSI_Q))
1648 b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_TSSI, tmp); 2074 b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_TSSI, tmp);
1649 if (core2or5 && (type == 5)) 2075 if (core2or5 && (type == B43_NPHY_RSSI_TSSI_Q))
1650 b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TSSI, tmp); 2076 b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TSSI, tmp);
1651} 2077}
1652 2078
@@ -1674,27 +2100,39 @@ static void b43_nphy_rev2_rssi_select(struct b43_wldev *dev, u8 code, u8 type)
1674 (type + 1) << 4); 2100 (type + 1) << 4);
1675 } 2101 }
1676 2102
1677 /* TODO use some definitions */
1678 if (code == 0) { 2103 if (code == 0) {
1679 b43_phy_maskset(dev, B43_NPHY_AFECTL_OVER, 0xCFFF, 0); 2104 b43_phy_mask(dev, B43_NPHY_AFECTL_OVER, ~0x3000);
1680 if (type < 3) { 2105 if (type < 3) {
1681 b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 0xFEC7, 0); 2106 b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
1682 b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 0xEFDC, 0); 2107 ~(B43_NPHY_RFCTL_CMD_RXEN |
1683 b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 0xFFFE, 0); 2108 B43_NPHY_RFCTL_CMD_CORESEL));
2109 b43_phy_mask(dev, B43_NPHY_RFCTL_OVER,
2110 ~(0x1 << 12 |
2111 0x1 << 5 |
2112 0x1 << 1 |
2113 0x1));
2114 b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
2115 ~B43_NPHY_RFCTL_CMD_START);
1684 udelay(20); 2116 udelay(20);
1685 b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 0xFFFE, 0); 2117 b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, ~0x1);
1686 } 2118 }
1687 } else { 2119 } else {
1688 b43_phy_maskset(dev, B43_NPHY_AFECTL_OVER, 0xCFFF, 2120 b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x3000);
1689 0x3000);
1690 if (type < 3) { 2121 if (type < 3) {
1691 b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 2122 b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD,
1692 0xFEC7, 0x0180); 2123 ~(B43_NPHY_RFCTL_CMD_RXEN |
1693 b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 2124 B43_NPHY_RFCTL_CMD_CORESEL),
1694 0xEFDC, (code << 1 | 0x1021)); 2125 (B43_NPHY_RFCTL_CMD_RXEN |
1695 b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 0xFFFE, 0x1); 2126 code << B43_NPHY_RFCTL_CMD_CORESEL_SHIFT));
2127 b43_phy_set(dev, B43_NPHY_RFCTL_OVER,
2128 (0x1 << 12 |
2129 0x1 << 5 |
2130 0x1 << 1 |
2131 0x1));
2132 b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
2133 B43_NPHY_RFCTL_CMD_START);
1696 udelay(20); 2134 udelay(20);
1697 b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 0xFFFE, 0); 2135 b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, ~0x1);
1698 } 2136 }
1699 } 2137 }
1700} 2138}
@@ -1843,6 +2281,17 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
1843 save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER); 2281 save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
1844 save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S0); 2282 save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S0);
1845 save_regs_phy[7] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B32S1); 2283 save_regs_phy[7] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B32S1);
2284 save_regs_phy[8] = 0;
2285 } else {
2286 save_regs_phy[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
2287 save_regs_phy[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
2288 save_regs_phy[2] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
2289 save_regs_phy[3] = b43_phy_read(dev, B43_NPHY_RFCTL_CMD);
2290 save_regs_phy[4] = b43_phy_read(dev, B43_NPHY_RFCTL_OVER);
2291 save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO1);
2292 save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO2);
2293 save_regs_phy[7] = 0;
2294 save_regs_phy[8] = 0;
1846 } 2295 }
1847 2296
1848 b43_nphy_rssi_select(dev, 5, type); 2297 b43_nphy_rssi_select(dev, 5, type);
@@ -1886,6 +2335,14 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
1886 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[5]); 2335 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[5]);
1887 b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S0, save_regs_phy[6]); 2336 b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S0, save_regs_phy[6]);
1888 b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S1, save_regs_phy[7]); 2337 b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S1, save_regs_phy[7]);
2338 } else {
2339 b43_phy_write(dev, B43_NPHY_AFECTL_C1, save_regs_phy[0]);
2340 b43_phy_write(dev, B43_NPHY_AFECTL_C2, save_regs_phy[1]);
2341 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[2]);
2342 b43_phy_write(dev, B43_NPHY_RFCTL_CMD, save_regs_phy[3]);
2343 b43_phy_write(dev, B43_NPHY_RFCTL_OVER, save_regs_phy[4]);
2344 b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO1, save_regs_phy[5]);
2345 b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO2, save_regs_phy[6]);
1889 } 2346 }
1890 2347
1891 return out; 2348 return out;
@@ -1900,7 +2357,10 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type)
1900 u16 class, override; 2357 u16 class, override;
1901 u8 regs_save_radio[2]; 2358 u8 regs_save_radio[2];
1902 u16 regs_save_phy[2]; 2359 u16 regs_save_phy[2];
2360
1903 s8 offset[4]; 2361 s8 offset[4];
2362 u8 core;
2363 u8 rail;
1904 2364
1905 u16 clip_state[2]; 2365 u16 clip_state[2];
1906 u16 clip_off[2] = { 0xFFFF, 0xFFFF }; 2366 u16 clip_off[2] = { 0xFFFF, 0xFFFF };
@@ -2001,16 +2461,15 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type)
2001 if (results_min[i] == 248) 2461 if (results_min[i] == 248)
2002 offset[i] = code - 32; 2462 offset[i] = code - 32;
2003 2463
2004 if (i % 2 == 0) 2464 core = (i / 2) ? 2 : 1;
2005 b43_nphy_scale_offset_rssi(dev, 0, offset[i], 1, 0, 2465 rail = (i % 2) ? 1 : 0;
2006 type); 2466
2007 else 2467 b43_nphy_scale_offset_rssi(dev, 0, offset[i], core, rail,
2008 b43_nphy_scale_offset_rssi(dev, 0, offset[i], 2, 1, 2468 type);
2009 type);
2010 } 2469 }
2011 2470
2012 b43_radio_maskset(dev, B2055_C1_PD_RSSIMISC, 0xF8, state[0]); 2471 b43_radio_maskset(dev, B2055_C1_PD_RSSIMISC, 0xF8, state[0]);
2013 b43_radio_maskset(dev, B2055_C1_PD_RSSIMISC, 0xF8, state[1]); 2472 b43_radio_maskset(dev, B2055_C2_PD_RSSIMISC, 0xF8, state[1]);
2014 2473
2015 switch (state[2]) { 2474 switch (state[2]) {
2016 case 1: 2475 case 1:
@@ -2048,6 +2507,9 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type)
2048 2507
2049 b43_nphy_classifier(dev, 7, class); 2508 b43_nphy_classifier(dev, 7, class);
2050 b43_nphy_write_clip_detection(dev, clip_state); 2509 b43_nphy_write_clip_detection(dev, clip_state);
2510 /* Specs don't say about reset here, but it makes wl and b43 dumps
2511 identical, it really seems wl performs this */
2512 b43_nphy_reset_cca(dev);
2051} 2513}
2052 2514
2053/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */ 2515/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */
@@ -2065,9 +2527,9 @@ static void b43_nphy_rssi_cal(struct b43_wldev *dev)
2065 if (dev->phy.rev >= 3) { 2527 if (dev->phy.rev >= 3) {
2066 b43_nphy_rev3_rssi_cal(dev); 2528 b43_nphy_rev3_rssi_cal(dev);
2067 } else { 2529 } else {
2068 b43_nphy_rev2_rssi_cal(dev, 2); 2530 b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_Z);
2069 b43_nphy_rev2_rssi_cal(dev, 0); 2531 b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_X);
2070 b43_nphy_rev2_rssi_cal(dev, 1); 2532 b43_nphy_rev2_rssi_cal(dev, B43_NPHY_RSSI_Y);
2071 } 2533 }
2072} 2534}
2073 2535
@@ -2083,12 +2545,12 @@ static void b43_nphy_restore_rssi_cal(struct b43_wldev *dev)
2083 u16 *rssical_phy_regs = NULL; 2545 u16 *rssical_phy_regs = NULL;
2084 2546
2085 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { 2547 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
2086 if (b43_empty_chanspec(&nphy->rssical_chanspec_2G)) 2548 if (!nphy->rssical_chanspec_2G.center_freq)
2087 return; 2549 return;
2088 rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_2G; 2550 rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_2G;
2089 rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_2G; 2551 rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_2G;
2090 } else { 2552 } else {
2091 if (b43_empty_chanspec(&nphy->rssical_chanspec_5G)) 2553 if (!nphy->rssical_chanspec_5G.center_freq)
2092 return; 2554 return;
2093 rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_5G; 2555 rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_5G;
2094 rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G; 2556 rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G;
@@ -2301,7 +2763,7 @@ static void b43_nphy_int_pa_set_tx_dig_filters(struct b43_wldev *dev)
2301{ 2763{
2302 int i, j; 2764 int i, j;
2303 /* B43_NPHY_TXF_20CO_S0A1, B43_NPHY_TXF_40CO_S0A1, unknown */ 2765 /* B43_NPHY_TXF_20CO_S0A1, B43_NPHY_TXF_40CO_S0A1, unknown */
2304 u16 offset[] = { 0x186, 0x195, 0x2C5 }; 2766 static const u16 offset[] = { 0x186, 0x195, 0x2C5 };
2305 2767
2306 for (i = 0; i < 3; i++) 2768 for (i = 0; i < 3; i++)
2307 for (j = 0; j < 15; j++) 2769 for (j = 0; j < 15; j++)
@@ -2333,7 +2795,7 @@ static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev)
2333 struct nphy_txgains target; 2795 struct nphy_txgains target;
2334 const u32 *table = NULL; 2796 const u32 *table = NULL;
2335 2797
2336 if (nphy->txpwrctrl == 0) { 2798 if (!nphy->txpwrctrl) {
2337 int i; 2799 int i;
2338 2800
2339 if (nphy->hang_avoid) 2801 if (nphy->hang_avoid)
@@ -2544,8 +3006,9 @@ static void b43_nphy_save_cal(struct b43_wldev *dev)
2544 txcal_radio_regs[2] = b43_radio_read(dev, 0x8D); 3006 txcal_radio_regs[2] = b43_radio_read(dev, 0x8D);
2545 txcal_radio_regs[3] = b43_radio_read(dev, 0xBC); 3007 txcal_radio_regs[3] = b43_radio_read(dev, 0xBC);
2546 } 3008 }
2547 *iqcal_chanspec = nphy->radio_chanspec; 3009 iqcal_chanspec->center_freq = dev->phy.channel_freq;
2548 b43_ntab_write_bulk(dev, B43_NTAB16(15, 80), 8, table); 3010 iqcal_chanspec->channel_type = dev->phy.channel_type;
3011 b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 8, table);
2549 3012
2550 if (nphy->hang_avoid) 3013 if (nphy->hang_avoid)
2551 b43_nphy_stay_in_carrier_search(dev, 0); 3014 b43_nphy_stay_in_carrier_search(dev, 0);
@@ -2565,12 +3028,12 @@ static void b43_nphy_restore_cal(struct b43_wldev *dev)
2565 struct b43_phy_n_iq_comp *rxcal_coeffs = NULL; 3028 struct b43_phy_n_iq_comp *rxcal_coeffs = NULL;
2566 3029
2567 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { 3030 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
2568 if (b43_empty_chanspec(&nphy->iqcal_chanspec_2G)) 3031 if (!nphy->iqcal_chanspec_2G.center_freq)
2569 return; 3032 return;
2570 table = nphy->cal_cache.txcal_coeffs_2G; 3033 table = nphy->cal_cache.txcal_coeffs_2G;
2571 loft = &nphy->cal_cache.txcal_coeffs_2G[5]; 3034 loft = &nphy->cal_cache.txcal_coeffs_2G[5];
2572 } else { 3035 } else {
2573 if (b43_empty_chanspec(&nphy->iqcal_chanspec_5G)) 3036 if (!nphy->iqcal_chanspec_5G.center_freq)
2574 return; 3037 return;
2575 table = nphy->cal_cache.txcal_coeffs_5G; 3038 table = nphy->cal_cache.txcal_coeffs_5G;
2576 loft = &nphy->cal_cache.txcal_coeffs_5G[5]; 3039 loft = &nphy->cal_cache.txcal_coeffs_5G[5];
@@ -2630,7 +3093,7 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
2630 int freq; 3093 int freq;
2631 bool avoid = false; 3094 bool avoid = false;
2632 u8 length; 3095 u8 length;
2633 u16 tmp, core, type, count, max, numb, last, cmd; 3096 u16 tmp, core, type, count, max, numb, last = 0, cmd;
2634 const u16 *table; 3097 const u16 *table;
2635 bool phy6or5x; 3098 bool phy6or5x;
2636 3099
@@ -2815,7 +3278,10 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
2815 b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length, 3278 b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length,
2816 nphy->txiqlocal_bestc); 3279 nphy->txiqlocal_bestc);
2817 nphy->txiqlocal_coeffsvalid = true; 3280 nphy->txiqlocal_coeffsvalid = true;
2818 nphy->txiqlocal_chanspec = nphy->radio_chanspec; 3281 nphy->txiqlocal_chanspec.center_freq =
3282 dev->phy.channel_freq;
3283 nphy->txiqlocal_chanspec.channel_type =
3284 dev->phy.channel_type;
2819 } else { 3285 } else {
2820 length = 11; 3286 length = 11;
2821 if (dev->phy.rev < 3) 3287 if (dev->phy.rev < 3)
@@ -2851,7 +3317,8 @@ static void b43_nphy_reapply_tx_cal_coeffs(struct b43_wldev *dev)
2851 bool equal = true; 3317 bool equal = true;
2852 3318
2853 if (!nphy->txiqlocal_coeffsvalid || 3319 if (!nphy->txiqlocal_coeffsvalid ||
2854 b43_eq_chanspecs(&nphy->txiqlocal_chanspec, &nphy->radio_chanspec)) 3320 nphy->txiqlocal_chanspec.center_freq != dev->phy.channel_freq ||
3321 nphy->txiqlocal_chanspec.channel_type != dev->phy.channel_type)
2855 return; 3322 return;
2856 3323
2857 b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer); 3324 b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer);
@@ -2885,7 +3352,7 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev,
2885 u8 rfctl[2]; 3352 u8 rfctl[2];
2886 u8 afectl_core; 3353 u8 afectl_core;
2887 u16 tmp[6]; 3354 u16 tmp[6];
2888 u16 cur_hpf1, cur_hpf2, cur_lna; 3355 u16 uninitialized_var(cur_hpf1), uninitialized_var(cur_hpf2), cur_lna;
2889 u32 real, imag; 3356 u32 real, imag;
2890 enum ieee80211_band band; 3357 enum ieee80211_band band;
2891 3358
@@ -2965,7 +3432,7 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev,
2965 (2 - i)); 3432 (2 - i));
2966 } 3433 }
2967 3434
2968 for (j = 0; i < 4; j++) { 3435 for (j = 0; j < 4; j++) {
2969 if (j < 3) { 3436 if (j < 3) {
2970 cur_lna = lna[j]; 3437 cur_lna = lna[j];
2971 cur_hpf1 = hpf1[j]; 3438 cur_hpf1 = hpf1[j];
@@ -3073,13 +3540,53 @@ static int b43_nphy_cal_rx_iq(struct b43_wldev *dev,
3073 return b43_nphy_rev2_cal_rx_iq(dev, target, type, debug); 3540 return b43_nphy_rev2_cal_rx_iq(dev, target, type, debug);
3074} 3541}
3075 3542
3543/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCoreSetState */
3544static void b43_nphy_set_rx_core_state(struct b43_wldev *dev, u8 mask)
3545{
3546 struct b43_phy *phy = &dev->phy;
3547 struct b43_phy_n *nphy = phy->n;
3548 /* u16 buf[16]; it's rev3+ */
3549
3550 nphy->phyrxchain = mask;
3551
3552 if (0 /* FIXME clk */)
3553 return;
3554
3555 b43_mac_suspend(dev);
3556
3557 if (nphy->hang_avoid)
3558 b43_nphy_stay_in_carrier_search(dev, true);
3559
3560 b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_RXEN,
3561 (mask & 0x3) << B43_NPHY_RFSEQCA_RXEN_SHIFT);
3562
3563 if ((mask & 0x3) != 0x3) {
3564 b43_phy_write(dev, B43_NPHY_HPANT_SWTHRES, 1);
3565 if (dev->phy.rev >= 3) {
3566 /* TODO */
3567 }
3568 } else {
3569 b43_phy_write(dev, B43_NPHY_HPANT_SWTHRES, 0x1E);
3570 if (dev->phy.rev >= 3) {
3571 /* TODO */
3572 }
3573 }
3574
3575 b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
3576
3577 if (nphy->hang_avoid)
3578 b43_nphy_stay_in_carrier_search(dev, false);
3579
3580 b43_mac_enable(dev);
3581}
3582
3076/* 3583/*
3077 * Init N-PHY 3584 * Init N-PHY
3078 * http://bcm-v4.sipsolutions.net/802.11/PHY/Init/N 3585 * http://bcm-v4.sipsolutions.net/802.11/PHY/Init/N
3079 */ 3586 */
3080int b43_phy_initn(struct b43_wldev *dev) 3587int b43_phy_initn(struct b43_wldev *dev)
3081{ 3588{
3082 struct ssb_bus *bus = dev->dev->bus; 3589 struct ssb_bus *bus = dev->sdev->bus;
3083 struct b43_phy *phy = &dev->phy; 3590 struct b43_phy *phy = &dev->phy;
3084 struct b43_phy_n *nphy = phy->n; 3591 struct b43_phy_n *nphy = phy->n;
3085 u8 tx_pwr_state; 3592 u8 tx_pwr_state;
@@ -3094,7 +3601,7 @@ int b43_phy_initn(struct b43_wldev *dev)
3094 if ((dev->phy.rev >= 3) && 3601 if ((dev->phy.rev >= 3) &&
3095 (bus->sprom.boardflags_lo & B43_BFL_EXTLNA) && 3602 (bus->sprom.boardflags_lo & B43_BFL_EXTLNA) &&
3096 (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)) { 3603 (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)) {
3097 chipco_set32(&dev->dev->bus->chipco, SSB_CHIPCO_CHIPCTL, 0x40); 3604 chipco_set32(&dev->sdev->bus->chipco, SSB_CHIPCO_CHIPCTL, 0x40);
3098 } 3605 }
3099 nphy->deaf_count = 0; 3606 nphy->deaf_count = 0;
3100 b43_nphy_tables_init(dev); 3607 b43_nphy_tables_init(dev);
@@ -3173,7 +3680,7 @@ int b43_phy_initn(struct b43_wldev *dev)
3173 b43_phy_write(dev, B43_NPHY_BBCFG, tmp & ~B43_NPHY_BBCFG_RSTCCA); 3680 b43_phy_write(dev, B43_NPHY_BBCFG, tmp & ~B43_NPHY_BBCFG_RSTCCA);
3174 b43_nphy_bmac_clock_fgc(dev, 0); 3681 b43_nphy_bmac_clock_fgc(dev, 0);
3175 3682
3176 /* TODO N PHY MAC PHY Clock Set with argument 1 */ 3683 b43_mac_phy_clock_set(dev, true);
3177 3684
3178 b43_nphy_pa_override(dev, false); 3685 b43_nphy_pa_override(dev, false);
3179 b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX); 3686 b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX);
@@ -3182,10 +3689,12 @@ int b43_phy_initn(struct b43_wldev *dev)
3182 3689
3183 b43_nphy_classifier(dev, 0, 0); 3690 b43_nphy_classifier(dev, 0, 0);
3184 b43_nphy_read_clip_detection(dev, clip); 3691 b43_nphy_read_clip_detection(dev, clip);
3692 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
3693 b43_nphy_bphy_init(dev);
3694
3185 tx_pwr_state = nphy->txpwrctrl; 3695 tx_pwr_state = nphy->txpwrctrl;
3186 /* TODO N PHY TX power control with argument 0 3696 b43_nphy_tx_power_ctrl(dev, false);
3187 (turning off power control) */ 3697 b43_nphy_tx_power_fix(dev);
3188 /* TODO Fix the TX Power Settings */
3189 /* TODO N PHY TX Power Control Idle TSSI */ 3698 /* TODO N PHY TX Power Control Idle TSSI */
3190 /* TODO N PHY TX Power Control Setup */ 3699 /* TODO N PHY TX Power Control Setup */
3191 3700
@@ -3199,18 +3708,16 @@ int b43_phy_initn(struct b43_wldev *dev)
3199 } 3708 }
3200 3709
3201 if (nphy->phyrxchain != 3) 3710 if (nphy->phyrxchain != 3)
3202 ;/* TODO N PHY RX Core Set State with phyrxchain as argument */ 3711 b43_nphy_set_rx_core_state(dev, nphy->phyrxchain);
3203 if (nphy->mphase_cal_phase_id > 0) 3712 if (nphy->mphase_cal_phase_id > 0)
3204 ;/* TODO PHY Periodic Calibration Multi-Phase Restart */ 3713 ;/* TODO PHY Periodic Calibration Multi-Phase Restart */
3205 3714
3206 do_rssi_cal = false; 3715 do_rssi_cal = false;
3207 if (phy->rev >= 3) { 3716 if (phy->rev >= 3) {
3208 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) 3717 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
3209 do_rssi_cal = 3718 do_rssi_cal = !nphy->rssical_chanspec_2G.center_freq;
3210 b43_empty_chanspec(&nphy->rssical_chanspec_2G);
3211 else 3719 else
3212 do_rssi_cal = 3720 do_rssi_cal = !nphy->rssical_chanspec_5G.center_freq;
3213 b43_empty_chanspec(&nphy->rssical_chanspec_5G);
3214 3721
3215 if (do_rssi_cal) 3722 if (do_rssi_cal)
3216 b43_nphy_rssi_cal(dev); 3723 b43_nphy_rssi_cal(dev);
@@ -3222,9 +3729,9 @@ int b43_phy_initn(struct b43_wldev *dev)
3222 3729
3223 if (!((nphy->measure_hold & 0x6) != 0)) { 3730 if (!((nphy->measure_hold & 0x6) != 0)) {
3224 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) 3731 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
3225 do_cal = b43_empty_chanspec(&nphy->iqcal_chanspec_2G); 3732 do_cal = !nphy->iqcal_chanspec_2G.center_freq;
3226 else 3733 else
3227 do_cal = b43_empty_chanspec(&nphy->iqcal_chanspec_5G); 3734 do_cal = !nphy->iqcal_chanspec_5G.center_freq;
3228 3735
3229 if (nphy->mute) 3736 if (nphy->mute)
3230 do_cal = false; 3737 do_cal = false;
@@ -3244,21 +3751,18 @@ int b43_phy_initn(struct b43_wldev *dev)
3244 /* TODO N PHY Pre Calibrate TX Gain */ 3751 /* TODO N PHY Pre Calibrate TX Gain */
3245 target = b43_nphy_get_tx_gains(dev); 3752 target = b43_nphy_get_tx_gains(dev);
3246 } 3753 }
3247 } 3754 if (!b43_nphy_cal_tx_iq_lo(dev, target, true, false))
3755 if (b43_nphy_cal_rx_iq(dev, target, 2, 0) == 0)
3756 b43_nphy_save_cal(dev);
3757 } else if (nphy->mphase_cal_phase_id == 0)
3758 ;/* N PHY Periodic Calibration with arg 3 */
3759 } else {
3760 b43_nphy_restore_cal(dev);
3248 } 3761 }
3249 } 3762 }
3250 3763
3251 if (!b43_nphy_cal_tx_iq_lo(dev, target, true, false)) {
3252 if (b43_nphy_cal_rx_iq(dev, target, 2, 0) == 0)
3253 b43_nphy_save_cal(dev);
3254 else if (nphy->mphase_cal_phase_id == 0)
3255 ;/* N PHY Periodic Calibration with argument 3 */
3256 } else {
3257 b43_nphy_restore_cal(dev);
3258 }
3259
3260 b43_nphy_tx_pwr_ctrl_coef_setup(dev); 3764 b43_nphy_tx_pwr_ctrl_coef_setup(dev);
3261 /* TODO N PHY TX Power Control Enable with argument tx_pwr_state */ 3765 b43_nphy_tx_power_ctrl(dev, tx_pwr_state);
3262 b43_phy_write(dev, B43_NPHY_TXMACIF_HOLDOFF, 0x0015); 3766 b43_phy_write(dev, B43_NPHY_TXMACIF_HOLDOFF, 0x0015);
3263 b43_phy_write(dev, B43_NPHY_TXMACDELAY, 0x0320); 3767 b43_phy_write(dev, B43_NPHY_TXMACDELAY, 0x0320);
3264 if (phy->rev >= 3 && phy->rev <= 6) 3768 if (phy->rev >= 3 && phy->rev <= 6)
@@ -3267,29 +3771,29 @@ int b43_phy_initn(struct b43_wldev *dev)
3267 if (phy->rev >= 3) 3771 if (phy->rev >= 3)
3268 b43_nphy_spur_workaround(dev); 3772 b43_nphy_spur_workaround(dev);
3269 3773
3270 b43err(dev->wl, "IEEE 802.11n devices are not supported, yet.\n");
3271 return 0; 3774 return 0;
3272} 3775}
3273 3776
3274/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ChanspecSetup */ 3777/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ChanspecSetup */
3275static void b43_nphy_chanspec_setup(struct b43_wldev *dev, 3778static void b43_nphy_channel_setup(struct b43_wldev *dev,
3276 const struct b43_phy_n_sfo_cfg *e, 3779 const struct b43_phy_n_sfo_cfg *e,
3277 struct b43_chanspec chanspec) 3780 struct ieee80211_channel *new_channel)
3278{ 3781{
3279 struct b43_phy *phy = &dev->phy; 3782 struct b43_phy *phy = &dev->phy;
3280 struct b43_phy_n *nphy = dev->phy.n; 3783 struct b43_phy_n *nphy = dev->phy.n;
3281 3784
3282 u16 tmp; 3785 u16 old_band_5ghz;
3283 u32 tmp32; 3786 u32 tmp32;
3284 3787
3285 tmp = b43_phy_read(dev, B43_NPHY_BANDCTL) & B43_NPHY_BANDCTL_5GHZ; 3788 old_band_5ghz =
3286 if (chanspec.b_freq == 1 && tmp == 0) { 3789 b43_phy_read(dev, B43_NPHY_BANDCTL) & B43_NPHY_BANDCTL_5GHZ;
3790 if (new_channel->band == IEEE80211_BAND_5GHZ && !old_band_5ghz) {
3287 tmp32 = b43_read32(dev, B43_MMIO_PSM_PHY_HDR); 3791 tmp32 = b43_read32(dev, B43_MMIO_PSM_PHY_HDR);
3288 b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32 | 4); 3792 b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32 | 4);
3289 b43_phy_set(dev, B43_PHY_B_BBCFG, 0xC000); 3793 b43_phy_set(dev, B43_PHY_B_BBCFG, 0xC000);
3290 b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32); 3794 b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32);
3291 b43_phy_set(dev, B43_NPHY_BANDCTL, B43_NPHY_BANDCTL_5GHZ); 3795 b43_phy_set(dev, B43_NPHY_BANDCTL, B43_NPHY_BANDCTL_5GHZ);
3292 } else if (chanspec.b_freq == 1) { 3796 } else if (new_channel->band == IEEE80211_BAND_2GHZ && old_band_5ghz) {
3293 b43_phy_mask(dev, B43_NPHY_BANDCTL, ~B43_NPHY_BANDCTL_5GHZ); 3797 b43_phy_mask(dev, B43_NPHY_BANDCTL, ~B43_NPHY_BANDCTL_5GHZ);
3294 tmp32 = b43_read32(dev, B43_MMIO_PSM_PHY_HDR); 3798 tmp32 = b43_read32(dev, B43_MMIO_PSM_PHY_HDR);
3295 b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32 | 4); 3799 b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32 | 4);
@@ -3299,23 +3803,16 @@ static void b43_nphy_chanspec_setup(struct b43_wldev *dev,
3299 3803
3300 b43_chantab_phy_upload(dev, e); 3804 b43_chantab_phy_upload(dev, e);
3301 3805
3302 tmp = chanspec.channel; 3806 if (new_channel->hw_value == 14) {
3303 if (chanspec.b_freq == 1)
3304 tmp |= 0x0100;
3305 if (chanspec.b_width == 3)
3306 tmp |= 0x0200;
3307 b43_shm_write16(dev, B43_SHM_SHARED, 0xA0, tmp);
3308
3309 if (nphy->radio_chanspec.channel == 14) {
3310 b43_nphy_classifier(dev, 2, 0); 3807 b43_nphy_classifier(dev, 2, 0);
3311 b43_phy_set(dev, B43_PHY_B_TEST, 0x0800); 3808 b43_phy_set(dev, B43_PHY_B_TEST, 0x0800);
3312 } else { 3809 } else {
3313 b43_nphy_classifier(dev, 2, 2); 3810 b43_nphy_classifier(dev, 2, 2);
3314 if (chanspec.b_freq == 2) 3811 if (new_channel->band == IEEE80211_BAND_2GHZ)
3315 b43_phy_mask(dev, B43_PHY_B_TEST, ~0x840); 3812 b43_phy_mask(dev, B43_PHY_B_TEST, ~0x840);
3316 } 3813 }
3317 3814
3318 if (nphy->txpwrctrl) 3815 if (!nphy->txpwrctrl)
3319 b43_nphy_tx_power_fix(dev); 3816 b43_nphy_tx_power_fix(dev);
3320 3817
3321 if (dev->phy.rev < 3) 3818 if (dev->phy.rev < 3)
@@ -3334,70 +3831,60 @@ static void b43_nphy_chanspec_setup(struct b43_wldev *dev,
3334} 3831}
3335 3832
3336/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetChanspec */ 3833/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetChanspec */
3337static int b43_nphy_set_chanspec(struct b43_wldev *dev, 3834static int b43_nphy_set_channel(struct b43_wldev *dev,
3338 struct b43_chanspec chanspec) 3835 struct ieee80211_channel *channel,
3836 enum nl80211_channel_type channel_type)
3339{ 3837{
3340 struct b43_phy_n *nphy = dev->phy.n; 3838 struct b43_phy *phy = &dev->phy;
3341 3839
3342 const struct b43_nphy_channeltab_entry_rev2 *tabent_r2; 3840 const struct b43_nphy_channeltab_entry_rev2 *tabent_r2 = NULL;
3343 const struct b43_nphy_channeltab_entry_rev3 *tabent_r3; 3841 const struct b43_nphy_channeltab_entry_rev3 *tabent_r3 = NULL;
3344 3842
3345 u8 tmp; 3843 u8 tmp;
3346 u8 channel = chanspec.channel;
3347 3844
3348 if (dev->phy.rev >= 3) { 3845 if (dev->phy.rev >= 3) {
3349 /* TODO */ 3846 tabent_r3 = b43_nphy_get_chantabent_rev3(dev,
3350 tabent_r3 = NULL; 3847 channel->center_freq);
3351 if (!tabent_r3) 3848 if (!tabent_r3)
3352 return -ESRCH; 3849 return -ESRCH;
3353 } else { 3850 } else {
3354 tabent_r2 = b43_nphy_get_chantabent_rev2(dev, channel); 3851 tabent_r2 = b43_nphy_get_chantabent_rev2(dev,
3852 channel->hw_value);
3355 if (!tabent_r2) 3853 if (!tabent_r2)
3356 return -ESRCH; 3854 return -ESRCH;
3357 } 3855 }
3358 3856
3359 nphy->radio_chanspec = chanspec; 3857 /* Channel is set later in common code, but we need to set it on our
3858 own to let this function's subcalls work properly. */
3859 phy->channel = channel->hw_value;
3860 phy->channel_freq = channel->center_freq;
3360 3861
3361 if (chanspec.b_width != nphy->b_width) 3862 if (b43_channel_type_is_40mhz(phy->channel_type) !=
3362 ; /* TODO: BMAC BW Set (chanspec.b_width) */ 3863 b43_channel_type_is_40mhz(channel_type))
3864 ; /* TODO: BMAC BW Set (channel_type) */
3363 3865
3364 /* TODO: use defines */ 3866 if (channel_type == NL80211_CHAN_HT40PLUS)
3365 if (chanspec.b_width == 3) { 3867 b43_phy_set(dev, B43_NPHY_RXCTL,
3366 if (chanspec.sideband == 2) 3868 B43_NPHY_RXCTL_BSELU20);
3367 b43_phy_set(dev, B43_NPHY_RXCTL, 3869 else if (channel_type == NL80211_CHAN_HT40MINUS)
3368 B43_NPHY_RXCTL_BSELU20); 3870 b43_phy_mask(dev, B43_NPHY_RXCTL,
3369 else 3871 ~B43_NPHY_RXCTL_BSELU20);
3370 b43_phy_mask(dev, B43_NPHY_RXCTL,
3371 ~B43_NPHY_RXCTL_BSELU20);
3372 }
3373 3872
3374 if (dev->phy.rev >= 3) { 3873 if (dev->phy.rev >= 3) {
3375 tmp = (chanspec.b_freq == 1) ? 4 : 0; 3874 tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 4 : 0;
3376 b43_radio_maskset(dev, 0x08, 0xFFFB, tmp); 3875 b43_radio_maskset(dev, 0x08, 0xFFFB, tmp);
3377 /* TODO: PHY Radio2056 Setup (dev, tabent_r3); */ 3876 b43_radio_2056_setup(dev, tabent_r3);
3378 b43_nphy_chanspec_setup(dev, &(tabent_r3->phy_regs), chanspec); 3877 b43_nphy_channel_setup(dev, &(tabent_r3->phy_regs), channel);
3379 } else { 3878 } else {
3380 tmp = (chanspec.b_freq == 1) ? 0x0020 : 0x0050; 3879 tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 0x0020 : 0x0050;
3381 b43_radio_maskset(dev, B2055_MASTER1, 0xFF8F, tmp); 3880 b43_radio_maskset(dev, B2055_MASTER1, 0xFF8F, tmp);
3382 b43_radio_2055_setup(dev, tabent_r2); 3881 b43_radio_2055_setup(dev, tabent_r2);
3383 b43_nphy_chanspec_setup(dev, &(tabent_r2->phy_regs), chanspec); 3882 b43_nphy_channel_setup(dev, &(tabent_r2->phy_regs), channel);
3384 } 3883 }
3385 3884
3386 return 0; 3885 return 0;
3387} 3886}
3388 3887
3389/* Tune the hardware to a new channel */
3390static int nphy_channel_switch(struct b43_wldev *dev, unsigned int channel)
3391{
3392 struct b43_phy_n *nphy = dev->phy.n;
3393
3394 struct b43_chanspec chanspec;
3395 chanspec = nphy->radio_chanspec;
3396 chanspec.channel = channel;
3397
3398 return b43_nphy_set_chanspec(dev, chanspec);
3399}
3400
3401static int b43_nphy_op_allocate(struct b43_wldev *dev) 3888static int b43_nphy_op_allocate(struct b43_wldev *dev)
3402{ 3889{
3403 struct b43_phy_n *nphy; 3890 struct b43_phy_n *nphy;
@@ -3417,7 +3904,11 @@ static void b43_nphy_op_prepare_structs(struct b43_wldev *dev)
3417 3904
3418 memset(nphy, 0, sizeof(*nphy)); 3905 memset(nphy, 0, sizeof(*nphy));
3419 3906
3420 //TODO init struct b43_phy_n 3907 nphy->hang_avoid = (phy->rev == 3 || phy->rev == 4);
3908 nphy->gain_boost = true; /* this way we follow wl, assume it is true */
3909 nphy->txrx_chain = 2; /* sth different than 0 and 1 for now */
3910 nphy->phyrxchain = 3; /* to avoid b43_nphy_set_rx_core_state like wl */
3911 nphy->perical = 2; /* avoid additional rssi cal on init (like wl) */
3421} 3912}
3422 3913
3423static void b43_nphy_op_free(struct b43_wldev *dev) 3914static void b43_nphy_op_free(struct b43_wldev *dev)
@@ -3466,6 +3957,15 @@ static void b43_nphy_op_write(struct b43_wldev *dev, u16 reg, u16 value)
3466 b43_write16(dev, B43_MMIO_PHY_DATA, value); 3957 b43_write16(dev, B43_MMIO_PHY_DATA, value);
3467} 3958}
3468 3959
3960static void b43_nphy_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
3961 u16 set)
3962{
3963 check_phyreg(dev, reg);
3964 b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
3965 b43_write16(dev, B43_MMIO_PHY_DATA,
3966 (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set);
3967}
3968
3469static u16 b43_nphy_op_radio_read(struct b43_wldev *dev, u16 reg) 3969static u16 b43_nphy_op_radio_read(struct b43_wldev *dev, u16 reg)
3470{ 3970{
3471 /* Register 1 is a 32-bit register. */ 3971 /* Register 1 is a 32-bit register. */
@@ -3490,8 +3990,6 @@ static void b43_nphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
3490static void b43_nphy_op_software_rfkill(struct b43_wldev *dev, 3990static void b43_nphy_op_software_rfkill(struct b43_wldev *dev,
3491 bool blocked) 3991 bool blocked)
3492{ 3992{
3493 struct b43_phy_n *nphy = dev->phy.n;
3494
3495 if (b43_read32(dev, B43_MMIO_MACCTL) & B43_MACCTL_ENABLED) 3993 if (b43_read32(dev, B43_MMIO_MACCTL) & B43_MACCTL_ENABLED)
3496 b43err(dev->wl, "MAC not suspended\n"); 3994 b43err(dev->wl, "MAC not suspended\n");
3497 3995
@@ -3518,22 +4016,29 @@ static void b43_nphy_op_software_rfkill(struct b43_wldev *dev,
3518 } else { 4016 } else {
3519 if (dev->phy.rev >= 3) { 4017 if (dev->phy.rev >= 3) {
3520 b43_radio_init2056(dev); 4018 b43_radio_init2056(dev);
3521 b43_nphy_set_chanspec(dev, nphy->radio_chanspec); 4019 b43_switch_channel(dev, dev->phy.channel);
3522 } else { 4020 } else {
3523 b43_radio_init2055(dev); 4021 b43_radio_init2055(dev);
3524 } 4022 }
3525 } 4023 }
3526} 4024}
3527 4025
4026/* http://bcm-v4.sipsolutions.net/802.11/PHY/Anacore */
3528static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on) 4027static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on)
3529{ 4028{
3530 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, 4029 u16 val = on ? 0 : 0x7FFF;
3531 on ? 0 : 0x7FFF); 4030
4031 if (dev->phy.rev >= 3)
4032 b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, val);
4033 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, val);
3532} 4034}
3533 4035
3534static int b43_nphy_op_switch_channel(struct b43_wldev *dev, 4036static int b43_nphy_op_switch_channel(struct b43_wldev *dev,
3535 unsigned int new_channel) 4037 unsigned int new_channel)
3536{ 4038{
4039 struct ieee80211_channel *channel = dev->wl->hw->conf.channel;
4040 enum nl80211_channel_type channel_type = dev->wl->hw->conf.channel_type;
4041
3537 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { 4042 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
3538 if ((new_channel < 1) || (new_channel > 14)) 4043 if ((new_channel < 1) || (new_channel > 14))
3539 return -EINVAL; 4044 return -EINVAL;
@@ -3542,7 +4047,7 @@ static int b43_nphy_op_switch_channel(struct b43_wldev *dev,
3542 return -EINVAL; 4047 return -EINVAL;
3543 } 4048 }
3544 4049
3545 return nphy_channel_switch(dev, new_channel); 4050 return b43_nphy_set_channel(dev, channel, channel_type);
3546} 4051}
3547 4052
3548static unsigned int b43_nphy_op_get_default_chan(struct b43_wldev *dev) 4053static unsigned int b43_nphy_op_get_default_chan(struct b43_wldev *dev)
@@ -3559,6 +4064,7 @@ const struct b43_phy_operations b43_phyops_n = {
3559 .init = b43_nphy_op_init, 4064 .init = b43_nphy_op_init,
3560 .phy_read = b43_nphy_op_read, 4065 .phy_read = b43_nphy_op_read,
3561 .phy_write = b43_nphy_op_write, 4066 .phy_write = b43_nphy_op_write,
4067 .phy_maskset = b43_nphy_op_maskset,
3562 .radio_read = b43_nphy_op_radio_read, 4068 .radio_read = b43_nphy_op_radio_read,
3563 .radio_write = b43_nphy_op_radio_write, 4069 .radio_write = b43_nphy_op_radio_write,
3564 .software_rfkill = b43_nphy_op_software_rfkill, 4070 .software_rfkill = b43_nphy_op_software_rfkill,