diff options
author | Rafał Miłecki <zajec5@gmail.com> | 2011-09-16 06:34:00 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-09-19 16:10:12 -0400 |
commit | 0c5644b98b54dd4d156aba098689adb2054205cd (patch) | |
tree | a878455b8b9d2e534eee7a52937d1d317db79e0d | |
parent | b534706a0692912e72d4be78f45be57c5b231ed5 (diff) |
b43: LCN-PHY: set TX filters
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/b43/phy_lcn.c | 107 |
1 files changed, 106 insertions, 1 deletions
diff --git a/drivers/net/wireless/b43/phy_lcn.c b/drivers/net/wireless/b43/phy_lcn.c index 06d8efc2f29..76503646120 100644 --- a/drivers/net/wireless/b43/phy_lcn.c +++ b/drivers/net/wireless/b43/phy_lcn.c | |||
@@ -37,6 +37,11 @@ | |||
37 | #include "tables_phy_lcn.h" | 37 | #include "tables_phy_lcn.h" |
38 | #include "main.h" | 38 | #include "main.h" |
39 | 39 | ||
40 | struct lcn_tx_iir_filter { | ||
41 | u8 type; | ||
42 | u16 values[16]; | ||
43 | }; | ||
44 | |||
40 | /************************************************** | 45 | /************************************************** |
41 | * Radio 2064. | 46 | * Radio 2064. |
42 | **************************************************/ | 47 | **************************************************/ |
@@ -282,6 +287,86 @@ static void b43_phy_lcn_sense_setup(struct b43_wldev *dev) | |||
282 | b43_radio_write(dev, 0x4a4, save_radio_4a4); | 287 | b43_radio_write(dev, 0x4a4, save_radio_4a4); |
283 | } | 288 | } |
284 | 289 | ||
290 | static bool b43_phy_lcn_load_tx_iir_cck_filter(struct b43_wldev *dev, | ||
291 | u8 filter_type) | ||
292 | { | ||
293 | int i, j; | ||
294 | u16 phy_regs[] = { 0x910, 0x91e, 0x91f, 0x924, 0x925, 0x926, 0x920, | ||
295 | 0x921, 0x927, 0x928, 0x929, 0x922, 0x923, 0x930, | ||
296 | 0x931, 0x932 }; | ||
297 | /* Table is from brcmsmac, values for type 25 were outdated, probably | ||
298 | * others need updating too */ | ||
299 | struct lcn_tx_iir_filter tx_iir_filters_cck[] = { | ||
300 | { 0, { 1, 415, 1874, 64, 128, 64, 792, 1656, 64, 128, 64, 778, | ||
301 | 1582, 64, 128, 64 } }, | ||
302 | { 1, { 1, 402, 1847, 259, 59, 259, 671, 1794, 68, 54, 68, 608, | ||
303 | 1863, 93, 167, 93 } }, | ||
304 | { 2, { 1, 415, 1874, 64, 128, 64, 792, 1656, 192, 384, 192, | ||
305 | 778, 1582, 64, 128, 64 } }, | ||
306 | { 3, { 1, 302, 1841, 129, 258, 129, 658, 1720, 205, 410, 205, | ||
307 | 754, 1760, 170, 340, 170 } }, | ||
308 | { 20, { 1, 360, 1884, 242, 1734, 242, 752, 1720, 205, 1845, 205, | ||
309 | 767, 1760, 256, 185, 256 } }, | ||
310 | { 21, { 1, 360, 1884, 149, 1874, 149, 752, 1720, 205, 1883, 205, | ||
311 | 767, 1760, 256, 273, 256 } }, | ||
312 | { 22, { 1, 360, 1884, 98, 1948, 98, 752, 1720, 205, 1924, 205, | ||
313 | 767, 1760, 256, 352, 256 } }, | ||
314 | { 23, { 1, 350, 1884, 116, 1966, 116, 752, 1720, 205, 2008, 205, | ||
315 | 767, 1760, 128, 233, 128 } }, | ||
316 | { 24, { 1, 325, 1884, 32, 40, 32, 756, 1720, 256, 471, 256, 766, | ||
317 | 1760, 256, 1881, 256 } }, | ||
318 | { 25, { 1, 299, 1884, 51, 64, 51, 736, 1720, 256, 471, 256, 765, | ||
319 | 1760, 262, 1878, 262 } }, | ||
320 | /* brcmsmac version { 25, { 1, 299, 1884, 51, 64, 51, 736, 1720, | ||
321 | * 256, 471, 256, 765, 1760, 256, 1881, 256 } }, */ | ||
322 | { 26, { 1, 277, 1943, 39, 117, 88, 637, 1838, 64, 192, 144, 614, | ||
323 | 1864, 128, 384, 288 } }, | ||
324 | { 27, { 1, 245, 1943, 49, 147, 110, 626, 1838, 256, 768, 576, | ||
325 | 613, 1864, 128, 384, 288 } }, | ||
326 | { 30, { 1, 302, 1841, 61, 122, 61, 658, 1720, 205, 410, 205, | ||
327 | 754, 1760, 170, 340, 170 } }, | ||
328 | }; | ||
329 | |||
330 | for (i = 0; i < ARRAY_SIZE(tx_iir_filters_cck); i++) { | ||
331 | if (tx_iir_filters_cck[i].type == filter_type) { | ||
332 | for (j = 0; j < 16; j++) | ||
333 | b43_phy_write(dev, phy_regs[j], | ||
334 | tx_iir_filters_cck[i].values[j]); | ||
335 | return true; | ||
336 | } | ||
337 | } | ||
338 | |||
339 | return false; | ||
340 | } | ||
341 | |||
342 | static bool b43_phy_lcn_load_tx_iir_ofdm_filter(struct b43_wldev *dev, | ||
343 | u8 filter_type) | ||
344 | { | ||
345 | int i, j; | ||
346 | u16 phy_regs[] = { 0x90f, 0x900, 0x901, 0x906, 0x907, 0x908, 0x902, | ||
347 | 0x903, 0x909, 0x90a, 0x90b, 0x904, 0x905, 0x90c, | ||
348 | 0x90d, 0x90e }; | ||
349 | struct lcn_tx_iir_filter tx_iir_filters_ofdm[] = { | ||
350 | { 0, { 0, 0xa2, 0x0, 0x100, 0x100, 0x0, 0x0, 0x0, 0x100, 0x0, | ||
351 | 0x0, 0x278, 0xfea0, 0x80, 0x100, 0x80 } }, | ||
352 | { 1, { 0, 374, 0xFF79, 16, 32, 16, 799, 0xFE74, 50, 32, 50, 750, | ||
353 | 0xFE2B, 212, 0xFFCE, 212 } }, | ||
354 | { 2, { 0, 375, 0xFF16, 37, 76, 37, 799, 0xFE74, 32, 20, 32, 748, | ||
355 | 0xFEF2, 128, 0xFFE2, 128 } }, | ||
356 | }; | ||
357 | |||
358 | for (i = 0; i < ARRAY_SIZE(tx_iir_filters_ofdm); i++) { | ||
359 | if (tx_iir_filters_ofdm[i].type == filter_type) { | ||
360 | for (j = 0; j < 16; j++) | ||
361 | b43_phy_write(dev, phy_regs[j], | ||
362 | tx_iir_filters_ofdm[i].values[j]); | ||
363 | return true; | ||
364 | } | ||
365 | } | ||
366 | |||
367 | return false; | ||
368 | } | ||
369 | |||
285 | /************************************************** | 370 | /************************************************** |
286 | * Channel switching ops. | 371 | * Channel switching ops. |
287 | **************************************************/ | 372 | **************************************************/ |
@@ -329,6 +414,12 @@ static int b43_phy_lcn_set_channel(struct b43_wldev *dev, | |||
329 | struct ieee80211_channel *channel, | 414 | struct ieee80211_channel *channel, |
330 | enum nl80211_channel_type channel_type) | 415 | enum nl80211_channel_type channel_type) |
331 | { | 416 | { |
417 | static const u16 sfo_cfg[14][2] = { | ||
418 | {965, 1087}, {967, 1085}, {969, 1082}, {971, 1080}, {973, 1078}, | ||
419 | {975, 1076}, {977, 1073}, {979, 1071}, {981, 1069}, {983, 1067}, | ||
420 | {985, 1065}, {987, 1063}, {989, 1060}, {994, 1055}, | ||
421 | }; | ||
422 | |||
332 | b43_phy_lcn_set_channel_tweaks(dev, channel->hw_value); | 423 | b43_phy_lcn_set_channel_tweaks(dev, channel->hw_value); |
333 | 424 | ||
334 | b43_phy_set(dev, 0x44a, 0x44); | 425 | b43_phy_set(dev, 0x44a, 0x44); |
@@ -339,7 +430,21 @@ static int b43_phy_lcn_set_channel(struct b43_wldev *dev, | |||
339 | 430 | ||
340 | b43_phy_lcn_afe_set_unset(dev); | 431 | b43_phy_lcn_afe_set_unset(dev); |
341 | 432 | ||
342 | /* TODO */ | 433 | b43_phy_write(dev, 0x657, sfo_cfg[channel->hw_value - 1][0]); |
434 | b43_phy_write(dev, 0x658, sfo_cfg[channel->hw_value - 1][1]); | ||
435 | |||
436 | if (channel->hw_value == 14) { | ||
437 | b43_phy_maskset(dev, 0x448, ~(0x3 << 8), (2) << 8); | ||
438 | b43_phy_lcn_load_tx_iir_cck_filter(dev, 3); | ||
439 | } else { | ||
440 | b43_phy_maskset(dev, 0x448, ~(0x3 << 8), (1) << 8); | ||
441 | /* brcmsmac uses filter_type 2, we follow wl with 25 */ | ||
442 | b43_phy_lcn_load_tx_iir_cck_filter(dev, 25); | ||
443 | } | ||
444 | /* brcmsmac uses filter_type 2, we follow wl with 0 */ | ||
445 | b43_phy_lcn_load_tx_iir_ofdm_filter(dev, 0); | ||
446 | |||
447 | b43_phy_maskset(dev, 0x4eb, ~(0x7 << 3), 0x1 << 3); | ||
343 | 448 | ||
344 | return 0; | 449 | return 0; |
345 | } | 450 | } |