diff options
Diffstat (limited to 'drivers/net/wireless/b43/phy_n.c')
-rw-r--r-- | drivers/net/wireless/b43/phy_n.c | 1014 |
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 | ||
34 | struct nphy_txgains { | 36 | struct 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 | ||
70 | enum 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 | |||
80 | static void b43_nphy_stay_in_carrier_search(struct b43_wldev *dev, | ||
81 | bool enable); | ||
68 | static void b43_nphy_set_rf_sequence(struct b43_wldev *dev, u8 cmd, | 82 | static 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); |
70 | static void b43_nphy_force_rf_sequence(struct b43_wldev *dev, | 84 | static 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); |
74 | static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, | 88 | static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, |
75 | u16 value, u8 core); | 89 | u16 value, u8 core); |
76 | static int nphy_channel_switch(struct b43_wldev *dev, unsigned int channel); | ||
77 | |||
78 | static 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 | |||
84 | static 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 | ||
93 | void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna) | 91 | void 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 | ||
142 | static 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 */ | ||
218 | static 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 | |||
144 | static void b43_chantab_phy_upload(struct b43_wldev *dev, | 235 | static 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 */ | ||
247 | static 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 */ | ||
155 | static void b43_nphy_tx_power_fix(struct b43_wldev *dev) | 299 | static 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) | |||
187 | static void b43_radio_init2055_post(struct b43_wldev *dev) | 423 | static 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) | |||
247 | static void b43_radio_init2055(struct b43_wldev *dev) | 484 | static 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 | ||
497 | static 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 | |||
510 | static 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 | */ |
261 | static void b43_radio_init2056(struct b43_wldev *dev) | 529 | static 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 */ |
464 | static void b43_nphy_rx_cal_phy_cleanup(struct b43_wldev *dev, u8 core) | 735 | static 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 */ |
546 | static void b43_nphy_calc_rx_iq_comp(struct b43_wldev *dev, u8 mask) | 818 | static 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 */ |
661 | static void b43_nphy_write_clip_detection(struct b43_wldev *dev, u16 *clip_st) | 932 | static 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 */ |
896 | static void b43_nphy_gain_crtl_workarounds(struct b43_wldev *dev) | 1168 | static 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 */ |
1024 | static void b43_nphy_workarounds(struct b43_wldev *dev) | 1374 | static 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 */ | ||
1574 | static void b43_nphy_bphy_init(struct b43_wldev *dev) | 1993 | static 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 */ |
1593 | static void b43_nphy_scale_offset_rssi(struct b43_wldev *dev, u16 scale, | 2012 | static 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 */ | ||
3544 | static 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 | */ |
3080 | int b43_phy_initn(struct b43_wldev *dev) | 3587 | int 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 */ |
3275 | static void b43_nphy_chanspec_setup(struct b43_wldev *dev, | 3778 | static 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 */ |
3337 | static int b43_nphy_set_chanspec(struct b43_wldev *dev, | 3834 | static 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 */ | ||
3390 | static 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 | |||
3401 | static int b43_nphy_op_allocate(struct b43_wldev *dev) | 3888 | static 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 | ||
3423 | static void b43_nphy_op_free(struct b43_wldev *dev) | 3914 | static 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 | ||
3960 | static 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 | |||
3469 | static u16 b43_nphy_op_radio_read(struct b43_wldev *dev, u16 reg) | 3969 | static 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) | |||
3490 | static void b43_nphy_op_software_rfkill(struct b43_wldev *dev, | 3990 | static 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 */ | ||
3528 | static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on) | 4027 | static 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 | ||
3534 | static int b43_nphy_op_switch_channel(struct b43_wldev *dev, | 4036 | static 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 | ||
3548 | static unsigned int b43_nphy_op_get_default_chan(struct b43_wldev *dev) | 4053 | static 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, |