diff options
author | David S. Miller <davem@davemloft.net> | 2010-02-04 11:58:14 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-02-04 11:58:14 -0500 |
commit | 10be7eb36b93364b98688831ee7d26f58402bb96 (patch) | |
tree | eb13ae80fcaa8baacd804a721c5a4962a501a2a4 /drivers/net/wireless/b43 | |
parent | 90c30335a70e96b8b8493b7deb15e6b30e6d9fce (diff) | |
parent | 5ffaf8a361b4c9025963959a744f21d8173c7669 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'drivers/net/wireless/b43')
-rw-r--r-- | drivers/net/wireless/b43/main.c | 28 | ||||
-rw-r--r-- | drivers/net/wireless/b43/phy_common.c | 45 | ||||
-rw-r--r-- | drivers/net/wireless/b43/phy_common.h | 10 | ||||
-rw-r--r-- | drivers/net/wireless/b43/phy_lp.c | 52 | ||||
-rw-r--r-- | drivers/net/wireless/b43/phy_n.c | 1264 | ||||
-rw-r--r-- | drivers/net/wireless/b43/phy_n.h | 7 | ||||
-rw-r--r-- | drivers/net/wireless/b43/tables_nphy.c | 167 | ||||
-rw-r--r-- | drivers/net/wireless/b43/tables_nphy.h | 27 |
8 files changed, 1294 insertions, 306 deletions
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 9c5c7c9ad53..316a913860d 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -844,8 +844,10 @@ static void rx_tkip_phase1_write(struct b43_wldev *dev, u8 index, u32 iv32, | |||
844 | } | 844 | } |
845 | 845 | ||
846 | static void b43_op_update_tkip_key(struct ieee80211_hw *hw, | 846 | static void b43_op_update_tkip_key(struct ieee80211_hw *hw, |
847 | struct ieee80211_key_conf *keyconf, const u8 *addr, | 847 | struct ieee80211_vif *vif, |
848 | u32 iv32, u16 *phase1key) | 848 | struct ieee80211_key_conf *keyconf, |
849 | struct ieee80211_sta *sta, | ||
850 | u32 iv32, u16 *phase1key) | ||
849 | { | 851 | { |
850 | struct b43_wl *wl = hw_to_b43_wl(hw); | 852 | struct b43_wl *wl = hw_to_b43_wl(hw); |
851 | struct b43_wldev *dev; | 853 | struct b43_wldev *dev; |
@@ -854,19 +856,19 @@ static void b43_op_update_tkip_key(struct ieee80211_hw *hw, | |||
854 | if (B43_WARN_ON(!modparam_hwtkip)) | 856 | if (B43_WARN_ON(!modparam_hwtkip)) |
855 | return; | 857 | return; |
856 | 858 | ||
857 | mutex_lock(&wl->mutex); | 859 | /* This is only called from the RX path through mac80211, where |
858 | 860 | * our mutex is already locked. */ | |
861 | B43_WARN_ON(!mutex_is_locked(&wl->mutex)); | ||
859 | dev = wl->current_dev; | 862 | dev = wl->current_dev; |
860 | if (!dev || b43_status(dev) < B43_STAT_INITIALIZED) | 863 | B43_WARN_ON(!dev || b43_status(dev) < B43_STAT_INITIALIZED); |
861 | goto out_unlock; | ||
862 | 864 | ||
863 | keymac_write(dev, index, NULL); /* First zero out mac to avoid race */ | 865 | keymac_write(dev, index, NULL); /* First zero out mac to avoid race */ |
864 | 866 | ||
865 | rx_tkip_phase1_write(dev, index, iv32, phase1key); | 867 | rx_tkip_phase1_write(dev, index, iv32, phase1key); |
866 | keymac_write(dev, index, addr); | 868 | /* only pairwise TKIP keys are supported right now */ |
867 | 869 | if (WARN_ON(!sta)) | |
868 | out_unlock: | 870 | return; |
869 | mutex_unlock(&wl->mutex); | 871 | keymac_write(dev, index, sta->addr); |
870 | } | 872 | } |
871 | 873 | ||
872 | static void do_key_write(struct b43_wldev *dev, | 874 | static void do_key_write(struct b43_wldev *dev, |
@@ -3571,6 +3573,12 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed) | |||
3571 | dev = wl->current_dev; | 3573 | dev = wl->current_dev; |
3572 | phy = &dev->phy; | 3574 | phy = &dev->phy; |
3573 | 3575 | ||
3576 | if (conf_is_ht(conf)) | ||
3577 | phy->is_40mhz = | ||
3578 | (conf_is_ht40_minus(conf) || conf_is_ht40_plus(conf)); | ||
3579 | else | ||
3580 | phy->is_40mhz = false; | ||
3581 | |||
3574 | b43_mac_suspend(dev); | 3582 | b43_mac_suspend(dev); |
3575 | 3583 | ||
3576 | if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) | 3584 | if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) |
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c index 75b26e175e8..8f7d7eff2d8 100644 --- a/drivers/net/wireless/b43/phy_common.c +++ b/drivers/net/wireless/b43/phy_common.c | |||
@@ -421,3 +421,48 @@ void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on) | |||
421 | { | 421 | { |
422 | b43_write16(dev, B43_MMIO_PHY0, on ? 0 : 0xF4); | 422 | b43_write16(dev, B43_MMIO_PHY0, on ? 0 : 0xF4); |
423 | } | 423 | } |
424 | |||
425 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/Cordic */ | ||
426 | struct b43_c32 b43_cordic(int theta) | ||
427 | { | ||
428 | u32 arctg[] = { 2949120, 1740967, 919879, 466945, 234379, 117304, | ||
429 | 58666, 29335, 14668, 7334, 3667, 1833, 917, 458, | ||
430 | 229, 115, 57, 29, }; | ||
431 | u8 i; | ||
432 | s32 tmp; | ||
433 | s8 signx = 1; | ||
434 | u32 angle = 0; | ||
435 | struct b43_c32 ret = { .i = 39797, .q = 0, }; | ||
436 | |||
437 | while (theta > (180 << 16)) | ||
438 | theta -= (360 << 16); | ||
439 | while (theta < -(180 << 16)) | ||
440 | theta += (360 << 16); | ||
441 | |||
442 | if (theta > (90 << 16)) { | ||
443 | theta -= (180 << 16); | ||
444 | signx = -1; | ||
445 | } else if (theta < -(90 << 16)) { | ||
446 | theta += (180 << 16); | ||
447 | signx = -1; | ||
448 | } | ||
449 | |||
450 | for (i = 0; i <= 17; i++) { | ||
451 | if (theta > angle) { | ||
452 | tmp = ret.i - (ret.q >> i); | ||
453 | ret.q += ret.i >> i; | ||
454 | ret.i = tmp; | ||
455 | angle += arctg[i]; | ||
456 | } else { | ||
457 | tmp = ret.i + (ret.q >> i); | ||
458 | ret.q -= ret.i >> i; | ||
459 | ret.i = tmp; | ||
460 | angle -= arctg[i]; | ||
461 | } | ||
462 | } | ||
463 | |||
464 | ret.i *= signx; | ||
465 | ret.q *= signx; | ||
466 | |||
467 | return ret; | ||
468 | } | ||
diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h index 9edd4e8e0c8..bd480b481bf 100644 --- a/drivers/net/wireless/b43/phy_common.h +++ b/drivers/net/wireless/b43/phy_common.h | |||
@@ -5,6 +5,12 @@ | |||
5 | 5 | ||
6 | struct b43_wldev; | 6 | struct b43_wldev; |
7 | 7 | ||
8 | /* Complex number using 2 32-bit signed integers */ | ||
9 | struct b43_c32 { s32 i, q; }; | ||
10 | |||
11 | #define CORDIC_CONVERT(value) (((value) >= 0) ? \ | ||
12 | ((((value) >> 15) + 1) >> 1) : \ | ||
13 | -((((-(value)) >> 15) + 1) >> 1)) | ||
8 | 14 | ||
9 | /* PHY register routing bits */ | 15 | /* PHY register routing bits */ |
10 | #define B43_PHYROUTE 0x0C00 /* PHY register routing bits mask */ | 16 | #define B43_PHYROUTE 0x0C00 /* PHY register routing bits mask */ |
@@ -212,6 +218,9 @@ struct b43_phy { | |||
212 | bool supports_2ghz; | 218 | bool supports_2ghz; |
213 | bool supports_5ghz; | 219 | bool supports_5ghz; |
214 | 220 | ||
221 | /* HT info */ | ||
222 | bool is_40mhz; | ||
223 | |||
215 | /* GMODE bit enabled? */ | 224 | /* GMODE bit enabled? */ |
216 | bool gmode; | 225 | bool gmode; |
217 | 226 | ||
@@ -418,5 +427,6 @@ int b43_phy_shm_tssi_read(struct b43_wldev *dev, u16 shm_offset); | |||
418 | */ | 427 | */ |
419 | void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on); | 428 | void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on); |
420 | 429 | ||
430 | struct b43_c32 b43_cordic(int theta); | ||
421 | 431 | ||
422 | #endif /* LINUX_B43_PHY_COMMON_H_ */ | 432 | #endif /* LINUX_B43_PHY_COMMON_H_ */ |
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c index b58d6cf2658..185219e0a55 100644 --- a/drivers/net/wireless/b43/phy_lp.c +++ b/drivers/net/wireless/b43/phy_lp.c | |||
@@ -1767,47 +1767,6 @@ out: | |||
1767 | return ret; | 1767 | return ret; |
1768 | } | 1768 | } |
1769 | 1769 | ||
1770 | /* Complex number using 2 32-bit signed integers */ | ||
1771 | typedef struct {s32 i, q;} lpphy_c32; | ||
1772 | |||
1773 | static lpphy_c32 lpphy_cordic(int theta) | ||
1774 | { | ||
1775 | u32 arctg[] = { 2949120, 1740967, 919879, 466945, 234379, 117304, | ||
1776 | 58666, 29335, 14668, 7334, 3667, 1833, 917, 458, | ||
1777 | 229, 115, 57, 29, }; | ||
1778 | int i, tmp, signx = 1, angle = 0; | ||
1779 | lpphy_c32 ret = { .i = 39797, .q = 0, }; | ||
1780 | |||
1781 | theta = clamp_t(int, theta, -180, 180); | ||
1782 | |||
1783 | if (theta > 90) { | ||
1784 | theta -= 180; | ||
1785 | signx = -1; | ||
1786 | } else if (theta < -90) { | ||
1787 | theta += 180; | ||
1788 | signx = -1; | ||
1789 | } | ||
1790 | |||
1791 | for (i = 0; i <= 17; i++) { | ||
1792 | if (theta > angle) { | ||
1793 | tmp = ret.i - (ret.q >> i); | ||
1794 | ret.q += ret.i >> i; | ||
1795 | ret.i = tmp; | ||
1796 | angle += arctg[i]; | ||
1797 | } else { | ||
1798 | tmp = ret.i + (ret.q >> i); | ||
1799 | ret.q -= ret.i >> i; | ||
1800 | ret.i = tmp; | ||
1801 | angle -= arctg[i]; | ||
1802 | } | ||
1803 | } | ||
1804 | |||
1805 | ret.i *= signx; | ||
1806 | ret.q *= signx; | ||
1807 | |||
1808 | return ret; | ||
1809 | } | ||
1810 | |||
1811 | static void lpphy_run_samples(struct b43_wldev *dev, u16 samples, u16 loops, | 1770 | static void lpphy_run_samples(struct b43_wldev *dev, u16 samples, u16 loops, |
1812 | u16 wait) | 1771 | u16 wait) |
1813 | { | 1772 | { |
@@ -1825,8 +1784,9 @@ static void lpphy_start_tx_tone(struct b43_wldev *dev, s32 freq, u16 max) | |||
1825 | { | 1784 | { |
1826 | struct b43_phy_lp *lpphy = dev->phy.lp; | 1785 | struct b43_phy_lp *lpphy = dev->phy.lp; |
1827 | u16 buf[64]; | 1786 | u16 buf[64]; |
1828 | int i, samples = 0, angle = 0, rotation = (9 * freq) / 500; | 1787 | int i, samples = 0, angle = 0; |
1829 | lpphy_c32 sample; | 1788 | int rotation = (((36 * freq) / 20) << 16) / 100; |
1789 | struct b43_c32 sample; | ||
1830 | 1790 | ||
1831 | lpphy->tx_tone_freq = freq; | 1791 | lpphy->tx_tone_freq = freq; |
1832 | 1792 | ||
@@ -1842,10 +1802,10 @@ static void lpphy_start_tx_tone(struct b43_wldev *dev, s32 freq, u16 max) | |||
1842 | } | 1802 | } |
1843 | 1803 | ||
1844 | for (i = 0; i < samples; i++) { | 1804 | for (i = 0; i < samples; i++) { |
1845 | sample = lpphy_cordic(angle); | 1805 | sample = b43_cordic(angle); |
1846 | angle += rotation; | 1806 | angle += rotation; |
1847 | buf[i] = ((sample.i * max) & 0xFF) << 8; | 1807 | buf[i] = CORDIC_CONVERT((sample.i * max) & 0xFF) << 8; |
1848 | buf[i] |= (sample.q * max) & 0xFF; | 1808 | buf[i] |= CORDIC_CONVERT((sample.q * max) & 0xFF); |
1849 | } | 1809 | } |
1850 | 1810 | ||
1851 | b43_lptab_write_bulk(dev, B43_LPTAB16(5, 0), samples, buf); | 1811 | b43_lptab_write_bulk(dev, B43_LPTAB16(5, 0), samples, buf); |
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 4a817e3da16..6392da25efe 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c | |||
@@ -55,6 +55,20 @@ struct nphy_iq_est { | |||
55 | u32 q1_pwr; | 55 | u32 q1_pwr; |
56 | }; | 56 | }; |
57 | 57 | ||
58 | enum b43_nphy_rf_sequence { | ||
59 | B43_RFSEQ_RX2TX, | ||
60 | B43_RFSEQ_TX2RX, | ||
61 | B43_RFSEQ_RESET2RX, | ||
62 | B43_RFSEQ_UPDATE_GAINH, | ||
63 | B43_RFSEQ_UPDATE_GAINL, | ||
64 | B43_RFSEQ_UPDATE_GAINU, | ||
65 | }; | ||
66 | |||
67 | static void b43_nphy_set_rf_sequence(struct b43_wldev *dev, u8 cmd, | ||
68 | u8 *events, u8 *delays, u8 length); | ||
69 | static void b43_nphy_force_rf_sequence(struct b43_wldev *dev, | ||
70 | enum b43_nphy_rf_sequence seq); | ||
71 | |||
58 | void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna) | 72 | void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna) |
59 | {//TODO | 73 | {//TODO |
60 | } | 74 | } |
@@ -234,110 +248,6 @@ static void b43_nphy_tables_init(struct b43_wldev *dev) | |||
234 | b43_nphy_rev3plus_tables_init(dev); | 248 | b43_nphy_rev3plus_tables_init(dev); |
235 | } | 249 | } |
236 | 250 | ||
237 | static void b43_nphy_workarounds(struct b43_wldev *dev) | ||
238 | { | ||
239 | struct b43_phy *phy = &dev->phy; | ||
240 | unsigned int i; | ||
241 | |||
242 | b43_phy_set(dev, B43_NPHY_IQFLIP, | ||
243 | B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2); | ||
244 | if (1 /* FIXME band is 2.4GHz */) { | ||
245 | b43_phy_set(dev, B43_NPHY_CLASSCTL, | ||
246 | B43_NPHY_CLASSCTL_CCKEN); | ||
247 | } else { | ||
248 | b43_phy_mask(dev, B43_NPHY_CLASSCTL, | ||
249 | ~B43_NPHY_CLASSCTL_CCKEN); | ||
250 | } | ||
251 | b43_radio_set(dev, B2055_C1_TX_RF_SPARE, 0x8); | ||
252 | b43_phy_write(dev, B43_NPHY_TXFRAMEDELAY, 8); | ||
253 | |||
254 | /* Fixup some tables */ | ||
255 | b43_ntab_write(dev, B43_NTAB16(8, 0x00), 0xA); | ||
256 | b43_ntab_write(dev, B43_NTAB16(8, 0x10), 0xA); | ||
257 | b43_ntab_write(dev, B43_NTAB16(8, 0x02), 0xCDAA); | ||
258 | b43_ntab_write(dev, B43_NTAB16(8, 0x12), 0xCDAA); | ||
259 | b43_ntab_write(dev, B43_NTAB16(8, 0x08), 0); | ||
260 | b43_ntab_write(dev, B43_NTAB16(8, 0x18), 0); | ||
261 | b43_ntab_write(dev, B43_NTAB16(8, 0x07), 0x7AAB); | ||
262 | b43_ntab_write(dev, B43_NTAB16(8, 0x17), 0x7AAB); | ||
263 | b43_ntab_write(dev, B43_NTAB16(8, 0x06), 0x800); | ||
264 | b43_ntab_write(dev, B43_NTAB16(8, 0x16), 0x800); | ||
265 | |||
266 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8); | ||
267 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0x301); | ||
268 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8); | ||
269 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301); | ||
270 | |||
271 | //TODO set RF sequence | ||
272 | |||
273 | /* Set narrowband clip threshold */ | ||
274 | b43_phy_write(dev, B43_NPHY_C1_NBCLIPTHRES, 66); | ||
275 | b43_phy_write(dev, B43_NPHY_C2_NBCLIPTHRES, 66); | ||
276 | |||
277 | /* Set wideband clip 2 threshold */ | ||
278 | b43_phy_maskset(dev, B43_NPHY_C1_CLIPWBTHRES, | ||
279 | ~B43_NPHY_C1_CLIPWBTHRES_CLIP2, | ||
280 | 21 << B43_NPHY_C1_CLIPWBTHRES_CLIP2_SHIFT); | ||
281 | b43_phy_maskset(dev, B43_NPHY_C2_CLIPWBTHRES, | ||
282 | ~B43_NPHY_C2_CLIPWBTHRES_CLIP2, | ||
283 | 21 << B43_NPHY_C2_CLIPWBTHRES_CLIP2_SHIFT); | ||
284 | |||
285 | /* Set Clip 2 detect */ | ||
286 | b43_phy_set(dev, B43_NPHY_C1_CGAINI, | ||
287 | B43_NPHY_C1_CGAINI_CL2DETECT); | ||
288 | b43_phy_set(dev, B43_NPHY_C2_CGAINI, | ||
289 | B43_NPHY_C2_CGAINI_CL2DETECT); | ||
290 | |||
291 | if (0 /*FIXME*/) { | ||
292 | /* Set dwell lengths */ | ||
293 | b43_phy_write(dev, B43_NPHY_CLIP1_NBDWELL_LEN, 43); | ||
294 | b43_phy_write(dev, B43_NPHY_CLIP2_NBDWELL_LEN, 43); | ||
295 | b43_phy_write(dev, B43_NPHY_W1CLIP1_DWELL_LEN, 9); | ||
296 | b43_phy_write(dev, B43_NPHY_W1CLIP2_DWELL_LEN, 9); | ||
297 | |||
298 | /* Set gain backoff */ | ||
299 | b43_phy_maskset(dev, B43_NPHY_C1_CGAINI, | ||
300 | ~B43_NPHY_C1_CGAINI_GAINBKOFF, | ||
301 | 1 << B43_NPHY_C1_CGAINI_GAINBKOFF_SHIFT); | ||
302 | b43_phy_maskset(dev, B43_NPHY_C2_CGAINI, | ||
303 | ~B43_NPHY_C2_CGAINI_GAINBKOFF, | ||
304 | 1 << B43_NPHY_C2_CGAINI_GAINBKOFF_SHIFT); | ||
305 | |||
306 | /* Set HPVGA2 index */ | ||
307 | b43_phy_maskset(dev, B43_NPHY_C1_INITGAIN, | ||
308 | ~B43_NPHY_C1_INITGAIN_HPVGA2, | ||
309 | 6 << B43_NPHY_C1_INITGAIN_HPVGA2_SHIFT); | ||
310 | b43_phy_maskset(dev, B43_NPHY_C2_INITGAIN, | ||
311 | ~B43_NPHY_C2_INITGAIN_HPVGA2, | ||
312 | 6 << B43_NPHY_C2_INITGAIN_HPVGA2_SHIFT); | ||
313 | |||
314 | //FIXME verify that the specs really mean to use autoinc here. | ||
315 | for (i = 0; i < 3; i++) | ||
316 | b43_ntab_write(dev, B43_NTAB16(7, 0x106) + i, 0x673); | ||
317 | } | ||
318 | |||
319 | /* Set minimum gain value */ | ||
320 | b43_phy_maskset(dev, B43_NPHY_C1_MINMAX_GAIN, | ||
321 | ~B43_NPHY_C1_MINGAIN, | ||
322 | 23 << B43_NPHY_C1_MINGAIN_SHIFT); | ||
323 | b43_phy_maskset(dev, B43_NPHY_C2_MINMAX_GAIN, | ||
324 | ~B43_NPHY_C2_MINGAIN, | ||
325 | 23 << B43_NPHY_C2_MINGAIN_SHIFT); | ||
326 | |||
327 | if (phy->rev < 2) { | ||
328 | b43_phy_mask(dev, B43_NPHY_SCRAM_SIGCTL, | ||
329 | ~B43_NPHY_SCRAM_SIGCTL_SCM); | ||
330 | } | ||
331 | |||
332 | /* Set phase track alpha and beta */ | ||
333 | b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x125); | ||
334 | b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x1B3); | ||
335 | b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x105); | ||
336 | b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x16E); | ||
337 | b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0xCD); | ||
338 | b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x20); | ||
339 | } | ||
340 | |||
341 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/PA%20override */ | 251 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/PA%20override */ |
342 | static void b43_nphy_pa_override(struct b43_wldev *dev, bool enable) | 252 | static void b43_nphy_pa_override(struct b43_wldev *dev, bool enable) |
343 | { | 253 | { |
@@ -421,7 +331,49 @@ static void b43_nphy_reset_cca(struct b43_wldev *dev) | |||
421 | udelay(1); | 331 | udelay(1); |
422 | b43_phy_write(dev, B43_NPHY_BBCFG, bbcfg & ~B43_NPHY_BBCFG_RSTCCA); | 332 | b43_phy_write(dev, B43_NPHY_BBCFG, bbcfg & ~B43_NPHY_BBCFG_RSTCCA); |
423 | b43_nphy_bmac_clock_fgc(dev, 0); | 333 | b43_nphy_bmac_clock_fgc(dev, 0); |
424 | /* TODO: N PHY Force RF Seq with argument 2 */ | 334 | b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); |
335 | } | ||
336 | |||
337 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MIMOConfig */ | ||
338 | static void b43_nphy_update_mimo_config(struct b43_wldev *dev, s32 preamble) | ||
339 | { | ||
340 | u16 mimocfg = b43_phy_read(dev, B43_NPHY_MIMOCFG); | ||
341 | |||
342 | mimocfg |= B43_NPHY_MIMOCFG_AUTO; | ||
343 | if (preamble == 1) | ||
344 | mimocfg |= B43_NPHY_MIMOCFG_GFMIX; | ||
345 | else | ||
346 | mimocfg &= ~B43_NPHY_MIMOCFG_GFMIX; | ||
347 | |||
348 | b43_phy_write(dev, B43_NPHY_MIMOCFG, mimocfg); | ||
349 | } | ||
350 | |||
351 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Chains */ | ||
352 | static void b43_nphy_update_txrx_chain(struct b43_wldev *dev) | ||
353 | { | ||
354 | struct b43_phy_n *nphy = dev->phy.n; | ||
355 | |||
356 | bool override = false; | ||
357 | u16 chain = 0x33; | ||
358 | |||
359 | if (nphy->txrx_chain == 0) { | ||
360 | chain = 0x11; | ||
361 | override = true; | ||
362 | } else if (nphy->txrx_chain == 1) { | ||
363 | chain = 0x22; | ||
364 | override = true; | ||
365 | } | ||
366 | |||
367 | b43_phy_maskset(dev, B43_NPHY_RFSEQCA, | ||
368 | ~(B43_NPHY_RFSEQCA_TXEN | B43_NPHY_RFSEQCA_RXEN), | ||
369 | chain); | ||
370 | |||
371 | if (override) | ||
372 | b43_phy_set(dev, B43_NPHY_RFSEQMODE, | ||
373 | B43_NPHY_RFSEQMODE_CAOVER); | ||
374 | else | ||
375 | b43_phy_mask(dev, B43_NPHY_RFSEQMODE, | ||
376 | ~B43_NPHY_RFSEQMODE_CAOVER); | ||
425 | } | 377 | } |
426 | 378 | ||
427 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxIqEst */ | 379 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxIqEst */ |
@@ -480,6 +432,88 @@ static void b43_nphy_rx_iq_coeffs(struct b43_wldev *dev, bool write, | |||
480 | } | 432 | } |
481 | } | 433 | } |
482 | 434 | ||
435 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCalPhyCleanup */ | ||
436 | static void b43_nphy_rx_cal_phy_cleanup(struct b43_wldev *dev, u8 core) | ||
437 | { | ||
438 | u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs; | ||
439 | |||
440 | b43_phy_write(dev, B43_NPHY_RFSEQCA, regs[0]); | ||
441 | if (core == 0) { | ||
442 | b43_phy_write(dev, B43_NPHY_AFECTL_C1, regs[1]); | ||
443 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, regs[2]); | ||
444 | } else { | ||
445 | b43_phy_write(dev, B43_NPHY_AFECTL_C2, regs[1]); | ||
446 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER, regs[2]); | ||
447 | } | ||
448 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs[3]); | ||
449 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs[4]); | ||
450 | b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO1, regs[5]); | ||
451 | b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO2, regs[6]); | ||
452 | b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S1, regs[7]); | ||
453 | b43_phy_write(dev, B43_NPHY_RFCTL_OVER, regs[8]); | ||
454 | b43_phy_write(dev, B43_NPHY_PAPD_EN0, regs[9]); | ||
455 | b43_phy_write(dev, B43_NPHY_PAPD_EN1, regs[10]); | ||
456 | } | ||
457 | |||
458 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCalPhySetup */ | ||
459 | static void b43_nphy_rx_cal_phy_setup(struct b43_wldev *dev, u8 core) | ||
460 | { | ||
461 | u8 rxval, txval; | ||
462 | u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs; | ||
463 | |||
464 | regs[0] = b43_phy_read(dev, B43_NPHY_RFSEQCA); | ||
465 | if (core == 0) { | ||
466 | regs[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C1); | ||
467 | regs[2] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER1); | ||
468 | } else { | ||
469 | regs[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2); | ||
470 | regs[2] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER); | ||
471 | } | ||
472 | regs[3] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1); | ||
473 | regs[4] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2); | ||
474 | regs[5] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO1); | ||
475 | regs[6] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO2); | ||
476 | regs[7] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S1); | ||
477 | regs[8] = b43_phy_read(dev, B43_NPHY_RFCTL_OVER); | ||
478 | regs[9] = b43_phy_read(dev, B43_NPHY_PAPD_EN0); | ||
479 | regs[10] = b43_phy_read(dev, B43_NPHY_PAPD_EN1); | ||
480 | |||
481 | b43_phy_mask(dev, B43_NPHY_PAPD_EN0, ~0x0001); | ||
482 | b43_phy_mask(dev, B43_NPHY_PAPD_EN1, ~0x0001); | ||
483 | |||
484 | b43_phy_maskset(dev, B43_NPHY_RFSEQCA, (u16)~B43_NPHY_RFSEQCA_RXDIS, | ||
485 | ((1 - core) << B43_NPHY_RFSEQCA_RXDIS_SHIFT)); | ||
486 | b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_TXEN, | ||
487 | ((1 - core) << B43_NPHY_RFSEQCA_TXEN_SHIFT)); | ||
488 | b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_RXEN, | ||
489 | (core << B43_NPHY_RFSEQCA_RXEN_SHIFT)); | ||
490 | b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_TXDIS, | ||
491 | (core << B43_NPHY_RFSEQCA_TXDIS_SHIFT)); | ||
492 | |||
493 | if (core == 0) { | ||
494 | b43_phy_mask(dev, B43_NPHY_AFECTL_C1, ~0x0007); | ||
495 | b43_phy_set(dev, B43_NPHY_AFECTL_OVER1, 0x0007); | ||
496 | } else { | ||
497 | b43_phy_mask(dev, B43_NPHY_AFECTL_C2, ~0x0007); | ||
498 | b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x0007); | ||
499 | } | ||
500 | |||
501 | /* TODO: Call N PHY RF Ctrl Intc Override with 2, 0, 3 as arguments */ | ||
502 | /* TODO: Call N PHY RF Intc Override with 8, 0, 3, 0 as arguments */ | ||
503 | b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX); | ||
504 | |||
505 | if (core == 0) { | ||
506 | rxval = 1; | ||
507 | txval = 8; | ||
508 | } else { | ||
509 | rxval = 4; | ||
510 | txval = 2; | ||
511 | } | ||
512 | |||
513 | /* TODO: Call N PHY RF Ctrl Intc Override with 1, rxval, (core + 1) */ | ||
514 | /* TODO: Call N PHY RF Ctrl Intc Override with 1, txval, (2 - core) */ | ||
515 | } | ||
516 | |||
483 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalcRxIqComp */ | 517 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalcRxIqComp */ |
484 | static void b43_nphy_calc_rx_iq_comp(struct b43_wldev *dev, u8 mask) | 518 | static void b43_nphy_calc_rx_iq_comp(struct b43_wldev *dev, u8 mask) |
485 | { | 519 | { |
@@ -653,6 +687,386 @@ static void b43_nphy_stay_in_carrier_search(struct b43_wldev *dev, bool enable) | |||
653 | } | 687 | } |
654 | } | 688 | } |
655 | 689 | ||
690 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/stop-playback */ | ||
691 | static void b43_nphy_stop_playback(struct b43_wldev *dev) | ||
692 | { | ||
693 | struct b43_phy_n *nphy = dev->phy.n; | ||
694 | u16 tmp; | ||
695 | |||
696 | if (nphy->hang_avoid) | ||
697 | b43_nphy_stay_in_carrier_search(dev, 1); | ||
698 | |||
699 | tmp = b43_phy_read(dev, B43_NPHY_SAMP_STAT); | ||
700 | if (tmp & 0x1) | ||
701 | b43_phy_set(dev, B43_NPHY_SAMP_CMD, B43_NPHY_SAMP_CMD_STOP); | ||
702 | else if (tmp & 0x2) | ||
703 | b43_phy_mask(dev, B43_NPHY_IQLOCAL_CMDGCTL, (u16)~0x8000); | ||
704 | |||
705 | b43_phy_mask(dev, B43_NPHY_SAMP_CMD, ~0x0004); | ||
706 | |||
707 | if (nphy->bb_mult_save & 0x80000000) { | ||
708 | tmp = nphy->bb_mult_save & 0xFFFF; | ||
709 | b43_ntab_write(dev, B43_NTAB16(15, 87), tmp); | ||
710 | nphy->bb_mult_save = 0; | ||
711 | } | ||
712 | |||
713 | if (nphy->hang_avoid) | ||
714 | b43_nphy_stay_in_carrier_search(dev, 0); | ||
715 | } | ||
716 | |||
717 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */ | ||
718 | static void b43_nphy_gain_crtl_workarounds(struct b43_wldev *dev) | ||
719 | { | ||
720 | struct b43_phy_n *nphy = dev->phy.n; | ||
721 | u8 i, j; | ||
722 | u8 code; | ||
723 | |||
724 | /* TODO: for PHY >= 3 | ||
725 | s8 *lna1_gain, *lna2_gain; | ||
726 | u8 *gain_db, *gain_bits; | ||
727 | u16 *rfseq_init; | ||
728 | u8 lpf_gain[6] = { 0x00, 0x06, 0x0C, 0x12, 0x12, 0x12 }; | ||
729 | u8 lpf_bits[6] = { 0, 1, 2, 3, 3, 3 }; | ||
730 | */ | ||
731 | |||
732 | u8 rfseq_events[3] = { 6, 8, 7 }; | ||
733 | u8 rfseq_delays[3] = { 10, 30, 1 }; | ||
734 | |||
735 | if (dev->phy.rev >= 3) { | ||
736 | /* TODO */ | ||
737 | } else { | ||
738 | /* Set Clip 2 detect */ | ||
739 | b43_phy_set(dev, B43_NPHY_C1_CGAINI, | ||
740 | B43_NPHY_C1_CGAINI_CL2DETECT); | ||
741 | b43_phy_set(dev, B43_NPHY_C2_CGAINI, | ||
742 | B43_NPHY_C2_CGAINI_CL2DETECT); | ||
743 | |||
744 | /* Set narrowband clip threshold */ | ||
745 | b43_phy_set(dev, B43_NPHY_C1_NBCLIPTHRES, 0x84); | ||
746 | b43_phy_set(dev, B43_NPHY_C2_NBCLIPTHRES, 0x84); | ||
747 | |||
748 | if (!dev->phy.is_40mhz) { | ||
749 | /* Set dwell lengths */ | ||
750 | b43_phy_set(dev, B43_NPHY_CLIP1_NBDWELL_LEN, 0x002B); | ||
751 | b43_phy_set(dev, B43_NPHY_CLIP2_NBDWELL_LEN, 0x002B); | ||
752 | b43_phy_set(dev, B43_NPHY_W1CLIP1_DWELL_LEN, 0x0009); | ||
753 | b43_phy_set(dev, B43_NPHY_W1CLIP2_DWELL_LEN, 0x0009); | ||
754 | } | ||
755 | |||
756 | /* Set wideband clip 2 threshold */ | ||
757 | b43_phy_maskset(dev, B43_NPHY_C1_CLIPWBTHRES, | ||
758 | ~B43_NPHY_C1_CLIPWBTHRES_CLIP2, | ||
759 | 21); | ||
760 | b43_phy_maskset(dev, B43_NPHY_C2_CLIPWBTHRES, | ||
761 | ~B43_NPHY_C2_CLIPWBTHRES_CLIP2, | ||
762 | 21); | ||
763 | |||
764 | if (!dev->phy.is_40mhz) { | ||
765 | b43_phy_maskset(dev, B43_NPHY_C1_CGAINI, | ||
766 | ~B43_NPHY_C1_CGAINI_GAINBKOFF, 0x1); | ||
767 | b43_phy_maskset(dev, B43_NPHY_C2_CGAINI, | ||
768 | ~B43_NPHY_C2_CGAINI_GAINBKOFF, 0x1); | ||
769 | b43_phy_maskset(dev, B43_NPHY_C1_CCK_CGAINI, | ||
770 | ~B43_NPHY_C1_CCK_CGAINI_GAINBKOFF, 0x1); | ||
771 | b43_phy_maskset(dev, B43_NPHY_C2_CCK_CGAINI, | ||
772 | ~B43_NPHY_C2_CCK_CGAINI_GAINBKOFF, 0x1); | ||
773 | } | ||
774 | |||
775 | b43_phy_set(dev, B43_NPHY_CCK_SHIFTB_REF, 0x809C); | ||
776 | |||
777 | if (nphy->gain_boost) { | ||
778 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ && | ||
779 | dev->phy.is_40mhz) | ||
780 | code = 4; | ||
781 | else | ||
782 | code = 5; | ||
783 | } else { | ||
784 | code = dev->phy.is_40mhz ? 6 : 7; | ||
785 | } | ||
786 | |||
787 | /* Set HPVGA2 index */ | ||
788 | b43_phy_maskset(dev, B43_NPHY_C1_INITGAIN, | ||
789 | ~B43_NPHY_C1_INITGAIN_HPVGA2, | ||
790 | code << B43_NPHY_C1_INITGAIN_HPVGA2_SHIFT); | ||
791 | b43_phy_maskset(dev, B43_NPHY_C2_INITGAIN, | ||
792 | ~B43_NPHY_C2_INITGAIN_HPVGA2, | ||
793 | code << B43_NPHY_C2_INITGAIN_HPVGA2_SHIFT); | ||
794 | |||
795 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D06); | ||
796 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, | ||
797 | (code << 8 | 0x7C)); | ||
798 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, | ||
799 | (code << 8 | 0x7C)); | ||
800 | |||
801 | /* TODO: b43_nphy_adjust_lna_gain_table(dev); */ | ||
802 | |||
803 | if (nphy->elna_gain_config) { | ||
804 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x0808); | ||
805 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0); | ||
806 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1); | ||
807 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1); | ||
808 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1); | ||
809 | |||
810 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x0C08); | ||
811 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0); | ||
812 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1); | ||
813 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1); | ||
814 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1); | ||
815 | |||
816 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D06); | ||
817 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, | ||
818 | (code << 8 | 0x74)); | ||
819 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, | ||
820 | (code << 8 | 0x74)); | ||
821 | } | ||
822 | |||
823 | if (dev->phy.rev == 2) { | ||
824 | for (i = 0; i < 4; i++) { | ||
825 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, | ||
826 | (0x0400 * i) + 0x0020); | ||
827 | for (j = 0; j < 21; j++) | ||
828 | b43_phy_write(dev, | ||
829 | B43_NPHY_TABLE_DATALO, 3 * j); | ||
830 | } | ||
831 | |||
832 | b43_nphy_set_rf_sequence(dev, 5, | ||
833 | rfseq_events, rfseq_delays, 3); | ||
834 | b43_phy_maskset(dev, B43_NPHY_OVER_DGAIN1, | ||
835 | (u16)~B43_NPHY_OVER_DGAIN_CCKDGECV, | ||
836 | 0x5A << B43_NPHY_OVER_DGAIN_CCKDGECV_SHIFT); | ||
837 | |||
838 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) | ||
839 | b43_phy_maskset(dev, B43_PHY_N(0xC5D), | ||
840 | 0xFF80, 4); | ||
841 | } | ||
842 | } | ||
843 | } | ||
844 | |||
845 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Workarounds */ | ||
846 | static void b43_nphy_workarounds(struct b43_wldev *dev) | ||
847 | { | ||
848 | struct ssb_bus *bus = dev->dev->bus; | ||
849 | struct b43_phy *phy = &dev->phy; | ||
850 | struct b43_phy_n *nphy = phy->n; | ||
851 | |||
852 | u8 events1[7] = { 0x0, 0x1, 0x2, 0x8, 0x4, 0x5, 0x3 }; | ||
853 | u8 delays1[7] = { 0x8, 0x6, 0x6, 0x2, 0x4, 0x3C, 0x1 }; | ||
854 | |||
855 | u8 events2[7] = { 0x0, 0x3, 0x5, 0x4, 0x2, 0x1, 0x8 }; | ||
856 | u8 delays2[7] = { 0x8, 0x6, 0x2, 0x4, 0x4, 0x6, 0x1 }; | ||
857 | |||
858 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) | ||
859 | b43_nphy_classifier(dev, 1, 0); | ||
860 | else | ||
861 | b43_nphy_classifier(dev, 1, 1); | ||
862 | |||
863 | if (nphy->hang_avoid) | ||
864 | b43_nphy_stay_in_carrier_search(dev, 1); | ||
865 | |||
866 | b43_phy_set(dev, B43_NPHY_IQFLIP, | ||
867 | B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2); | ||
868 | |||
869 | if (dev->phy.rev >= 3) { | ||
870 | /* TODO */ | ||
871 | } else { | ||
872 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ && | ||
873 | nphy->band5g_pwrgain) { | ||
874 | b43_radio_mask(dev, B2055_C1_TX_RF_SPARE, ~0x8); | ||
875 | b43_radio_mask(dev, B2055_C2_TX_RF_SPARE, ~0x8); | ||
876 | } else { | ||
877 | b43_radio_set(dev, B2055_C1_TX_RF_SPARE, 0x8); | ||
878 | b43_radio_set(dev, B2055_C2_TX_RF_SPARE, 0x8); | ||
879 | } | ||
880 | |||
881 | /* TODO: convert to b43_ntab_write? */ | ||
882 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2000); | ||
883 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x000A); | ||
884 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2010); | ||
885 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x000A); | ||
886 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2002); | ||
887 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0xCDAA); | ||
888 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2012); | ||
889 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0xCDAA); | ||
890 | |||
891 | if (dev->phy.rev < 2) { | ||
892 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2008); | ||
893 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0000); | ||
894 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2018); | ||
895 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0000); | ||
896 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2007); | ||
897 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x7AAB); | ||
898 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2017); | ||
899 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x7AAB); | ||
900 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2006); | ||
901 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0800); | ||
902 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2016); | ||
903 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0800); | ||
904 | } | ||
905 | |||
906 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8); | ||
907 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0x301); | ||
908 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8); | ||
909 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301); | ||
910 | |||
911 | if (bus->sprom.boardflags2_lo & 0x100 && | ||
912 | bus->boardinfo.type == 0x8B) { | ||
913 | delays1[0] = 0x1; | ||
914 | delays1[5] = 0x14; | ||
915 | } | ||
916 | b43_nphy_set_rf_sequence(dev, 0, events1, delays1, 7); | ||
917 | b43_nphy_set_rf_sequence(dev, 1, events2, delays2, 7); | ||
918 | |||
919 | b43_nphy_gain_crtl_workarounds(dev); | ||
920 | |||
921 | if (dev->phy.rev < 2) { | ||
922 | if (b43_phy_read(dev, B43_NPHY_RXCTL) & 0x2) | ||
923 | ; /*TODO: b43_mhf(dev, 2, 0x0010, 0x0010, 3);*/ | ||
924 | } else if (dev->phy.rev == 2) { | ||
925 | b43_phy_write(dev, B43_NPHY_CRSCHECK2, 0); | ||
926 | b43_phy_write(dev, B43_NPHY_CRSCHECK3, 0); | ||
927 | } | ||
928 | |||
929 | if (dev->phy.rev < 2) | ||
930 | b43_phy_mask(dev, B43_NPHY_SCRAM_SIGCTL, | ||
931 | ~B43_NPHY_SCRAM_SIGCTL_SCM); | ||
932 | |||
933 | /* Set phase track alpha and beta */ | ||
934 | b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x125); | ||
935 | b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x1B3); | ||
936 | b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x105); | ||
937 | b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x16E); | ||
938 | b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0xCD); | ||
939 | b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x20); | ||
940 | |||
941 | b43_phy_mask(dev, B43_NPHY_PIL_DW1, | ||
942 | (u16)~B43_NPHY_PIL_DW_64QAM); | ||
943 | b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B1, 0xB5); | ||
944 | b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B2, 0xA4); | ||
945 | b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B3, 0x00); | ||
946 | |||
947 | if (dev->phy.rev == 2) | ||
948 | b43_phy_set(dev, B43_NPHY_FINERX2_CGC, | ||
949 | B43_NPHY_FINERX2_CGC_DECGC); | ||
950 | } | ||
951 | |||
952 | if (nphy->hang_avoid) | ||
953 | b43_nphy_stay_in_carrier_search(dev, 0); | ||
954 | } | ||
955 | |||
956 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GenLoadSamples */ | ||
957 | static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max, | ||
958 | bool test) | ||
959 | { | ||
960 | int i; | ||
961 | u16 bw, len, rot, angle; | ||
962 | struct b43_c32 *samples; | ||
963 | |||
964 | |||
965 | bw = (dev->phy.is_40mhz) ? 40 : 20; | ||
966 | len = bw << 3; | ||
967 | |||
968 | if (test) { | ||
969 | if (b43_phy_read(dev, B43_NPHY_BBCFG) & B43_NPHY_BBCFG_RSTRX) | ||
970 | bw = 82; | ||
971 | else | ||
972 | bw = 80; | ||
973 | |||
974 | if (dev->phy.is_40mhz) | ||
975 | bw <<= 1; | ||
976 | |||
977 | len = bw << 1; | ||
978 | } | ||
979 | |||
980 | samples = kzalloc(len * sizeof(struct b43_c32), GFP_KERNEL); | ||
981 | rot = (((freq * 36) / bw) << 16) / 100; | ||
982 | angle = 0; | ||
983 | |||
984 | for (i = 0; i < len; i++) { | ||
985 | samples[i] = b43_cordic(angle); | ||
986 | angle += rot; | ||
987 | samples[i].q = CORDIC_CONVERT(samples[i].q * max); | ||
988 | samples[i].i = CORDIC_CONVERT(samples[i].i * max); | ||
989 | } | ||
990 | |||
991 | /* TODO: Call N PHY Load Sample Table with buffer, len as arguments */ | ||
992 | kfree(samples); | ||
993 | return len; | ||
994 | } | ||
995 | |||
996 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RunSamples */ | ||
997 | static void b43_nphy_run_samples(struct b43_wldev *dev, u16 samps, u16 loops, | ||
998 | u16 wait, bool iqmode, bool dac_test) | ||
999 | { | ||
1000 | struct b43_phy_n *nphy = dev->phy.n; | ||
1001 | int i; | ||
1002 | u16 seq_mode; | ||
1003 | u32 tmp; | ||
1004 | |||
1005 | if (nphy->hang_avoid) | ||
1006 | b43_nphy_stay_in_carrier_search(dev, true); | ||
1007 | |||
1008 | if ((nphy->bb_mult_save & 0x80000000) == 0) { | ||
1009 | tmp = b43_ntab_read(dev, B43_NTAB16(15, 87)); | ||
1010 | nphy->bb_mult_save = (tmp & 0xFFFF) | 0x80000000; | ||
1011 | } | ||
1012 | |||
1013 | if (!dev->phy.is_40mhz) | ||
1014 | tmp = 0x6464; | ||
1015 | else | ||
1016 | tmp = 0x4747; | ||
1017 | b43_ntab_write(dev, B43_NTAB16(15, 87), tmp); | ||
1018 | |||
1019 | if (nphy->hang_avoid) | ||
1020 | b43_nphy_stay_in_carrier_search(dev, false); | ||
1021 | |||
1022 | b43_phy_write(dev, B43_NPHY_SAMP_DEPCNT, (samps - 1)); | ||
1023 | |||
1024 | if (loops != 0xFFFF) | ||
1025 | b43_phy_write(dev, B43_NPHY_SAMP_LOOPCNT, (loops - 1)); | ||
1026 | else | ||
1027 | b43_phy_write(dev, B43_NPHY_SAMP_LOOPCNT, loops); | ||
1028 | |||
1029 | b43_phy_write(dev, B43_NPHY_SAMP_WAITCNT, wait); | ||
1030 | |||
1031 | seq_mode = b43_phy_read(dev, B43_NPHY_RFSEQMODE); | ||
1032 | |||
1033 | b43_phy_set(dev, B43_NPHY_RFSEQMODE, B43_NPHY_RFSEQMODE_CAOVER); | ||
1034 | if (iqmode) { | ||
1035 | b43_phy_mask(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x7FFF); | ||
1036 | b43_phy_set(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8000); | ||
1037 | } else { | ||
1038 | if (dac_test) | ||
1039 | b43_phy_write(dev, B43_NPHY_SAMP_CMD, 5); | ||
1040 | else | ||
1041 | b43_phy_write(dev, B43_NPHY_SAMP_CMD, 1); | ||
1042 | } | ||
1043 | for (i = 0; i < 100; i++) { | ||
1044 | if (b43_phy_read(dev, B43_NPHY_RFSEQST) & 1) { | ||
1045 | i = 0; | ||
1046 | break; | ||
1047 | } | ||
1048 | udelay(10); | ||
1049 | } | ||
1050 | if (i) | ||
1051 | b43err(dev->wl, "run samples timeout\n"); | ||
1052 | |||
1053 | b43_phy_write(dev, B43_NPHY_RFSEQMODE, seq_mode); | ||
1054 | } | ||
1055 | |||
1056 | /* | ||
1057 | * Transmits a known value for LO calibration | ||
1058 | * http://bcm-v4.sipsolutions.net/802.11/PHY/N/TXTone | ||
1059 | */ | ||
1060 | static int b43_nphy_tx_tone(struct b43_wldev *dev, u32 freq, u16 max_val, | ||
1061 | bool iqmode, bool dac_test) | ||
1062 | { | ||
1063 | u16 samp = b43_nphy_gen_load_samples(dev, freq, max_val, dac_test); | ||
1064 | if (samp == 0) | ||
1065 | return -1; | ||
1066 | b43_nphy_run_samples(dev, samp, 0xFFFF, 0, iqmode, dac_test); | ||
1067 | return 0; | ||
1068 | } | ||
1069 | |||
656 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlCoefSetup */ | 1070 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlCoefSetup */ |
657 | static void b43_nphy_tx_pwr_ctrl_coef_setup(struct b43_wldev *dev) | 1071 | static void b43_nphy_tx_pwr_ctrl_coef_setup(struct b43_wldev *dev) |
658 | { | 1072 | { |
@@ -666,8 +1080,7 @@ static void b43_nphy_tx_pwr_ctrl_coef_setup(struct b43_wldev *dev) | |||
666 | if (nphy->hang_avoid) | 1080 | if (nphy->hang_avoid) |
667 | b43_nphy_stay_in_carrier_search(dev, true); | 1081 | b43_nphy_stay_in_carrier_search(dev, true); |
668 | 1082 | ||
669 | /* TODO: Read an N PHY Table with ID 15, length 7, offset 80, | 1083 | b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer); |
670 | width 16, and data pointer buffer */ | ||
671 | 1084 | ||
672 | for (i = 0; i < 2; i++) { | 1085 | for (i = 0; i < 2; i++) { |
673 | tmp = ((buffer[i * 2] & 0x3FF) << 10) | | 1086 | tmp = ((buffer[i * 2] & 0x3FF) << 10) | |
@@ -720,15 +1133,32 @@ static void b43_nphy_tx_pwr_ctrl_coef_setup(struct b43_wldev *dev) | |||
720 | b43_nphy_stay_in_carrier_search(dev, false); | 1133 | b43_nphy_stay_in_carrier_search(dev, false); |
721 | } | 1134 | } |
722 | 1135 | ||
723 | enum b43_nphy_rf_sequence { | 1136 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetRfSeq */ |
724 | B43_RFSEQ_RX2TX, | 1137 | static void b43_nphy_set_rf_sequence(struct b43_wldev *dev, u8 cmd, |
725 | B43_RFSEQ_TX2RX, | 1138 | u8 *events, u8 *delays, u8 length) |
726 | B43_RFSEQ_RESET2RX, | 1139 | { |
727 | B43_RFSEQ_UPDATE_GAINH, | 1140 | struct b43_phy_n *nphy = dev->phy.n; |
728 | B43_RFSEQ_UPDATE_GAINL, | 1141 | u8 i; |
729 | B43_RFSEQ_UPDATE_GAINU, | 1142 | u8 end = (dev->phy.rev >= 3) ? 0x1F : 0x0F; |
730 | }; | 1143 | u16 offset1 = cmd << 4; |
1144 | u16 offset2 = offset1 + 0x80; | ||
731 | 1145 | ||
1146 | if (nphy->hang_avoid) | ||
1147 | b43_nphy_stay_in_carrier_search(dev, true); | ||
1148 | |||
1149 | b43_ntab_write_bulk(dev, B43_NTAB8(7, offset1), length, events); | ||
1150 | b43_ntab_write_bulk(dev, B43_NTAB8(7, offset2), length, delays); | ||
1151 | |||
1152 | for (i = length; i < 16; i++) { | ||
1153 | b43_ntab_write(dev, B43_NTAB8(7, offset1 + i), end); | ||
1154 | b43_ntab_write(dev, B43_NTAB8(7, offset2 + i), 1); | ||
1155 | } | ||
1156 | |||
1157 | if (nphy->hang_avoid) | ||
1158 | b43_nphy_stay_in_carrier_search(dev, false); | ||
1159 | } | ||
1160 | |||
1161 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ForceRFSeq */ | ||
732 | static void b43_nphy_force_rf_sequence(struct b43_wldev *dev, | 1162 | static void b43_nphy_force_rf_sequence(struct b43_wldev *dev, |
733 | enum b43_nphy_rf_sequence seq) | 1163 | enum b43_nphy_rf_sequence seq) |
734 | { | 1164 | { |
@@ -741,6 +1171,7 @@ static void b43_nphy_force_rf_sequence(struct b43_wldev *dev, | |||
741 | [B43_RFSEQ_UPDATE_GAINU] = B43_NPHY_RFSEQTR_UPGU, | 1171 | [B43_RFSEQ_UPDATE_GAINU] = B43_NPHY_RFSEQTR_UPGU, |
742 | }; | 1172 | }; |
743 | int i; | 1173 | int i; |
1174 | u16 seq_mode = b43_phy_read(dev, B43_NPHY_RFSEQMODE); | ||
744 | 1175 | ||
745 | B43_WARN_ON(seq >= ARRAY_SIZE(trigger)); | 1176 | B43_WARN_ON(seq >= ARRAY_SIZE(trigger)); |
746 | 1177 | ||
@@ -754,8 +1185,83 @@ static void b43_nphy_force_rf_sequence(struct b43_wldev *dev, | |||
754 | } | 1185 | } |
755 | b43err(dev->wl, "RF sequence status timeout\n"); | 1186 | b43err(dev->wl, "RF sequence status timeout\n"); |
756 | ok: | 1187 | ok: |
757 | b43_phy_mask(dev, B43_NPHY_RFSEQMODE, | 1188 | b43_phy_write(dev, B43_NPHY_RFSEQMODE, seq_mode); |
758 | ~(B43_NPHY_RFSEQMODE_CAOVER | B43_NPHY_RFSEQMODE_TROVER)); | 1189 | } |
1190 | |||
1191 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverride */ | ||
1192 | static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field, | ||
1193 | u16 value, u8 core, bool off) | ||
1194 | { | ||
1195 | int i; | ||
1196 | u8 index = fls(field); | ||
1197 | u8 addr, en_addr, val_addr; | ||
1198 | /* we expect only one bit set */ | ||
1199 | B43_WARN_ON(field & (~(1 << (index - 1)))); | ||
1200 | |||
1201 | if (dev->phy.rev >= 3) { | ||
1202 | const struct nphy_rf_control_override_rev3 *rf_ctrl; | ||
1203 | for (i = 0; i < 2; i++) { | ||
1204 | if (index == 0 || index == 16) { | ||
1205 | b43err(dev->wl, | ||
1206 | "Unsupported RF Ctrl Override call\n"); | ||
1207 | return; | ||
1208 | } | ||
1209 | |||
1210 | rf_ctrl = &tbl_rf_control_override_rev3[index - 1]; | ||
1211 | en_addr = B43_PHY_N((i == 0) ? | ||
1212 | rf_ctrl->en_addr0 : rf_ctrl->en_addr1); | ||
1213 | val_addr = B43_PHY_N((i == 0) ? | ||
1214 | rf_ctrl->val_addr0 : rf_ctrl->val_addr1); | ||
1215 | |||
1216 | if (off) { | ||
1217 | b43_phy_mask(dev, en_addr, ~(field)); | ||
1218 | b43_phy_mask(dev, val_addr, | ||
1219 | ~(rf_ctrl->val_mask)); | ||
1220 | } else { | ||
1221 | if (core == 0 || ((1 << core) & i) != 0) { | ||
1222 | b43_phy_set(dev, en_addr, field); | ||
1223 | b43_phy_maskset(dev, val_addr, | ||
1224 | ~(rf_ctrl->val_mask), | ||
1225 | (value << rf_ctrl->val_shift)); | ||
1226 | } | ||
1227 | } | ||
1228 | } | ||
1229 | } else { | ||
1230 | const struct nphy_rf_control_override_rev2 *rf_ctrl; | ||
1231 | if (off) { | ||
1232 | b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, ~(field)); | ||
1233 | value = 0; | ||
1234 | } else { | ||
1235 | b43_phy_set(dev, B43_NPHY_RFCTL_OVER, field); | ||
1236 | } | ||
1237 | |||
1238 | for (i = 0; i < 2; i++) { | ||
1239 | if (index <= 1 || index == 16) { | ||
1240 | b43err(dev->wl, | ||
1241 | "Unsupported RF Ctrl Override call\n"); | ||
1242 | return; | ||
1243 | } | ||
1244 | |||
1245 | if (index == 2 || index == 10 || | ||
1246 | (index >= 13 && index <= 15)) { | ||
1247 | core = 1; | ||
1248 | } | ||
1249 | |||
1250 | rf_ctrl = &tbl_rf_control_override_rev2[index - 2]; | ||
1251 | addr = B43_PHY_N((i == 0) ? | ||
1252 | rf_ctrl->addr0 : rf_ctrl->addr1); | ||
1253 | |||
1254 | if ((core & (1 << i)) != 0) | ||
1255 | b43_phy_maskset(dev, addr, ~(rf_ctrl->bmask), | ||
1256 | (value << rf_ctrl->shift)); | ||
1257 | |||
1258 | b43_phy_set(dev, B43_NPHY_RFCTL_OVER, 0x1); | ||
1259 | b43_phy_set(dev, B43_NPHY_RFCTL_CMD, | ||
1260 | B43_NPHY_RFCTL_CMD_START); | ||
1261 | udelay(1); | ||
1262 | b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, 0xFFFE); | ||
1263 | } | ||
1264 | } | ||
759 | } | 1265 | } |
760 | 1266 | ||
761 | static void b43_nphy_bphy_init(struct b43_wldev *dev) | 1267 | static void b43_nphy_bphy_init(struct b43_wldev *dev) |
@@ -837,66 +1343,151 @@ static void b43_nphy_scale_offset_rssi(struct b43_wldev *dev, u16 scale, | |||
837 | b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TSSI, tmp); | 1343 | b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TSSI, tmp); |
838 | } | 1344 | } |
839 | 1345 | ||
840 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSISel */ | 1346 | static void b43_nphy_rev2_rssi_select(struct b43_wldev *dev, u8 code, u8 type) |
841 | static void b43_nphy_rssi_select(struct b43_wldev *dev, u8 code, u8 type) | ||
842 | { | 1347 | { |
843 | u16 val; | 1348 | u16 val; |
844 | 1349 | ||
845 | if (dev->phy.rev >= 3) { | 1350 | if (type < 3) |
846 | /* TODO */ | 1351 | val = 0; |
847 | } else { | 1352 | else if (type == 6) |
848 | if (type < 3) | 1353 | val = 1; |
849 | val = 0; | 1354 | else if (type == 3) |
850 | else if (type == 6) | 1355 | val = 2; |
851 | val = 1; | 1356 | else |
852 | else if (type == 3) | 1357 | val = 3; |
853 | val = 2; | ||
854 | else | ||
855 | val = 3; | ||
856 | 1358 | ||
857 | val = (val << 12) | (val << 14); | 1359 | val = (val << 12) | (val << 14); |
858 | b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, val); | 1360 | b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, val); |
859 | b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, val); | 1361 | b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, val); |
860 | 1362 | ||
1363 | if (type < 3) { | ||
1364 | b43_phy_maskset(dev, B43_NPHY_RFCTL_RSSIO1, 0xFFCF, | ||
1365 | (type + 1) << 4); | ||
1366 | b43_phy_maskset(dev, B43_NPHY_RFCTL_RSSIO2, 0xFFCF, | ||
1367 | (type + 1) << 4); | ||
1368 | } | ||
1369 | |||
1370 | /* TODO use some definitions */ | ||
1371 | if (code == 0) { | ||
1372 | b43_phy_maskset(dev, B43_NPHY_AFECTL_OVER, 0xCFFF, 0); | ||
1373 | if (type < 3) { | ||
1374 | b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 0xFEC7, 0); | ||
1375 | b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 0xEFDC, 0); | ||
1376 | b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 0xFFFE, 0); | ||
1377 | udelay(20); | ||
1378 | b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 0xFFFE, 0); | ||
1379 | } | ||
1380 | } else { | ||
1381 | b43_phy_maskset(dev, B43_NPHY_AFECTL_OVER, 0xCFFF, | ||
1382 | 0x3000); | ||
861 | if (type < 3) { | 1383 | if (type < 3) { |
862 | b43_phy_maskset(dev, B43_NPHY_RFCTL_RSSIO1, 0xFFCF, | 1384 | b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, |
863 | (type + 1) << 4); | 1385 | 0xFEC7, 0x0180); |
864 | b43_phy_maskset(dev, B43_NPHY_RFCTL_RSSIO2, 0xFFCF, | 1386 | b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, |
865 | (type + 1) << 4); | 1387 | 0xEFDC, (code << 1 | 0x1021)); |
1388 | b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 0xFFFE, 0x1); | ||
1389 | udelay(20); | ||
1390 | b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 0xFFFE, 0); | ||
866 | } | 1391 | } |
1392 | } | ||
1393 | } | ||
1394 | |||
1395 | static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code, u8 type) | ||
1396 | { | ||
1397 | struct b43_phy_n *nphy = dev->phy.n; | ||
1398 | u8 i; | ||
1399 | u16 reg, val; | ||
1400 | |||
1401 | if (code == 0) { | ||
1402 | b43_phy_mask(dev, B43_NPHY_AFECTL_OVER1, 0xFDFF); | ||
1403 | b43_phy_mask(dev, B43_NPHY_AFECTL_OVER, 0xFDFF); | ||
1404 | b43_phy_mask(dev, B43_NPHY_AFECTL_C1, 0xFCFF); | ||
1405 | b43_phy_mask(dev, B43_NPHY_AFECTL_C2, 0xFCFF); | ||
1406 | b43_phy_mask(dev, B43_NPHY_TXF_40CO_B1S0, 0xFFDF); | ||
1407 | b43_phy_mask(dev, B43_NPHY_TXF_40CO_B32S1, 0xFFDF); | ||
1408 | b43_phy_mask(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0xFFC3); | ||
1409 | b43_phy_mask(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0xFFC3); | ||
1410 | } else { | ||
1411 | for (i = 0; i < 2; i++) { | ||
1412 | if ((code == 1 && i == 1) || (code == 2 && !i)) | ||
1413 | continue; | ||
1414 | |||
1415 | reg = (i == 0) ? | ||
1416 | B43_NPHY_AFECTL_OVER1 : B43_NPHY_AFECTL_OVER; | ||
1417 | b43_phy_maskset(dev, reg, 0xFDFF, 0x0200); | ||
867 | 1418 | ||
868 | /* TODO use some definitions */ | ||
869 | if (code == 0) { | ||
870 | b43_phy_maskset(dev, B43_NPHY_AFECTL_OVER, 0xCFFF, 0); | ||
871 | if (type < 3) { | ||
872 | b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, | ||
873 | 0xFEC7, 0); | ||
874 | b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, | ||
875 | 0xEFDC, 0); | ||
876 | b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, | ||
877 | 0xFFFE, 0); | ||
878 | udelay(20); | ||
879 | b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, | ||
880 | 0xFFFE, 0); | ||
881 | } | ||
882 | } else { | ||
883 | b43_phy_maskset(dev, B43_NPHY_AFECTL_OVER, 0xCFFF, | ||
884 | 0x3000); | ||
885 | if (type < 3) { | 1419 | if (type < 3) { |
886 | b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, | 1420 | reg = (i == 0) ? |
887 | 0xFEC7, 0x0180); | 1421 | B43_NPHY_AFECTL_C1 : |
888 | b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, | 1422 | B43_NPHY_AFECTL_C2; |
889 | 0xEFDC, (code << 1 | 0x1021)); | 1423 | b43_phy_maskset(dev, reg, 0xFCFF, 0); |
890 | b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, | 1424 | |
891 | 0xFFFE, 0x0001); | 1425 | reg = (i == 0) ? |
892 | udelay(20); | 1426 | B43_NPHY_RFCTL_LUT_TRSW_UP1 : |
893 | b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, | 1427 | B43_NPHY_RFCTL_LUT_TRSW_UP2; |
894 | 0xFFFE, 0); | 1428 | b43_phy_maskset(dev, reg, 0xFFC3, 0); |
1429 | |||
1430 | if (type == 0) | ||
1431 | val = (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ? 4 : 8; | ||
1432 | else if (type == 1) | ||
1433 | val = 16; | ||
1434 | else | ||
1435 | val = 32; | ||
1436 | b43_phy_set(dev, reg, val); | ||
1437 | |||
1438 | reg = (i == 0) ? | ||
1439 | B43_NPHY_TXF_40CO_B1S0 : | ||
1440 | B43_NPHY_TXF_40CO_B32S1; | ||
1441 | b43_phy_set(dev, reg, 0x0020); | ||
1442 | } else { | ||
1443 | if (type == 6) | ||
1444 | val = 0x0100; | ||
1445 | else if (type == 3) | ||
1446 | val = 0x0200; | ||
1447 | else | ||
1448 | val = 0x0300; | ||
1449 | |||
1450 | reg = (i == 0) ? | ||
1451 | B43_NPHY_AFECTL_C1 : | ||
1452 | B43_NPHY_AFECTL_C2; | ||
1453 | |||
1454 | b43_phy_maskset(dev, reg, 0xFCFF, val); | ||
1455 | b43_phy_maskset(dev, reg, 0xF3FF, val << 2); | ||
1456 | |||
1457 | if (type != 3 && type != 6) { | ||
1458 | enum ieee80211_band band = | ||
1459 | b43_current_band(dev->wl); | ||
1460 | |||
1461 | if ((nphy->ipa2g_on && | ||
1462 | band == IEEE80211_BAND_2GHZ) || | ||
1463 | (nphy->ipa5g_on && | ||
1464 | band == IEEE80211_BAND_5GHZ)) | ||
1465 | val = (band == IEEE80211_BAND_5GHZ) ? 0xC : 0xE; | ||
1466 | else | ||
1467 | val = 0x11; | ||
1468 | reg = (i == 0) ? 0x2000 : 0x3000; | ||
1469 | reg |= B2055_PADDRV; | ||
1470 | b43_radio_write16(dev, reg, val); | ||
1471 | |||
1472 | reg = (i == 0) ? | ||
1473 | B43_NPHY_AFECTL_OVER1 : | ||
1474 | B43_NPHY_AFECTL_OVER; | ||
1475 | b43_phy_set(dev, reg, 0x0200); | ||
1476 | } | ||
895 | } | 1477 | } |
896 | } | 1478 | } |
897 | } | 1479 | } |
898 | } | 1480 | } |
899 | 1481 | ||
1482 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSISel */ | ||
1483 | static void b43_nphy_rssi_select(struct b43_wldev *dev, u8 code, u8 type) | ||
1484 | { | ||
1485 | if (dev->phy.rev >= 3) | ||
1486 | b43_nphy_rev3_rssi_select(dev, code, type); | ||
1487 | else | ||
1488 | b43_nphy_rev2_rssi_select(dev, code, type); | ||
1489 | } | ||
1490 | |||
900 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetRssi2055Vcm */ | 1491 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetRssi2055Vcm */ |
901 | static void b43_nphy_set_rssi_2055_vcm(struct b43_wldev *dev, u8 type, u8 *buf) | 1492 | static void b43_nphy_set_rssi_2055_vcm(struct b43_wldev *dev, u8 type, u8 *buf) |
902 | { | 1493 | { |
@@ -1239,9 +1830,60 @@ static void b43_nphy_tx_cal_radio_setup(struct b43_wldev *dev) | |||
1239 | { | 1830 | { |
1240 | struct b43_phy_n *nphy = dev->phy.n; | 1831 | struct b43_phy_n *nphy = dev->phy.n; |
1241 | u16 *save = nphy->tx_rx_cal_radio_saveregs; | 1832 | u16 *save = nphy->tx_rx_cal_radio_saveregs; |
1833 | u16 tmp; | ||
1834 | u8 offset, i; | ||
1242 | 1835 | ||
1243 | if (dev->phy.rev >= 3) { | 1836 | if (dev->phy.rev >= 3) { |
1244 | /* TODO */ | 1837 | for (i = 0; i < 2; i++) { |
1838 | tmp = (i == 0) ? 0x2000 : 0x3000; | ||
1839 | offset = i * 11; | ||
1840 | |||
1841 | save[offset + 0] = b43_radio_read16(dev, B2055_CAL_RVARCTL); | ||
1842 | save[offset + 1] = b43_radio_read16(dev, B2055_CAL_LPOCTL); | ||
1843 | save[offset + 2] = b43_radio_read16(dev, B2055_CAL_TS); | ||
1844 | save[offset + 3] = b43_radio_read16(dev, B2055_CAL_RCCALRTS); | ||
1845 | save[offset + 4] = b43_radio_read16(dev, B2055_CAL_RCALRTS); | ||
1846 | save[offset + 5] = b43_radio_read16(dev, B2055_PADDRV); | ||
1847 | save[offset + 6] = b43_radio_read16(dev, B2055_XOCTL1); | ||
1848 | save[offset + 7] = b43_radio_read16(dev, B2055_XOCTL2); | ||
1849 | save[offset + 8] = b43_radio_read16(dev, B2055_XOREGUL); | ||
1850 | save[offset + 9] = b43_radio_read16(dev, B2055_XOMISC); | ||
1851 | save[offset + 10] = b43_radio_read16(dev, B2055_PLL_LFC1); | ||
1852 | |||
1853 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { | ||
1854 | b43_radio_write16(dev, tmp | B2055_CAL_RVARCTL, 0x0A); | ||
1855 | b43_radio_write16(dev, tmp | B2055_CAL_LPOCTL, 0x40); | ||
1856 | b43_radio_write16(dev, tmp | B2055_CAL_TS, 0x55); | ||
1857 | b43_radio_write16(dev, tmp | B2055_CAL_RCCALRTS, 0); | ||
1858 | b43_radio_write16(dev, tmp | B2055_CAL_RCALRTS, 0); | ||
1859 | if (nphy->ipa5g_on) { | ||
1860 | b43_radio_write16(dev, tmp | B2055_PADDRV, 4); | ||
1861 | b43_radio_write16(dev, tmp | B2055_XOCTL1, 1); | ||
1862 | } else { | ||
1863 | b43_radio_write16(dev, tmp | B2055_PADDRV, 0); | ||
1864 | b43_radio_write16(dev, tmp | B2055_XOCTL1, 0x2F); | ||
1865 | } | ||
1866 | b43_radio_write16(dev, tmp | B2055_XOCTL2, 0); | ||
1867 | } else { | ||
1868 | b43_radio_write16(dev, tmp | B2055_CAL_RVARCTL, 0x06); | ||
1869 | b43_radio_write16(dev, tmp | B2055_CAL_LPOCTL, 0x40); | ||
1870 | b43_radio_write16(dev, tmp | B2055_CAL_TS, 0x55); | ||
1871 | b43_radio_write16(dev, tmp | B2055_CAL_RCCALRTS, 0); | ||
1872 | b43_radio_write16(dev, tmp | B2055_CAL_RCALRTS, 0); | ||
1873 | b43_radio_write16(dev, tmp | B2055_XOCTL1, 0); | ||
1874 | if (nphy->ipa2g_on) { | ||
1875 | b43_radio_write16(dev, tmp | B2055_PADDRV, 6); | ||
1876 | b43_radio_write16(dev, tmp | B2055_XOCTL2, | ||
1877 | (dev->phy.rev < 5) ? 0x11 : 0x01); | ||
1878 | } else { | ||
1879 | b43_radio_write16(dev, tmp | B2055_PADDRV, 0); | ||
1880 | b43_radio_write16(dev, tmp | B2055_XOCTL2, 0); | ||
1881 | } | ||
1882 | } | ||
1883 | b43_radio_write16(dev, tmp | B2055_XOREGUL, 0); | ||
1884 | b43_radio_write16(dev, tmp | B2055_XOMISC, 0); | ||
1885 | b43_radio_write16(dev, tmp | B2055_PLL_LFC1, 0); | ||
1886 | } | ||
1245 | } else { | 1887 | } else { |
1246 | save[0] = b43_radio_read16(dev, B2055_C1_TX_RF_IQCAL1); | 1888 | save[0] = b43_radio_read16(dev, B2055_C1_TX_RF_IQCAL1); |
1247 | b43_radio_write16(dev, B2055_C1_TX_RF_IQCAL1, 0x29); | 1889 | b43_radio_write16(dev, B2055_C1_TX_RF_IQCAL1, 0x29); |
@@ -1330,16 +1972,51 @@ static void b43_nphy_update_tx_cal_ladder(struct b43_wldev *dev, u16 core) | |||
1330 | for (i = 0; i < 18; i++) { | 1972 | for (i = 0; i < 18; i++) { |
1331 | scale = (ladder_lo[i].percent * tmp) / 100; | 1973 | scale = (ladder_lo[i].percent * tmp) / 100; |
1332 | entry = ((scale & 0xFF) << 8) | ladder_lo[i].g_env; | 1974 | entry = ((scale & 0xFF) << 8) | ladder_lo[i].g_env; |
1333 | /* TODO: Write an N PHY Table with ID 15, length 1, | 1975 | b43_ntab_write(dev, B43_NTAB16(15, i), entry); |
1334 | offset i, width 16, and data entry */ | ||
1335 | 1976 | ||
1336 | scale = (ladder_iq[i].percent * tmp) / 100; | 1977 | scale = (ladder_iq[i].percent * tmp) / 100; |
1337 | entry = ((scale & 0xFF) << 8) | ladder_iq[i].g_env; | 1978 | entry = ((scale & 0xFF) << 8) | ladder_iq[i].g_env; |
1338 | /* TODO: Write an N PHY Table with ID 15, length 1, | 1979 | b43_ntab_write(dev, B43_NTAB16(15, i + 32), entry); |
1339 | offset i + 32, width 16, and data entry */ | ||
1340 | } | 1980 | } |
1341 | } | 1981 | } |
1342 | 1982 | ||
1983 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ExtPaSetTxDigiFilts */ | ||
1984 | static void b43_nphy_ext_pa_set_tx_dig_filters(struct b43_wldev *dev) | ||
1985 | { | ||
1986 | int i; | ||
1987 | for (i = 0; i < 15; i++) | ||
1988 | b43_phy_write(dev, B43_PHY_N(0x2C5 + i), | ||
1989 | tbl_tx_filter_coef_rev4[2][i]); | ||
1990 | } | ||
1991 | |||
1992 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/IpaSetTxDigiFilts */ | ||
1993 | static void b43_nphy_int_pa_set_tx_dig_filters(struct b43_wldev *dev) | ||
1994 | { | ||
1995 | int i, j; | ||
1996 | /* B43_NPHY_TXF_20CO_S0A1, B43_NPHY_TXF_40CO_S0A1, unknown */ | ||
1997 | u16 offset[] = { 0x186, 0x195, 0x2C5 }; | ||
1998 | |||
1999 | for (i = 0; i < 3; i++) | ||
2000 | for (j = 0; j < 15; j++) | ||
2001 | b43_phy_write(dev, B43_PHY_N(offset[i] + j), | ||
2002 | tbl_tx_filter_coef_rev4[i][j]); | ||
2003 | |||
2004 | if (dev->phy.is_40mhz) { | ||
2005 | for (j = 0; j < 15; j++) | ||
2006 | b43_phy_write(dev, B43_PHY_N(offset[0] + j), | ||
2007 | tbl_tx_filter_coef_rev4[3][j]); | ||
2008 | } else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { | ||
2009 | for (j = 0; j < 15; j++) | ||
2010 | b43_phy_write(dev, B43_PHY_N(offset[0] + j), | ||
2011 | tbl_tx_filter_coef_rev4[5][j]); | ||
2012 | } | ||
2013 | |||
2014 | if (dev->phy.channel == 14) | ||
2015 | for (j = 0; j < 15; j++) | ||
2016 | b43_phy_write(dev, B43_PHY_N(offset[0] + j), | ||
2017 | tbl_tx_filter_coef_rev4[6][j]); | ||
2018 | } | ||
2019 | |||
1343 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetTxGain */ | 2020 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetTxGain */ |
1344 | static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev) | 2021 | static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev) |
1345 | { | 2022 | { |
@@ -1354,8 +2031,7 @@ static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev) | |||
1354 | 2031 | ||
1355 | if (nphy->hang_avoid) | 2032 | if (nphy->hang_avoid) |
1356 | b43_nphy_stay_in_carrier_search(dev, true); | 2033 | b43_nphy_stay_in_carrier_search(dev, true); |
1357 | /* TODO: Read an N PHY Table with ID 7, length 2, | 2034 | b43_ntab_read_bulk(dev, B43_NTAB16(7, 0x110), 2, curr_gain); |
1358 | offset 0x110, width 16, and curr_gain */ | ||
1359 | if (nphy->hang_avoid) | 2035 | if (nphy->hang_avoid) |
1360 | b43_nphy_stay_in_carrier_search(dev, false); | 2036 | b43_nphy_stay_in_carrier_search(dev, false); |
1361 | 2037 | ||
@@ -1423,6 +2099,101 @@ static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev) | |||
1423 | return target; | 2099 | return target; |
1424 | } | 2100 | } |
1425 | 2101 | ||
2102 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalPhyCleanup */ | ||
2103 | static void b43_nphy_tx_cal_phy_cleanup(struct b43_wldev *dev) | ||
2104 | { | ||
2105 | u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs; | ||
2106 | |||
2107 | if (dev->phy.rev >= 3) { | ||
2108 | b43_phy_write(dev, B43_NPHY_AFECTL_C1, regs[0]); | ||
2109 | b43_phy_write(dev, B43_NPHY_AFECTL_C2, regs[1]); | ||
2110 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, regs[2]); | ||
2111 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER, regs[3]); | ||
2112 | b43_phy_write(dev, B43_NPHY_BBCFG, regs[4]); | ||
2113 | b43_ntab_write(dev, B43_NTAB16(8, 3), regs[5]); | ||
2114 | b43_ntab_write(dev, B43_NTAB16(8, 19), regs[6]); | ||
2115 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs[7]); | ||
2116 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs[8]); | ||
2117 | b43_phy_write(dev, B43_NPHY_PAPD_EN0, regs[9]); | ||
2118 | b43_phy_write(dev, B43_NPHY_PAPD_EN1, regs[10]); | ||
2119 | b43_nphy_reset_cca(dev); | ||
2120 | } else { | ||
2121 | b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, regs[0]); | ||
2122 | b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, regs[1]); | ||
2123 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER, regs[2]); | ||
2124 | b43_ntab_write(dev, B43_NTAB16(8, 2), regs[3]); | ||
2125 | b43_ntab_write(dev, B43_NTAB16(8, 18), regs[4]); | ||
2126 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs[5]); | ||
2127 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs[6]); | ||
2128 | } | ||
2129 | } | ||
2130 | |||
2131 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalPhySetup */ | ||
2132 | static void b43_nphy_tx_cal_phy_setup(struct b43_wldev *dev) | ||
2133 | { | ||
2134 | u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs; | ||
2135 | u16 tmp; | ||
2136 | |||
2137 | regs[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1); | ||
2138 | regs[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2); | ||
2139 | if (dev->phy.rev >= 3) { | ||
2140 | b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0xF0FF, 0x0A00); | ||
2141 | b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0xF0FF, 0x0A00); | ||
2142 | |||
2143 | tmp = b43_phy_read(dev, B43_NPHY_AFECTL_OVER1); | ||
2144 | regs[2] = tmp; | ||
2145 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, tmp | 0x0600); | ||
2146 | |||
2147 | tmp = b43_phy_read(dev, B43_NPHY_AFECTL_OVER); | ||
2148 | regs[3] = tmp; | ||
2149 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER, tmp | 0x0600); | ||
2150 | |||
2151 | regs[4] = b43_phy_read(dev, B43_NPHY_BBCFG); | ||
2152 | b43_phy_mask(dev, B43_NPHY_BBCFG, (u16)~B43_NPHY_BBCFG_RSTRX); | ||
2153 | |||
2154 | tmp = b43_ntab_read(dev, B43_NTAB16(8, 3)); | ||
2155 | regs[5] = tmp; | ||
2156 | b43_ntab_write(dev, B43_NTAB16(8, 3), 0); | ||
2157 | |||
2158 | tmp = b43_ntab_read(dev, B43_NTAB16(8, 19)); | ||
2159 | regs[6] = tmp; | ||
2160 | b43_ntab_write(dev, B43_NTAB16(8, 19), 0); | ||
2161 | regs[7] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1); | ||
2162 | regs[8] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2); | ||
2163 | |||
2164 | /* TODO: Call N PHY RF Ctrl Intc Override with 2, 1, 3 */ | ||
2165 | /* TODO: Call N PHY RF Ctrl Intc Override with 1, 2, 1 */ | ||
2166 | /* TODO: Call N PHY RF Ctrl Intc Override with 1, 8, 2 */ | ||
2167 | |||
2168 | regs[9] = b43_phy_read(dev, B43_NPHY_PAPD_EN0); | ||
2169 | regs[10] = b43_phy_read(dev, B43_NPHY_PAPD_EN1); | ||
2170 | b43_phy_mask(dev, B43_NPHY_PAPD_EN0, ~0x0001); | ||
2171 | b43_phy_mask(dev, B43_NPHY_PAPD_EN1, ~0x0001); | ||
2172 | } else { | ||
2173 | b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, 0xA000); | ||
2174 | b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, 0xA000); | ||
2175 | tmp = b43_phy_read(dev, B43_NPHY_AFECTL_OVER); | ||
2176 | regs[2] = tmp; | ||
2177 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER, tmp | 0x3000); | ||
2178 | tmp = b43_ntab_read(dev, B43_NTAB16(8, 2)); | ||
2179 | regs[3] = tmp; | ||
2180 | tmp |= 0x2000; | ||
2181 | b43_ntab_write(dev, B43_NTAB16(8, 2), tmp); | ||
2182 | tmp = b43_ntab_read(dev, B43_NTAB16(8, 18)); | ||
2183 | regs[4] = tmp; | ||
2184 | tmp |= 0x2000; | ||
2185 | b43_ntab_write(dev, B43_NTAB16(8, 18), tmp); | ||
2186 | regs[5] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1); | ||
2187 | regs[6] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2); | ||
2188 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) | ||
2189 | tmp = 0x0180; | ||
2190 | else | ||
2191 | tmp = 0x0120; | ||
2192 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, tmp); | ||
2193 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, tmp); | ||
2194 | } | ||
2195 | } | ||
2196 | |||
1426 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RestoreCal */ | 2197 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RestoreCal */ |
1427 | static void b43_nphy_restore_cal(struct b43_wldev *dev) | 2198 | static void b43_nphy_restore_cal(struct b43_wldev *dev) |
1428 | { | 2199 | { |
@@ -1448,8 +2219,7 @@ static void b43_nphy_restore_cal(struct b43_wldev *dev) | |||
1448 | loft = &nphy->cal_cache.txcal_coeffs_5G[5]; | 2219 | loft = &nphy->cal_cache.txcal_coeffs_5G[5]; |
1449 | } | 2220 | } |
1450 | 2221 | ||
1451 | /* TODO: Write an N PHY table with ID 15, length 4, offset 80, | 2222 | b43_ntab_write_bulk(dev, B43_NTAB16(15, 80), 4, table); |
1452 | width 16, and data from table */ | ||
1453 | 2223 | ||
1454 | for (i = 0; i < 4; i++) { | 2224 | for (i = 0; i < 4; i++) { |
1455 | if (dev->phy.rev >= 3) | 2225 | if (dev->phy.rev >= 3) |
@@ -1458,12 +2228,9 @@ static void b43_nphy_restore_cal(struct b43_wldev *dev) | |||
1458 | coef[i] = 0; | 2228 | coef[i] = 0; |
1459 | } | 2229 | } |
1460 | 2230 | ||
1461 | /* TODO: Write an N PHY table with ID 15, length 4, offset 88, | 2231 | b43_ntab_write_bulk(dev, B43_NTAB16(15, 88), 4, coef); |
1462 | width 16, and data from coef */ | 2232 | b43_ntab_write_bulk(dev, B43_NTAB16(15, 85), 2, loft); |
1463 | /* TODO: Write an N PHY table with ID 15, length 2, offset 85, | 2233 | b43_ntab_write_bulk(dev, B43_NTAB16(15, 93), 2, loft); |
1464 | width 16 and data from loft */ | ||
1465 | /* TODO: Write an N PHY table with ID 15, length 2, offset 93, | ||
1466 | width 16 and data from loft */ | ||
1467 | 2234 | ||
1468 | if (dev->phy.rev < 2) | 2235 | if (dev->phy.rev < 2) |
1469 | b43_nphy_tx_iq_workaround(dev); | 2236 | b43_nphy_tx_iq_workaround(dev); |
@@ -1524,39 +2291,47 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev, | |||
1524 | nphy->hang_avoid = 0; | 2291 | nphy->hang_avoid = 0; |
1525 | } | 2292 | } |
1526 | 2293 | ||
1527 | /* TODO: Read an N PHY Table with ID 7, length 2, offset 0x110, | 2294 | b43_ntab_read_bulk(dev, B43_NTAB16(7, 0x110), 2, save); |
1528 | width 16, and data pointer save */ | ||
1529 | 2295 | ||
1530 | for (i = 0; i < 2; i++) { | 2296 | for (i = 0; i < 2; i++) { |
1531 | b43_nphy_iq_cal_gain_params(dev, i, target, ¶ms[i]); | 2297 | b43_nphy_iq_cal_gain_params(dev, i, target, ¶ms[i]); |
1532 | gain[i] = params[i].cal_gain; | 2298 | gain[i] = params[i].cal_gain; |
1533 | } | 2299 | } |
1534 | /* TODO: Write an N PHY Table with ID 7, length 2, offset 0x110, | 2300 | |
1535 | width 16, and data pointer gain */ | 2301 | b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, gain); |
1536 | 2302 | ||
1537 | b43_nphy_tx_cal_radio_setup(dev); | 2303 | b43_nphy_tx_cal_radio_setup(dev); |
1538 | /* TODO: Call N PHY TX Cal PHY Setup */ | 2304 | b43_nphy_tx_cal_phy_setup(dev); |
1539 | 2305 | ||
1540 | phy6or5x = dev->phy.rev >= 6 || | 2306 | phy6or5x = dev->phy.rev >= 6 || |
1541 | (dev->phy.rev == 5 && nphy->ipa2g_on && | 2307 | (dev->phy.rev == 5 && nphy->ipa2g_on && |
1542 | b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ); | 2308 | b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ); |
1543 | if (phy6or5x) { | 2309 | if (phy6or5x) { |
1544 | /* TODO */ | 2310 | if (dev->phy.is_40mhz) { |
2311 | b43_ntab_write_bulk(dev, B43_NTAB16(15, 0), 18, | ||
2312 | tbl_tx_iqlo_cal_loft_ladder_40); | ||
2313 | b43_ntab_write_bulk(dev, B43_NTAB16(15, 32), 18, | ||
2314 | tbl_tx_iqlo_cal_iqimb_ladder_40); | ||
2315 | } else { | ||
2316 | b43_ntab_write_bulk(dev, B43_NTAB16(15, 0), 18, | ||
2317 | tbl_tx_iqlo_cal_loft_ladder_20); | ||
2318 | b43_ntab_write_bulk(dev, B43_NTAB16(15, 32), 18, | ||
2319 | tbl_tx_iqlo_cal_iqimb_ladder_20); | ||
2320 | } | ||
1545 | } | 2321 | } |
1546 | 2322 | ||
1547 | b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8AA9); | 2323 | b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8AA9); |
1548 | 2324 | ||
1549 | if (1 /* FIXME: the band width is 20 MHz */) | 2325 | if (!dev->phy.is_40mhz) |
1550 | freq = 2500; | 2326 | freq = 2500; |
1551 | else | 2327 | else |
1552 | freq = 5000; | 2328 | freq = 5000; |
1553 | 2329 | ||
1554 | if (nphy->mphase_cal_phase_id > 2) | 2330 | if (nphy->mphase_cal_phase_id > 2) |
1555 | ;/* TODO: Call N PHY Run Samples with (band width * 8), | 2331 | b43_nphy_run_samples(dev, (dev->phy.is_40mhz ? 40 : 20) * 8, |
1556 | 0xFFFF, 0, 1, 0 as arguments */ | 2332 | 0xFFFF, 0, true, false); |
1557 | else | 2333 | else |
1558 | ;/* TODO: Call N PHY TX Tone with freq, 250, 1, 0 as arguments | 2334 | error = b43_nphy_tx_tone(dev, freq, 250, true, false); |
1559 | and save result as error */ | ||
1560 | 2335 | ||
1561 | if (error == 0) { | 2336 | if (error == 0) { |
1562 | if (nphy->mphase_cal_phase_id > 2) { | 2337 | if (nphy->mphase_cal_phase_id > 2) { |
@@ -1582,8 +2357,7 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev, | |||
1582 | } | 2357 | } |
1583 | } | 2358 | } |
1584 | 2359 | ||
1585 | /* TODO: Write an N PHY Table with ID 15, length from above, | 2360 | b43_ntab_write_bulk(dev, B43_NTAB16(15, 64), length, table); |
1586 | offset 64, width 16, and the data pointer from above */ | ||
1587 | 2361 | ||
1588 | if (full) { | 2362 | if (full) { |
1589 | if (dev->phy.rev >= 3) | 2363 | if (dev->phy.rev >= 3) |
@@ -1631,14 +2405,12 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev, | |||
1631 | b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDNNUM, tmp); | 2405 | b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDNNUM, tmp); |
1632 | 2406 | ||
1633 | if (type == 1 || type == 3 || type == 4) { | 2407 | if (type == 1 || type == 3 || type == 4) { |
1634 | /* TODO: Read an N PHY Table with ID 15, | 2408 | buffer[0] = b43_ntab_read(dev, |
1635 | length 1, offset 69 + core, | 2409 | B43_NTAB16(15, 69 + core)); |
1636 | width 16, and data pointer buffer */ | ||
1637 | diq_start = buffer[0]; | 2410 | diq_start = buffer[0]; |
1638 | buffer[0] = 0; | 2411 | buffer[0] = 0; |
1639 | /* TODO: Write an N PHY Table with ID 15, | 2412 | b43_ntab_write(dev, B43_NTAB16(15, 69 + core), |
1640 | length 1, offset 69 + core, width 16, | 2413 | 0); |
1641 | and data of 0 */ | ||
1642 | } | 2414 | } |
1643 | 2415 | ||
1644 | b43_phy_write(dev, B43_NPHY_IQLOCAL_CMD, cmd); | 2416 | b43_phy_write(dev, B43_NPHY_IQLOCAL_CMD, cmd); |
@@ -1649,12 +2421,10 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev, | |||
1649 | udelay(10); | 2421 | udelay(10); |
1650 | } | 2422 | } |
1651 | 2423 | ||
1652 | /* TODO: Read an N PHY Table with ID 15, | 2424 | b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length, |
1653 | length table_length, offset 96, width 16, | 2425 | buffer); |
1654 | and data pointer buffer */ | 2426 | b43_ntab_write_bulk(dev, B43_NTAB16(15, 64), length, |
1655 | /* TODO: Write an N PHY Table with ID 15, | 2427 | buffer); |
1656 | length table_length, offset 64, width 16, | ||
1657 | and data pointer buffer */ | ||
1658 | 2428 | ||
1659 | if (type == 1 || type == 3 || type == 4) | 2429 | if (type == 1 || type == 3 || type == 4) |
1660 | buffer[0] = diq_start; | 2430 | buffer[0] = diq_start; |
@@ -1666,30 +2436,27 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev, | |||
1666 | last = (dev->phy.rev < 3) ? 6 : 7; | 2436 | last = (dev->phy.rev < 3) ? 6 : 7; |
1667 | 2437 | ||
1668 | if (!mphase || nphy->mphase_cal_phase_id == last) { | 2438 | if (!mphase || nphy->mphase_cal_phase_id == last) { |
1669 | /* TODO: Write an N PHY Table with ID 15, length 4, | 2439 | b43_ntab_write_bulk(dev, B43_NTAB16(15, 96), 4, buffer); |
1670 | offset 96, width 16, and data pointer buffer */ | 2440 | b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 4, buffer); |
1671 | /* TODO: Read an N PHY Table with ID 15, length 4, | ||
1672 | offset 80, width 16, and data pointer buffer */ | ||
1673 | if (dev->phy.rev < 3) { | 2441 | if (dev->phy.rev < 3) { |
1674 | buffer[0] = 0; | 2442 | buffer[0] = 0; |
1675 | buffer[1] = 0; | 2443 | buffer[1] = 0; |
1676 | buffer[2] = 0; | 2444 | buffer[2] = 0; |
1677 | buffer[3] = 0; | 2445 | buffer[3] = 0; |
1678 | } | 2446 | } |
1679 | /* TODO: Write an N PHY Table with ID 15, length 4, | 2447 | b43_ntab_write_bulk(dev, B43_NTAB16(15, 88), 4, |
1680 | offset 88, width 16, and data pointer buffer */ | 2448 | buffer); |
1681 | /* TODO: Read an N PHY Table with ID 15, length 2, | 2449 | b43_ntab_write_bulk(dev, B43_NTAB16(15, 101), 2, |
1682 | offset 101, width 16, and data pointer buffer*/ | 2450 | buffer); |
1683 | /* TODO: Write an N PHY Table with ID 15, length 2, | 2451 | b43_ntab_write_bulk(dev, B43_NTAB16(15, 85), 2, |
1684 | offset 85, width 16, and data pointer buffer */ | 2452 | buffer); |
1685 | /* TODO: Write an N PHY Table with ID 15, length 2, | 2453 | b43_ntab_write_bulk(dev, B43_NTAB16(15, 93), 2, |
1686 | offset 93, width 16, and data pointer buffer */ | 2454 | buffer); |
1687 | length = 11; | 2455 | length = 11; |
1688 | if (dev->phy.rev < 3) | 2456 | if (dev->phy.rev < 3) |
1689 | length -= 2; | 2457 | length -= 2; |
1690 | /* TODO: Read an N PHY Table with ID 15, length length, | 2458 | b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length, |
1691 | offset 96, width 16, and data pointer | 2459 | nphy->txiqlocal_bestc); |
1692 | nphy->txiqlocal_bestc */ | ||
1693 | nphy->txiqlocal_coeffsvalid = true; | 2460 | nphy->txiqlocal_coeffsvalid = true; |
1694 | /* TODO: Set nphy->txiqlocal_chanspec to | 2461 | /* TODO: Set nphy->txiqlocal_chanspec to |
1695 | the current channel */ | 2462 | the current channel */ |
@@ -1697,18 +2464,16 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev, | |||
1697 | length = 11; | 2464 | length = 11; |
1698 | if (dev->phy.rev < 3) | 2465 | if (dev->phy.rev < 3) |
1699 | length -= 2; | 2466 | length -= 2; |
1700 | /* TODO: Read an N PHY Table with ID 5, length length, | 2467 | b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length, |
1701 | offset 96, width 16, and data pointer | 2468 | nphy->mphase_txcal_bestcoeffs); |
1702 | nphy->mphase_txcal_bestcoeffs */ | ||
1703 | } | 2469 | } |
1704 | 2470 | ||
1705 | /* TODO: Call N PHY Stop Playback */ | 2471 | b43_nphy_stop_playback(dev); |
1706 | b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0); | 2472 | b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0); |
1707 | } | 2473 | } |
1708 | 2474 | ||
1709 | /* TODO: Call N PHY TX Cal PHY Cleanup */ | 2475 | b43_nphy_tx_cal_phy_cleanup(dev); |
1710 | /* TODO: Write an N PHY Table with ID 7, length 2, offset 0x110, | 2476 | b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, save); |
1711 | width 16, and data from save */ | ||
1712 | 2477 | ||
1713 | if (dev->phy.rev < 2 && (!mphase || nphy->mphase_cal_phase_id == last)) | 2478 | if (dev->phy.rev < 2 && (!mphase || nphy->mphase_cal_phase_id == last)) |
1714 | b43_nphy_tx_iq_workaround(dev); | 2479 | b43_nphy_tx_iq_workaround(dev); |
@@ -1739,7 +2504,7 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev, | |||
1739 | u16 lna[3] = { 3, 3, 1 }; | 2504 | u16 lna[3] = { 3, 3, 1 }; |
1740 | u16 hpf1[3] = { 7, 2, 0 }; | 2505 | u16 hpf1[3] = { 7, 2, 0 }; |
1741 | u16 hpf2[3] = { 2, 0, 0 }; | 2506 | u16 hpf2[3] = { 2, 0, 0 }; |
1742 | u32 power[3]; | 2507 | u32 power[3] = { }; |
1743 | u16 gain_save[2]; | 2508 | u16 gain_save[2]; |
1744 | u16 cal_gain[2]; | 2509 | u16 cal_gain[2]; |
1745 | struct nphy_iqcal_params cal_params[2]; | 2510 | struct nphy_iqcal_params cal_params[2]; |
@@ -1752,14 +2517,12 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev, | |||
1752 | 2517 | ||
1753 | if (dev->phy.rev < 2) | 2518 | if (dev->phy.rev < 2) |
1754 | ;/* TODO: Call N PHY Reapply TX Cal Coeffs */ | 2519 | ;/* TODO: Call N PHY Reapply TX Cal Coeffs */ |
1755 | /* TODO: Read an N PHY Table with ID 7, length 2, offset 0x110, | 2520 | b43_ntab_read_bulk(dev, B43_NTAB16(7, 0x110), 2, gain_save); |
1756 | width 16, and data gain_save */ | ||
1757 | for (i = 0; i < 2; i++) { | 2521 | for (i = 0; i < 2; i++) { |
1758 | b43_nphy_iq_cal_gain_params(dev, i, target, &cal_params[i]); | 2522 | b43_nphy_iq_cal_gain_params(dev, i, target, &cal_params[i]); |
1759 | cal_gain[i] = cal_params[i].cal_gain; | 2523 | cal_gain[i] = cal_params[i].cal_gain; |
1760 | } | 2524 | } |
1761 | /* TODO: Write an N PHY Table with ID 7, length 2, offset 0x110, | 2525 | b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, cal_gain); |
1762 | width 16, and data from cal_gain */ | ||
1763 | 2526 | ||
1764 | for (i = 0; i < 2; i++) { | 2527 | for (i = 0; i < 2; i++) { |
1765 | if (i == 0) { | 2528 | if (i == 0) { |
@@ -1846,19 +2609,19 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev, | |||
1846 | 2609 | ||
1847 | tmp[0] = ((cur_hpf2 << 8) | (cur_hpf1 << 4) | | 2610 | tmp[0] = ((cur_hpf2 << 8) | (cur_hpf1 << 4) | |
1848 | (cur_lna << 2)); | 2611 | (cur_lna << 2)); |
1849 | /* TODO:Call N PHY RF Ctrl Override with 0x400, tmp[0], | 2612 | b43_nphy_rf_control_override(dev, 0x400, tmp[0], 3, |
1850 | 3, 0 as arguments */ | 2613 | false); |
1851 | /* TODO: Call N PHY Force RF Seq with 2 as argument */ | 2614 | b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); |
1852 | /* TODO: Call N PHT Stop Playback */ | 2615 | b43_nphy_stop_playback(dev); |
1853 | 2616 | ||
1854 | if (playtone) { | 2617 | if (playtone) { |
1855 | /* TODO: Call N PHY TX Tone with 4000, | 2618 | ret = b43_nphy_tx_tone(dev, 4000, |
1856 | (nphy_rxcalparams & 0xffff), 0, 0 | 2619 | (nphy->rxcalparams & 0xFFFF), |
1857 | as arguments and save result as ret */ | 2620 | false, false); |
1858 | playtone = false; | 2621 | playtone = false; |
1859 | } else { | 2622 | } else { |
1860 | /* TODO: Call N PHY Run Samples with 160, | 2623 | b43_nphy_run_samples(dev, 160, 0xFFFF, 0, |
1861 | 0xFFFF, 0, 0, 0 as arguments */ | 2624 | false, false); |
1862 | } | 2625 | } |
1863 | 2626 | ||
1864 | if (ret == 0) { | 2627 | if (ret == 0) { |
@@ -1876,7 +2639,7 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev, | |||
1876 | } else { | 2639 | } else { |
1877 | b43_nphy_calc_rx_iq_comp(dev, 1 << i); | 2640 | b43_nphy_calc_rx_iq_comp(dev, 1 << i); |
1878 | } | 2641 | } |
1879 | /* TODO: Call N PHY Stop Playback */ | 2642 | b43_nphy_stop_playback(dev); |
1880 | } | 2643 | } |
1881 | 2644 | ||
1882 | if (ret != 0) | 2645 | if (ret != 0) |
@@ -1895,10 +2658,9 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev, | |||
1895 | break; | 2658 | break; |
1896 | } | 2659 | } |
1897 | 2660 | ||
1898 | /* TODO: Call N PHY RF Ctrl Override with 0x400, 0, 3, 1 as arguments*/ | 2661 | b43_nphy_rf_control_override(dev, 0x400, 0, 3, true); |
1899 | /* TODO: Call N PHY Force RF Seq with 2 as argument */ | 2662 | b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); |
1900 | /* TODO: Write an N PHY Table with ID 7, length 2, offset 0x110, | 2663 | b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, gain_save); |
1901 | width 16, and data from gain_save */ | ||
1902 | 2664 | ||
1903 | b43_nphy_stay_in_carrier_search(dev, 0); | 2665 | b43_nphy_stay_in_carrier_search(dev, 0); |
1904 | 2666 | ||
@@ -1990,8 +2752,8 @@ int b43_phy_initn(struct b43_wldev *dev) | |||
1990 | b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x50); | 2752 | b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x50); |
1991 | b43_phy_write(dev, B43_NPHY_TXRIFS_FRDEL, 0x30); | 2753 | b43_phy_write(dev, B43_NPHY_TXRIFS_FRDEL, 0x30); |
1992 | 2754 | ||
1993 | /* TODO MIMO-Config */ | 2755 | b43_nphy_update_mimo_config(dev, nphy->preamble_override); |
1994 | /* TODO Update TX/RX chain */ | 2756 | b43_nphy_update_txrx_chain(dev); |
1995 | 2757 | ||
1996 | if (phy->rev < 2) { | 2758 | if (phy->rev < 2) { |
1997 | b43_phy_write(dev, B43_NPHY_DUP40_GFBL, 0xAA8); | 2759 | b43_phy_write(dev, B43_NPHY_DUP40_GFBL, 0xAA8); |
@@ -2007,9 +2769,9 @@ int b43_phy_initn(struct b43_wldev *dev) | |||
2007 | b43_phy_set(dev, B43_NPHY_PAPD_EN1, 0x1); | 2769 | b43_phy_set(dev, B43_NPHY_PAPD_EN1, 0x1); |
2008 | b43_phy_maskset(dev, B43_NPHY_EPS_TABLE_ADJ1, 0x007F, | 2770 | b43_phy_maskset(dev, B43_NPHY_EPS_TABLE_ADJ1, 0x007F, |
2009 | nphy->papd_epsilon_offset[1] << 7); | 2771 | nphy->papd_epsilon_offset[1] << 7); |
2010 | /* TODO N PHY IPA Set TX Dig Filters */ | 2772 | b43_nphy_int_pa_set_tx_dig_filters(dev); |
2011 | } else if (phy->rev >= 5) { | 2773 | } else if (phy->rev >= 5) { |
2012 | /* TODO N PHY Ext PA Set TX Dig Filters */ | 2774 | b43_nphy_ext_pa_set_tx_dig_filters(dev); |
2013 | } | 2775 | } |
2014 | 2776 | ||
2015 | b43_nphy_workarounds(dev); | 2777 | b43_nphy_workarounds(dev); |
@@ -2040,8 +2802,10 @@ int b43_phy_initn(struct b43_wldev *dev) | |||
2040 | if (phy->rev >= 3) { | 2802 | if (phy->rev >= 3) { |
2041 | /* TODO */ | 2803 | /* TODO */ |
2042 | } else { | 2804 | } else { |
2043 | /* TODO Write an N PHY table with ID 26, length 128, offset 192, width 32, and the data from Rev 2 TX Power Control Table */ | 2805 | b43_ntab_write_bulk(dev, B43_NTAB32(26, 192), 128, |
2044 | /* TODO Write an N PHY table with ID 27, length 128, offset 192, width 32, and the data from Rev 2 TX Power Control Table */ | 2806 | b43_ntab_tx_gain_rev0_1_2); |
2807 | b43_ntab_write_bulk(dev, B43_NTAB32(27, 192), 128, | ||
2808 | b43_ntab_tx_gain_rev0_1_2); | ||
2045 | } | 2809 | } |
2046 | 2810 | ||
2047 | if (nphy->phyrxchain != 3) | 2811 | if (nphy->phyrxchain != 3) |
diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h index 4572866756f..ae82f0fc209 100644 --- a/drivers/net/wireless/b43/phy_n.h +++ b/drivers/net/wireless/b43/phy_n.h | |||
@@ -973,6 +973,12 @@ struct b43_phy_n { | |||
973 | bool hang_avoid; | 973 | bool hang_avoid; |
974 | bool mute; | 974 | bool mute; |
975 | u16 papd_epsilon_offset[2]; | 975 | u16 papd_epsilon_offset[2]; |
976 | s32 preamble_override; | ||
977 | u32 bb_mult_save; | ||
978 | |||
979 | bool gain_boost; | ||
980 | bool elna_gain_config; | ||
981 | bool band5g_pwrgain; | ||
976 | 982 | ||
977 | u8 mphase_cal_phase_id; | 983 | u8 mphase_cal_phase_id; |
978 | u16 mphase_txcal_cmdidx; | 984 | u16 mphase_txcal_cmdidx; |
@@ -985,6 +991,7 @@ struct b43_phy_n { | |||
985 | bool txiqlocal_coeffsvalid; | 991 | bool txiqlocal_coeffsvalid; |
986 | struct b43_phy_n_txpwrindex txpwrindex[2]; | 992 | struct b43_phy_n_txpwrindex txpwrindex[2]; |
987 | 993 | ||
994 | u8 txrx_chain; | ||
988 | u16 tx_rx_cal_phy_saveregs[11]; | 995 | u16 tx_rx_cal_phy_saveregs[11]; |
989 | u16 tx_rx_cal_radio_saveregs[22]; | 996 | u16 tx_rx_cal_radio_saveregs[22]; |
990 | 997 | ||
diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c index 7dff853ab96..a00d509150f 100644 --- a/drivers/net/wireless/b43/tables_nphy.c +++ b/drivers/net/wireless/b43/tables_nphy.c | |||
@@ -2883,6 +2883,67 @@ const u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = { | |||
2883 | 0x9084, 0x9267, 0x9056, 0x9234 | 2883 | 0x9084, 0x9267, 0x9056, 0x9234 |
2884 | }; | 2884 | }; |
2885 | 2885 | ||
2886 | const s16 tbl_tx_filter_coef_rev4[7][15] = { | ||
2887 | { -377, 137, -407, 208, -1527, | ||
2888 | 956, 93, 186, 93, 230, | ||
2889 | -44, 230, 20, -191, 201 }, | ||
2890 | { -77, 20, -98, 49, -93, | ||
2891 | 60, 56, 111, 56, 26, | ||
2892 | -5, 26, 34, -32, 34 }, | ||
2893 | { -360, 164, -376, 164, -1533, | ||
2894 | 576, 308, -314, 308, 121, | ||
2895 | -73, 121, 91, 124, 91 }, | ||
2896 | { -295, 200, -363, 142, -1391, | ||
2897 | 826, 151, 301, 151, 151, | ||
2898 | 301, 151, 602, -752, 602 }, | ||
2899 | { -92, 58, -96, 49, -104, | ||
2900 | 44, 17, 35, 17, 12, | ||
2901 | 25, 12, 13, 27, 13 }, | ||
2902 | { -375, 136, -399, 209, -1479, | ||
2903 | 949, 130, 260, 130, 230, | ||
2904 | -44, 230, 201, -191, 201 }, | ||
2905 | { 0xed9, 0xc8, 0xe95, 0x8e, 0xa91, | ||
2906 | 0x33a, 0x97, 0x12d, 0x97, 0x97, | ||
2907 | 0x12d, 0x97, 0x25a, 0xd10, 0x25a } | ||
2908 | }; | ||
2909 | |||
2910 | /* addr0, addr1, bmask, shift */ | ||
2911 | const struct nphy_rf_control_override_rev2 tbl_rf_control_override_rev2[] = { | ||
2912 | { 0x78, 0x78, 0x0038, 3 }, /* for field == 0x0002 (fls == 2) */ | ||
2913 | { 0x7A, 0x7D, 0x0001, 0 }, /* for field == 0x0004 (fls == 3) */ | ||
2914 | { 0x7A, 0x7D, 0x0002, 1 }, /* for field == 0x0008 (fls == 4) */ | ||
2915 | { 0x7A, 0x7D, 0x0004, 2 }, /* for field == 0x0010 (fls == 5) */ | ||
2916 | { 0x7A, 0x7D, 0x0030, 4 }, /* for field == 0x0020 (fls == 6) */ | ||
2917 | { 0x7A, 0x7D, 0x00C0, 6 }, /* for field == 0x0040 (fls == 7) */ | ||
2918 | { 0x7A, 0x7D, 0x0100, 8 }, /* for field == 0x0080 (fls == 8) */ | ||
2919 | { 0x7A, 0x7D, 0x0200, 9 }, /* for field == 0x0100 (fls == 9) */ | ||
2920 | { 0x78, 0x78, 0x0004, 2 }, /* for field == 0x0200 (fls == 10) */ | ||
2921 | { 0x7B, 0x7E, 0x01FF, 0 }, /* for field == 0x0400 (fls == 11) */ | ||
2922 | { 0x7C, 0x7F, 0x01FF, 0 }, /* for field == 0x0800 (fls == 12) */ | ||
2923 | { 0x78, 0x78, 0x0100, 8 }, /* for field == 0x1000 (fls == 13) */ | ||
2924 | { 0x78, 0x78, 0x0200, 9 }, /* for field == 0x2000 (fls == 14) */ | ||
2925 | { 0x78, 0x78, 0xF000, 12 } /* for field == 0x4000 (fls == 15) */ | ||
2926 | }; | ||
2927 | |||
2928 | /* val_mask, val_shift, en_addr0, val_addr0, en_addr1, val_addr1 */ | ||
2929 | const struct nphy_rf_control_override_rev3 tbl_rf_control_override_rev3[] = { | ||
2930 | { 0x8000, 15, 0xE5, 0xF9, 0xE6, 0xFB }, /* field == 0x0001 (fls 1) */ | ||
2931 | { 0x0001, 0, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0002 (fls 2) */ | ||
2932 | { 0x0002, 1, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0004 (fls 3) */ | ||
2933 | { 0x0004, 2, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0008 (fls 4) */ | ||
2934 | { 0x0016, 4, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0010 (fls 5) */ | ||
2935 | { 0x0020, 5, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0020 (fls 6) */ | ||
2936 | { 0x0040, 6, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0040 (fls 7) */ | ||
2937 | { 0x0080, 6, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0080 (fls 8) */ | ||
2938 | { 0x0100, 7, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0100 (fls 9) */ | ||
2939 | { 0x0007, 0, 0xE7, 0xF8, 0xEC, 0xFA }, /* field == 0x0200 (fls 10) */ | ||
2940 | { 0x0070, 4, 0xE7, 0xF8, 0xEC, 0xFA }, /* field == 0x0400 (fls 11) */ | ||
2941 | { 0xE000, 13, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0800 (fls 12) */ | ||
2942 | { 0xFFFF, 0, 0xE7, 0x7B, 0xEC, 0x7E }, /* field == 0x1000 (fls 13) */ | ||
2943 | { 0xFFFF, 0, 0xE7, 0x7C, 0xEC, 0x7F }, /* field == 0x2000 (fls 14) */ | ||
2944 | { 0x00C0, 6, 0xE7, 0xF9, 0xEC, 0xFB } /* field == 0x4000 (fls 15) */ | ||
2945 | }; | ||
2946 | |||
2886 | static inline void assert_ntab_array_sizes(void) | 2947 | static inline void assert_ntab_array_sizes(void) |
2887 | { | 2948 | { |
2888 | #undef check | 2949 | #undef check |
@@ -2919,6 +2980,72 @@ static inline void assert_ntab_array_sizes(void) | |||
2919 | #undef check | 2980 | #undef check |
2920 | } | 2981 | } |
2921 | 2982 | ||
2983 | u32 b43_ntab_read(struct b43_wldev *dev, u32 offset) | ||
2984 | { | ||
2985 | u32 type, value; | ||
2986 | |||
2987 | type = offset & B43_NTAB_TYPEMASK; | ||
2988 | offset &= ~B43_NTAB_TYPEMASK; | ||
2989 | B43_WARN_ON(offset > 0xFFFF); | ||
2990 | |||
2991 | switch (type) { | ||
2992 | case B43_NTAB_8BIT: | ||
2993 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset); | ||
2994 | value = b43_phy_read(dev, B43_NPHY_TABLE_DATALO) & 0xFF; | ||
2995 | break; | ||
2996 | case B43_NTAB_16BIT: | ||
2997 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset); | ||
2998 | value = b43_phy_read(dev, B43_NPHY_TABLE_DATALO); | ||
2999 | break; | ||
3000 | case B43_NTAB_32BIT: | ||
3001 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset); | ||
3002 | value = b43_phy_read(dev, B43_NPHY_TABLE_DATAHI); | ||
3003 | value <<= 16; | ||
3004 | value |= b43_phy_read(dev, B43_NPHY_TABLE_DATALO); | ||
3005 | break; | ||
3006 | default: | ||
3007 | B43_WARN_ON(1); | ||
3008 | value = 0; | ||
3009 | } | ||
3010 | |||
3011 | return value; | ||
3012 | } | ||
3013 | |||
3014 | void b43_ntab_read_bulk(struct b43_wldev *dev, u32 offset, | ||
3015 | unsigned int nr_elements, void *_data) | ||
3016 | { | ||
3017 | u32 type; | ||
3018 | u8 *data = _data; | ||
3019 | unsigned int i; | ||
3020 | |||
3021 | type = offset & B43_NTAB_TYPEMASK; | ||
3022 | offset &= ~B43_NTAB_TYPEMASK; | ||
3023 | B43_WARN_ON(offset > 0xFFFF); | ||
3024 | |||
3025 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset); | ||
3026 | |||
3027 | for (i = 0; i < nr_elements; i++) { | ||
3028 | switch (type) { | ||
3029 | case B43_NTAB_8BIT: | ||
3030 | *data = b43_phy_read(dev, B43_NPHY_TABLE_DATALO) & 0xFF; | ||
3031 | data++; | ||
3032 | break; | ||
3033 | case B43_NTAB_16BIT: | ||
3034 | *((u16 *)data) = b43_phy_read(dev, B43_NPHY_TABLE_DATALO); | ||
3035 | data += 2; | ||
3036 | break; | ||
3037 | case B43_NTAB_32BIT: | ||
3038 | *((u32 *)data) = b43_phy_read(dev, B43_NPHY_TABLE_DATAHI); | ||
3039 | *((u32 *)data) <<= 16; | ||
3040 | *((u32 *)data) |= b43_phy_read(dev, B43_NPHY_TABLE_DATALO); | ||
3041 | data += 4; | ||
3042 | break; | ||
3043 | default: | ||
3044 | B43_WARN_ON(1); | ||
3045 | } | ||
3046 | } | ||
3047 | } | ||
3048 | |||
2922 | void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value) | 3049 | void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value) |
2923 | { | 3050 | { |
2924 | u32 type; | 3051 | u32 type; |
@@ -2952,6 +3079,46 @@ void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value) | |||
2952 | assert_ntab_array_sizes(); | 3079 | assert_ntab_array_sizes(); |
2953 | } | 3080 | } |
2954 | 3081 | ||
3082 | void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset, | ||
3083 | unsigned int nr_elements, const void *_data) | ||
3084 | { | ||
3085 | u32 type, value; | ||
3086 | const u8 *data = _data; | ||
3087 | unsigned int i; | ||
3088 | |||
3089 | type = offset & B43_NTAB_TYPEMASK; | ||
3090 | offset &= ~B43_NTAB_TYPEMASK; | ||
3091 | B43_WARN_ON(offset > 0xFFFF); | ||
3092 | |||
3093 | b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset); | ||
3094 | |||
3095 | for (i = 0; i < nr_elements; i++) { | ||
3096 | switch (type) { | ||
3097 | case B43_NTAB_8BIT: | ||
3098 | value = *data; | ||
3099 | data++; | ||
3100 | B43_WARN_ON(value & ~0xFF); | ||
3101 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, value); | ||
3102 | break; | ||
3103 | case B43_NTAB_16BIT: | ||
3104 | value = *((u16 *)data); | ||
3105 | data += 2; | ||
3106 | B43_WARN_ON(value & ~0xFFFF); | ||
3107 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, value); | ||
3108 | break; | ||
3109 | case B43_NTAB_32BIT: | ||
3110 | value = *((u32 *)data); | ||
3111 | data += 4; | ||
3112 | b43_phy_write(dev, B43_NPHY_TABLE_DATAHI, value >> 16); | ||
3113 | b43_phy_write(dev, B43_NPHY_TABLE_DATALO, | ||
3114 | value & 0xFFFF); | ||
3115 | break; | ||
3116 | default: | ||
3117 | B43_WARN_ON(1); | ||
3118 | } | ||
3119 | } | ||
3120 | } | ||
3121 | |||
2955 | #define ntab_upload(dev, offset, data) do { \ | 3122 | #define ntab_upload(dev, offset, data) do { \ |
2956 | unsigned int i; \ | 3123 | unsigned int i; \ |
2957 | for (i = 0; i < (offset##_SIZE); i++) \ | 3124 | for (i = 0; i < (offset##_SIZE); i++) \ |
diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h index 51636d02f8b..9c1c6ecd367 100644 --- a/drivers/net/wireless/b43/tables_nphy.h +++ b/drivers/net/wireless/b43/tables_nphy.h | |||
@@ -51,6 +51,22 @@ struct nphy_txiqcal_ladder { | |||
51 | u8 g_env; | 51 | u8 g_env; |
52 | }; | 52 | }; |
53 | 53 | ||
54 | struct nphy_rf_control_override_rev2 { | ||
55 | u8 addr0; | ||
56 | u8 addr1; | ||
57 | u16 bmask; | ||
58 | u8 shift; | ||
59 | }; | ||
60 | |||
61 | struct nphy_rf_control_override_rev3 { | ||
62 | u16 val_mask; | ||
63 | u8 val_shift; | ||
64 | u8 en_addr0; | ||
65 | u8 val_addr0; | ||
66 | u8 en_addr1; | ||
67 | u8 val_addr1; | ||
68 | }; | ||
69 | |||
54 | /* Upload the default register value table. | 70 | /* Upload the default register value table. |
55 | * If "ghz5" is true, we upload the 5Ghz table. Otherwise the 2.4Ghz | 71 | * If "ghz5" is true, we upload the 5Ghz table. Otherwise the 2.4Ghz |
56 | * table is uploaded. If "ignore_uploadflag" is true, we upload any value | 72 | * table is uploaded. If "ignore_uploadflag" is true, we upload any value |
@@ -142,7 +158,12 @@ b43_nphy_get_chantabent(struct b43_wldev *dev, u8 channel); | |||
142 | #define B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL 10 | 158 | #define B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL 10 |
143 | #define B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL_REV3 12 | 159 | #define B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL_REV3 12 |
144 | 160 | ||
161 | u32 b43_ntab_read(struct b43_wldev *dev, u32 offset); | ||
162 | void b43_ntab_read_bulk(struct b43_wldev *dev, u32 offset, | ||
163 | unsigned int nr_elements, void *_data); | ||
145 | void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value); | 164 | void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value); |
165 | void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset, | ||
166 | unsigned int nr_elements, const void *_data); | ||
146 | 167 | ||
147 | void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev); | 168 | void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev); |
148 | void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev); | 169 | void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev); |
@@ -172,5 +193,11 @@ extern const u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[]; | |||
172 | extern const u16 tbl_tx_iqlo_cal_cmds_recal[]; | 193 | extern const u16 tbl_tx_iqlo_cal_cmds_recal[]; |
173 | extern const u16 tbl_tx_iqlo_cal_cmds_fullcal[]; | 194 | extern const u16 tbl_tx_iqlo_cal_cmds_fullcal[]; |
174 | extern const u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[]; | 195 | extern const u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[]; |
196 | extern const s16 tbl_tx_filter_coef_rev4[7][15]; | ||
197 | |||
198 | extern const struct nphy_rf_control_override_rev2 | ||
199 | tbl_rf_control_override_rev2[]; | ||
200 | extern const struct nphy_rf_control_override_rev3 | ||
201 | tbl_rf_control_override_rev3[]; | ||
175 | 202 | ||
176 | #endif /* B43_TABLES_NPHY_H_ */ | 203 | #endif /* B43_TABLES_NPHY_H_ */ |