aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorRafał Miłecki <zajec5@gmail.com>2012-07-26 04:25:09 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-08-06 15:01:56 -0400
commitc071b9f666beee2b27b5a4667f099026ca539bd7 (patch)
treee33e03aacc02fa03424c748dbd5aae518a99aa88 /drivers/net
parent2fdf8c54ea6ea161fa519a701188cbc56a3bb106 (diff)
b43: N-PHY: add overriding RF control for rev7+
Signed-off-by: Rafał Miłecki <zajec5@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/b43/phy_n.c48
-rw-r--r--drivers/net/wireless/b43/tables_nphy.c75
-rw-r--r--drivers/net/wireless/b43/tables_nphy.h10
3 files changed, 129 insertions, 4 deletions
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 113d5ca6623b..5c9074142a8e 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -127,6 +127,46 @@ ok:
127 b43_phy_write(dev, B43_NPHY_RFSEQMODE, seq_mode); 127 b43_phy_write(dev, B43_NPHY_RFSEQMODE, seq_mode);
128} 128}
129 129
130/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverrideRev7 */
131static void b43_nphy_rf_control_override_rev7(struct b43_wldev *dev, u16 field,
132 u16 value, u8 core, bool off,
133 u8 override)
134{
135 const struct nphy_rf_control_override_rev7 *e;
136 u16 en_addrs[3][2] = {
137 { 0x0E7, 0x0EC }, { 0x342, 0x343 }, { 0x346, 0x347 }
138 };
139 u16 en_addr;
140 u16 en_mask = field;
141 u16 val_addr;
142 u8 i;
143
144 /* Remember: we can get NULL! */
145 e = b43_nphy_get_rf_ctl_over_rev7(dev, field, override);
146
147 for (i = 0; i < 2; i++) {
148 if (override >= ARRAY_SIZE(en_addrs)) {
149 b43err(dev->wl, "Invalid override value %d\n", override);
150 return;
151 }
152 en_addr = en_addrs[override][i];
153
154 val_addr = (i == 0) ? e->val_addr_core0 : e->val_addr_core1;
155
156 if (off) {
157 b43_phy_mask(dev, en_addr, ~en_mask);
158 if (e) /* Do it safer, better than wl */
159 b43_phy_mask(dev, val_addr, ~e->val_mask);
160 } else {
161 if (!core || (core & (1 << i))) {
162 b43_phy_set(dev, en_addr, en_mask);
163 if (e)
164 b43_phy_maskset(dev, val_addr, ~e->val_mask, (value << e->val_shift));
165 }
166 }
167 }
168}
169
130/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverride */ 170/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverride */
131static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field, 171static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field,
132 u16 value, u8 core, bool off) 172 u16 value, u8 core, bool off)
@@ -2219,11 +2259,11 @@ static void b43_nphy_workarounds_rev7plus(struct b43_wldev *dev)
2219 b43_ntab_write(dev, B43_NTAB16(7, 0x159 + core * 16), 2259 b43_ntab_write(dev, B43_NTAB16(7, 0x159 + core * 16),
2220 rx2tx_lut_40_11n); 2260 rx2tx_lut_40_11n);
2221 } 2261 }
2222 /* b43_nphy_rf_control_override_rev7(dev, 16, 1, 3, 0, 2); */ 2262 b43_nphy_rf_control_override_rev7(dev, 16, 1, 3, false, 2);
2223 } 2263 }
2224 b43_phy_write(dev, 0x32F, 0x3); 2264 b43_phy_write(dev, 0x32F, 0x3);
2225 if (phy->radio_rev == 4 || phy->radio_rev == 6) 2265 if (phy->radio_rev == 4 || phy->radio_rev == 6)
2226 ; /* b43_nphy_rf_control_override_rev7(dev, 4, 1, 3, 0, 0); */ 2266 b43_nphy_rf_control_override_rev7(dev, 4, 1, 3, false, 0);
2227 2267
2228 if (phy->radio_rev == 3 || phy->radio_rev == 4 || phy->radio_rev == 6) { 2268 if (phy->radio_rev == 3 || phy->radio_rev == 4 || phy->radio_rev == 6) {
2229 if (sprom->revision && 2269 if (sprom->revision &&
@@ -3083,7 +3123,7 @@ static void b43_nphy_tx_power_ctl_idle_tssi(struct b43_wldev *dev)
3083 b43_nphy_ipa_internal_tssi_setup(dev); 3123 b43_nphy_ipa_internal_tssi_setup(dev);
3084 3124
3085 if (phy->rev >= 7) 3125 if (phy->rev >= 7)
3086 ; /* TODO: Override Rev7 with 0x2000, 0, 3, 0, 0 as arguments */ 3126 b43_nphy_rf_control_override_rev7(dev, 0x2000, 0, 3, false, 0);
3087 else if (phy->rev >= 3) 3127 else if (phy->rev >= 3)
3088 b43_nphy_rf_control_override(dev, 0x2000, 0, 3, false); 3128 b43_nphy_rf_control_override(dev, 0x2000, 0, 3, false);
3089 3129
@@ -3095,7 +3135,7 @@ static void b43_nphy_tx_power_ctl_idle_tssi(struct b43_wldev *dev)
3095 b43_nphy_rssi_select(dev, 0, 0); 3135 b43_nphy_rssi_select(dev, 0, 0);
3096 3136
3097 if (phy->rev >= 7) 3137 if (phy->rev >= 7)
3098 ; /* TODO: Override Rev7 with 0x2000, 0, 3, 1, 0 as arguments */ 3138 b43_nphy_rf_control_override_rev7(dev, 0x2000, 0, 3, true, 0);
3099 else if (phy->rev >= 3) 3139 else if (phy->rev >= 3)
3100 b43_nphy_rf_control_override(dev, 0x2000, 0, 3, true); 3140 b43_nphy_rf_control_override(dev, 0x2000, 0, 3, true);
3101 3141
diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c
index f0d8377429c6..97d4e27bf36f 100644
--- a/drivers/net/wireless/b43/tables_nphy.c
+++ b/drivers/net/wireless/b43/tables_nphy.c
@@ -2757,6 +2757,49 @@ const struct nphy_rf_control_override_rev3 tbl_rf_control_override_rev3[] = {
2757 { 0x00C0, 6, 0xE7, 0xF9, 0xEC, 0xFB } /* field == 0x4000 (fls 15) */ 2757 { 0x00C0, 6, 0xE7, 0xF9, 0xEC, 0xFB } /* field == 0x4000 (fls 15) */
2758}; 2758};
2759 2759
2760/* field, val_addr_core0, val_addr_core1, val_mask, val_shift */
2761static const struct nphy_rf_control_override_rev7
2762 tbl_rf_control_override_rev7_over0[] = {
2763 { 0x0004, 0x07A, 0x07D, 0x0002, 1 },
2764 { 0x0008, 0x07A, 0x07D, 0x0004, 2 },
2765 { 0x0010, 0x07A, 0x07D, 0x0010, 4 },
2766 { 0x0020, 0x07A, 0x07D, 0x0020, 5 },
2767 { 0x0040, 0x07A, 0x07D, 0x0040, 6 },
2768 { 0x0080, 0x0F8, 0x0FA, 0x0080, 7 },
2769 { 0x0400, 0x0F8, 0x0FA, 0x0070, 4 },
2770 { 0x0800, 0x07B, 0x07E, 0xFFFF, 0 },
2771 { 0x1000, 0x07C, 0x07F, 0xFFFF, 0 },
2772 { 0x6000, 0x348, 0x349, 0xFFFF, 0 },
2773 { 0x2000, 0x348, 0x349, 0x000F, 0 },
2774};
2775
2776/* field, val_addr_core0, val_addr_core1, val_mask, val_shift */
2777static const struct nphy_rf_control_override_rev7
2778 tbl_rf_control_override_rev7_over1[] = {
2779 { 0x0002, 0x340, 0x341, 0x0002, 1 },
2780 { 0x0008, 0x340, 0x341, 0x0008, 3 },
2781 { 0x0020, 0x340, 0x341, 0x0020, 5 },
2782 { 0x0010, 0x340, 0x341, 0x0010, 4 },
2783 { 0x0004, 0x340, 0x341, 0x0004, 2 },
2784 { 0x0080, 0x340, 0x341, 0x0700, 8 },
2785 { 0x0800, 0x340, 0x341, 0x4000, 14 },
2786 { 0x0400, 0x340, 0x341, 0x2000, 13 },
2787 { 0x0200, 0x340, 0x341, 0x0800, 12 },
2788 { 0x0100, 0x340, 0x341, 0x0100, 11 },
2789 { 0x0040, 0x340, 0x341, 0x0040, 6 },
2790 { 0x0001, 0x340, 0x341, 0x0001, 0 },
2791};
2792
2793/* field, val_addr_core0, val_addr_core1, val_mask, val_shift */
2794static const struct nphy_rf_control_override_rev7
2795 tbl_rf_control_override_rev7_over2[] = {
2796 { 0x0008, 0x344, 0x345, 0x0008, 3 },
2797 { 0x0002, 0x344, 0x345, 0x0002, 1 },
2798 { 0x0001, 0x344, 0x345, 0x0001, 0 },
2799 { 0x0004, 0x344, 0x345, 0x0004, 2 },
2800 { 0x0010, 0x344, 0x345, 0x0010, 4 },
2801};
2802
2760struct nphy_gain_ctl_workaround_entry nphy_gain_ctl_wa_phy6_radio11_ghz2 = { 2803struct nphy_gain_ctl_workaround_entry nphy_gain_ctl_wa_phy6_radio11_ghz2 = {
2761 { 10, 14, 19, 27 }, 2804 { 10, 14, 19, 27 },
2762 { -5, 6, 10, 15 }, 2805 { -5, 6, 10, 15 },
@@ -3248,3 +3291,35 @@ struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent(
3248 3291
3249 return e; 3292 return e;
3250} 3293}
3294
3295const struct nphy_rf_control_override_rev7 *b43_nphy_get_rf_ctl_over_rev7(
3296 struct b43_wldev *dev, u16 field, u8 override)
3297{
3298 const struct nphy_rf_control_override_rev7 *e;
3299 u8 size, i;
3300
3301 switch (override) {
3302 case 0:
3303 e = tbl_rf_control_override_rev7_over0;
3304 size = ARRAY_SIZE(tbl_rf_control_override_rev7_over0);
3305 break;
3306 case 1:
3307 e = tbl_rf_control_override_rev7_over1;
3308 size = ARRAY_SIZE(tbl_rf_control_override_rev7_over1);
3309 break;
3310 case 2:
3311 e = tbl_rf_control_override_rev7_over2;
3312 size = ARRAY_SIZE(tbl_rf_control_override_rev7_over2);
3313 break;
3314 default:
3315 b43err(dev->wl, "Invalid override value %d\n", override);
3316 return NULL;
3317 }
3318
3319 for (i = 0; i < size; i++) {
3320 if (e[i].field == field)
3321 return &e[i];
3322 }
3323
3324 return NULL;
3325}
diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h
index f348953c0230..c600700ceedc 100644
--- a/drivers/net/wireless/b43/tables_nphy.h
+++ b/drivers/net/wireless/b43/tables_nphy.h
@@ -35,6 +35,14 @@ struct nphy_rf_control_override_rev3 {
35 u8 val_addr1; 35 u8 val_addr1;
36}; 36};
37 37
38struct nphy_rf_control_override_rev7 {
39 u16 field;
40 u16 val_addr_core0;
41 u16 val_addr_core1;
42 u16 val_mask;
43 u8 val_shift;
44};
45
38struct nphy_gain_ctl_workaround_entry { 46struct nphy_gain_ctl_workaround_entry {
39 s8 lna1_gain[4]; 47 s8 lna1_gain[4];
40 s8 lna2_gain[4]; 48 s8 lna2_gain[4];
@@ -202,5 +210,7 @@ extern const struct nphy_rf_control_override_rev2
202 tbl_rf_control_override_rev2[]; 210 tbl_rf_control_override_rev2[];
203extern const struct nphy_rf_control_override_rev3 211extern const struct nphy_rf_control_override_rev3
204 tbl_rf_control_override_rev3[]; 212 tbl_rf_control_override_rev3[];
213const struct nphy_rf_control_override_rev7 *b43_nphy_get_rf_ctl_over_rev7(
214 struct b43_wldev *dev, u16 field, u8 override);
205 215
206#endif /* B43_TABLES_NPHY_H_ */ 216#endif /* B43_TABLES_NPHY_H_ */