diff options
author | Rafał Miłecki <zajec5@gmail.com> | 2010-01-21 19:53:13 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-01-22 16:11:37 -0500 |
commit | 75377b2476d85d90c0db07e780ee95741cff3a2d (patch) | |
tree | a5a104387be23f3140307cc8ec93d2ca474e9f6e /drivers | |
parent | aa4c7b2a2547db95388f795f092ea286fbdd98a1 (diff) |
b43: N-PHY: implement overriding RF control
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/b43/phy_n.c | 82 | ||||
-rw-r--r-- | drivers/net/wireless/b43/tables_nphy.c | 37 | ||||
-rw-r--r-- | drivers/net/wireless/b43/tables_nphy.h | 21 |
3 files changed, 137 insertions, 3 deletions
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 2cdf32e5fd9b..d3c9783b76ba 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c | |||
@@ -912,6 +912,82 @@ ok: | |||
912 | b43_phy_write(dev, B43_NPHY_RFSEQMODE, seq_mode); | 912 | b43_phy_write(dev, B43_NPHY_RFSEQMODE, seq_mode); |
913 | } | 913 | } |
914 | 914 | ||
915 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverride */ | ||
916 | static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field, | ||
917 | u16 value, u8 core, bool off) | ||
918 | { | ||
919 | int i; | ||
920 | u8 index = fls(field); | ||
921 | u8 addr, en_addr, val_addr; | ||
922 | /* we expect only one bit set */ | ||
923 | B43_WARN_ON(field & (~(1 << index))); | ||
924 | |||
925 | if (dev->phy.rev >= 3) { | ||
926 | const struct nphy_rf_control_override_rev3 *rf_ctrl; | ||
927 | for (i = 0; i < 2; i++) { | ||
928 | if (index == 0 || index == 16) { | ||
929 | b43err(dev->wl, | ||
930 | "Unsupported RF Ctrl Override call\n"); | ||
931 | return; | ||
932 | } | ||
933 | |||
934 | rf_ctrl = &tbl_rf_control_override_rev3[index - 1]; | ||
935 | en_addr = B43_PHY_N((i == 0) ? | ||
936 | rf_ctrl->en_addr0 : rf_ctrl->en_addr1); | ||
937 | val_addr = B43_PHY_N((i == 0) ? | ||
938 | rf_ctrl->val_addr0 : rf_ctrl->val_addr1); | ||
939 | |||
940 | if (off) { | ||
941 | b43_phy_mask(dev, en_addr, ~(field)); | ||
942 | b43_phy_mask(dev, val_addr, | ||
943 | ~(rf_ctrl->val_mask)); | ||
944 | } else { | ||
945 | if (core == 0 || ((1 << core) & i) != 0) { | ||
946 | b43_phy_set(dev, en_addr, field); | ||
947 | b43_phy_maskset(dev, val_addr, | ||
948 | ~(rf_ctrl->val_mask), | ||
949 | (value << rf_ctrl->val_shift)); | ||
950 | } | ||
951 | } | ||
952 | } | ||
953 | } else { | ||
954 | const struct nphy_rf_control_override_rev2 *rf_ctrl; | ||
955 | if (off) { | ||
956 | b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, ~(field)); | ||
957 | value = 0; | ||
958 | } else { | ||
959 | b43_phy_set(dev, B43_NPHY_RFCTL_OVER, field); | ||
960 | } | ||
961 | |||
962 | for (i = 0; i < 2; i++) { | ||
963 | if (index <= 1 || index == 16) { | ||
964 | b43err(dev->wl, | ||
965 | "Unsupported RF Ctrl Override call\n"); | ||
966 | return; | ||
967 | } | ||
968 | |||
969 | if (index == 2 || index == 10 || | ||
970 | (index >= 13 && index <= 15)) { | ||
971 | core = 1; | ||
972 | } | ||
973 | |||
974 | rf_ctrl = &tbl_rf_control_override_rev2[index - 2]; | ||
975 | addr = B43_PHY_N((i == 0) ? | ||
976 | rf_ctrl->addr0 : rf_ctrl->addr1); | ||
977 | |||
978 | if ((core & (1 << i)) != 0) | ||
979 | b43_phy_maskset(dev, addr, ~(rf_ctrl->bmask), | ||
980 | (value << rf_ctrl->shift)); | ||
981 | |||
982 | b43_phy_set(dev, B43_NPHY_RFCTL_OVER, 0x1); | ||
983 | b43_phy_set(dev, B43_NPHY_RFCTL_CMD, | ||
984 | B43_NPHY_RFCTL_CMD_START); | ||
985 | udelay(1); | ||
986 | b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, 0xFFFE); | ||
987 | } | ||
988 | } | ||
989 | } | ||
990 | |||
915 | static void b43_nphy_bphy_init(struct b43_wldev *dev) | 991 | static void b43_nphy_bphy_init(struct b43_wldev *dev) |
916 | { | 992 | { |
917 | unsigned int i; | 993 | unsigned int i; |
@@ -2075,8 +2151,8 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev, | |||
2075 | 2151 | ||
2076 | tmp[0] = ((cur_hpf2 << 8) | (cur_hpf1 << 4) | | 2152 | tmp[0] = ((cur_hpf2 << 8) | (cur_hpf1 << 4) | |
2077 | (cur_lna << 2)); | 2153 | (cur_lna << 2)); |
2078 | /* TODO:Call N PHY RF Ctrl Override with 0x400, tmp[0], | 2154 | b43_nphy_rf_control_override(dev, 0x400, tmp[0], 3, |
2079 | 3, 0 as arguments */ | 2155 | false); |
2080 | b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); | 2156 | b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); |
2081 | b43_nphy_stop_playback(dev); | 2157 | b43_nphy_stop_playback(dev); |
2082 | 2158 | ||
@@ -2124,7 +2200,7 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev, | |||
2124 | break; | 2200 | break; |
2125 | } | 2201 | } |
2126 | 2202 | ||
2127 | /* TODO: Call N PHY RF Ctrl Override with 0x400, 0, 3, 1 as arguments*/ | 2203 | b43_nphy_rf_control_override(dev, 0x400, 0, 3, true); |
2128 | b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); | 2204 | b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); |
2129 | b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, gain_save); | 2205 | b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, gain_save); |
2130 | 2206 | ||
diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c index b8c9fc619ab1..dd9687d611d7 100644 --- a/drivers/net/wireless/b43/tables_nphy.c +++ b/drivers/net/wireless/b43/tables_nphy.c | |||
@@ -2883,6 +2883,43 @@ const u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = { | |||
2883 | 0x9084, 0x9267, 0x9056, 0x9234 | 2883 | 0x9084, 0x9267, 0x9056, 0x9234 |
2884 | }; | 2884 | }; |
2885 | 2885 | ||
2886 | /* addr0, addr1, bmask, shift */ | ||
2887 | const struct nphy_rf_control_override_rev2 tbl_rf_control_override_rev2[] = { | ||
2888 | { 0x78, 0x78, 0x0038, 3 }, /* for field == 0x0002 (fls == 2) */ | ||
2889 | { 0x7A, 0x7D, 0x0001, 0 }, /* for field == 0x0004 (fls == 3) */ | ||
2890 | { 0x7A, 0x7D, 0x0002, 1 }, /* for field == 0x0008 (fls == 4) */ | ||
2891 | { 0x7A, 0x7D, 0x0004, 2 }, /* for field == 0x0010 (fls == 5) */ | ||
2892 | { 0x7A, 0x7D, 0x0030, 4 }, /* for field == 0x0020 (fls == 6) */ | ||
2893 | { 0x7A, 0x7D, 0x00C0, 6 }, /* for field == 0x0040 (fls == 7) */ | ||
2894 | { 0x7A, 0x7D, 0x0100, 8 }, /* for field == 0x0080 (fls == 8) */ | ||
2895 | { 0x7A, 0x7D, 0x0200, 9 }, /* for field == 0x0100 (fls == 9) */ | ||
2896 | { 0x78, 0x78, 0x0004, 2 }, /* for field == 0x0200 (fls == 10) */ | ||
2897 | { 0x7B, 0x7E, 0x01FF, 0 }, /* for field == 0x0400 (fls == 11) */ | ||
2898 | { 0x7C, 0x7F, 0x01FF, 0 }, /* for field == 0x0800 (fls == 12) */ | ||
2899 | { 0x78, 0x78, 0x0100, 8 }, /* for field == 0x1000 (fls == 13) */ | ||
2900 | { 0x78, 0x78, 0x0200, 9 }, /* for field == 0x2000 (fls == 14) */ | ||
2901 | { 0x78, 0x78, 0xF000, 12 } /* for field == 0x4000 (fls == 15) */ | ||
2902 | }; | ||
2903 | |||
2904 | /* val_mask, val_shift, en_addr0, val_addr0, en_addr1, val_addr1 */ | ||
2905 | const struct nphy_rf_control_override_rev3 tbl_rf_control_override_rev3[] = { | ||
2906 | { 0x8000, 15, 0xE5, 0xF9, 0xE6, 0xFB }, /* field == 0x0001 (fls 1) */ | ||
2907 | { 0x0001, 0, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0002 (fls 2) */ | ||
2908 | { 0x0002, 1, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0004 (fls 3) */ | ||
2909 | { 0x0004, 2, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0008 (fls 4) */ | ||
2910 | { 0x0016, 4, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0010 (fls 5) */ | ||
2911 | { 0x0020, 5, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0020 (fls 6) */ | ||
2912 | { 0x0040, 6, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0040 (fls 7) */ | ||
2913 | { 0x0080, 6, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0080 (fls 8) */ | ||
2914 | { 0x0100, 7, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0100 (fls 9) */ | ||
2915 | { 0x0007, 0, 0xE7, 0xF8, 0xEC, 0xFA }, /* field == 0x0200 (fls 10) */ | ||
2916 | { 0x0070, 4, 0xE7, 0xF8, 0xEC, 0xFA }, /* field == 0x0400 (fls 11) */ | ||
2917 | { 0xE000, 13, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0800 (fls 12) */ | ||
2918 | { 0xFFFF, 0, 0xE7, 0x7B, 0xEC, 0x7E }, /* field == 0x1000 (fls 13) */ | ||
2919 | { 0xFFFF, 0, 0xE7, 0x7C, 0xEC, 0x7F }, /* field == 0x2000 (fls 14) */ | ||
2920 | { 0x00C0, 6, 0xE7, 0xF9, 0xEC, 0xFB } /* field == 0x4000 (fls 15) */ | ||
2921 | }; | ||
2922 | |||
2886 | static inline void assert_ntab_array_sizes(void) | 2923 | static inline void assert_ntab_array_sizes(void) |
2887 | { | 2924 | { |
2888 | #undef check | 2925 | #undef check |
diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h index 6bbef894010c..5d38172a152d 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 |
@@ -178,4 +194,9 @@ extern const u16 tbl_tx_iqlo_cal_cmds_recal[]; | |||
178 | extern const u16 tbl_tx_iqlo_cal_cmds_fullcal[]; | 194 | extern const u16 tbl_tx_iqlo_cal_cmds_fullcal[]; |
179 | extern const u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[]; | 195 | extern const u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[]; |
180 | 196 | ||
197 | extern const struct nphy_rf_control_override_rev2 | ||
198 | tbl_rf_control_override_rev2[]; | ||
199 | extern const struct nphy_rf_control_override_rev3 | ||
200 | tbl_rf_control_override_rev3[]; | ||
201 | |||
181 | #endif /* B43_TABLES_NPHY_H_ */ | 202 | #endif /* B43_TABLES_NPHY_H_ */ |