aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorShahar Levi <shahar_levi@ti.com>2011-04-11 08:41:46 -0400
committerLuciano Coelho <coelho@ti.com>2011-05-02 03:26:06 -0400
commitff86843dfbb368766d0aecd0147821d9a2b60edb (patch)
tree529886d8567de0a766ade345aca6f043701ad2d6 /drivers
parentcb5ae0530e0e2af86d128ce758645b6b4a9132e1 (diff)
wl12xx: FM WLAN coexistence
Add support to FM WLAN coexistence (STA only). Some WiFi harmonics may interfere with FM operation, to avoid this problem special coexistence techniques are activated around some FM frequencies. Signed-off-by: Shahar Levi <shahar_levi@ti.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/wl12xx/acx.c40
-rw-r--r--drivers/net/wireless/wl12xx/acx.h61
-rw-r--r--drivers/net/wireless/wl12xx/conf.h14
-rw-r--r--drivers/net/wireless/wl12xx/init.c5
-rw-r--r--drivers/net/wireless/wl12xx/main.c17
5 files changed, 137 insertions, 0 deletions
diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c
index a5c9c0aff83f..8a39d1e40a68 100644
--- a/drivers/net/wireless/wl12xx/acx.c
+++ b/drivers/net/wireless/wl12xx/acx.c
@@ -1626,3 +1626,43 @@ out:
1626 kfree(acx); 1626 kfree(acx);
1627 return ret; 1627 return ret;
1628} 1628}
1629
1630int wl1271_acx_fm_coex(struct wl1271 *wl)
1631{
1632 struct wl1271_acx_fm_coex *acx;
1633 int ret;
1634
1635 wl1271_debug(DEBUG_ACX, "acx fm coex setting");
1636
1637 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1638 if (!acx) {
1639 ret = -ENOMEM;
1640 goto out;
1641 }
1642
1643 acx->enable = wl->conf.fm_coex.enable;
1644 acx->swallow_period = wl->conf.fm_coex.swallow_period;
1645 acx->n_divider_fref_set_1 = wl->conf.fm_coex.n_divider_fref_set_1;
1646 acx->n_divider_fref_set_2 = wl->conf.fm_coex.n_divider_fref_set_2;
1647 acx->m_divider_fref_set_1 =
1648 cpu_to_le16(wl->conf.fm_coex.m_divider_fref_set_1);
1649 acx->m_divider_fref_set_2 =
1650 cpu_to_le16(wl->conf.fm_coex.m_divider_fref_set_2);
1651 acx->coex_pll_stabilization_time =
1652 cpu_to_le32(wl->conf.fm_coex.coex_pll_stabilization_time);
1653 acx->ldo_stabilization_time =
1654 cpu_to_le16(wl->conf.fm_coex.ldo_stabilization_time);
1655 acx->fm_disturbed_band_margin =
1656 wl->conf.fm_coex.fm_disturbed_band_margin;
1657 acx->swallow_clk_diff = wl->conf.fm_coex.swallow_clk_diff;
1658
1659 ret = wl1271_cmd_configure(wl, ACX_FM_COEX_CFG, acx, sizeof(*acx));
1660 if (ret < 0) {
1661 wl1271_warning("acx fm coex setting failed: %d", ret);
1662 goto out;
1663 }
1664
1665out:
1666 kfree(acx);
1667 return ret;
1668}
diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h
index 942908cd53a3..2dde0346e955 100644
--- a/drivers/net/wireless/wl12xx/acx.h
+++ b/drivers/net/wireless/wl12xx/acx.h
@@ -1179,6 +1179,65 @@ struct wl1271_acx_inconnection_sta {
1179 u8 padding1[2]; 1179 u8 padding1[2];
1180} __packed; 1180} __packed;
1181 1181
1182/*
1183 * ACX_FM_COEX_CFG
1184 * set the FM co-existence parameters.
1185 */
1186struct wl1271_acx_fm_coex {
1187 struct acx_header header;
1188 /* enable(1) / disable(0) the FM Coex feature */
1189 u8 enable;
1190 /*
1191 * Swallow period used in COEX PLL swallowing mechanism.
1192 * 0xFF = use FW default
1193 */
1194 u8 swallow_period;
1195 /*
1196 * The N divider used in COEX PLL swallowing mechanism for Fref of
1197 * 38.4/19.2 Mhz. 0xFF = use FW default
1198 */
1199 u8 n_divider_fref_set_1;
1200 /*
1201 * The N divider used in COEX PLL swallowing mechanism for Fref of
1202 * 26/52 Mhz. 0xFF = use FW default
1203 */
1204 u8 n_divider_fref_set_2;
1205 /*
1206 * The M divider used in COEX PLL swallowing mechanism for Fref of
1207 * 38.4/19.2 Mhz. 0xFFFF = use FW default
1208 */
1209 __le16 m_divider_fref_set_1;
1210 /*
1211 * The M divider used in COEX PLL swallowing mechanism for Fref of
1212 * 26/52 Mhz. 0xFFFF = use FW default
1213 */
1214 __le16 m_divider_fref_set_2;
1215 /*
1216 * The time duration in uSec required for COEX PLL to stabilize.
1217 * 0xFFFFFFFF = use FW default
1218 */
1219 __le32 coex_pll_stabilization_time;
1220 /*
1221 * The time duration in uSec required for LDO to stabilize.
1222 * 0xFFFFFFFF = use FW default
1223 */
1224 __le16 ldo_stabilization_time;
1225 /*
1226 * The disturbed frequency band margin around the disturbed frequency
1227 * center (single sided).
1228 * For example, if 2 is configured, the following channels will be
1229 * considered disturbed channel:
1230 * 80 +- 0.1 MHz, 91 +- 0.1 MHz, 98 +- 0.1 MHz, 102 +- 0.1 MH
1231 * 0xFF = use FW default
1232 */
1233 u8 fm_disturbed_band_margin;
1234 /*
1235 * The swallow clock difference of the swallowing mechanism.
1236 * 0xFF = use FW default
1237 */
1238 u8 swallow_clk_diff;
1239} __packed;
1240
1182enum { 1241enum {
1183 ACX_WAKE_UP_CONDITIONS = 0x0002, 1242 ACX_WAKE_UP_CONDITIONS = 0x0002,
1184 ACX_MEM_CFG = 0x0003, 1243 ACX_MEM_CFG = 0x0003,
@@ -1208,6 +1267,7 @@ enum {
1208 ACX_BCN_DTIM_OPTIONS = 0x0031, 1267 ACX_BCN_DTIM_OPTIONS = 0x0031,
1209 ACX_SG_ENABLE = 0x0032, 1268 ACX_SG_ENABLE = 0x0032,
1210 ACX_SG_CFG = 0x0033, 1269 ACX_SG_CFG = 0x0033,
1270 ACX_FM_COEX_CFG = 0x0034,
1211 ACX_BEACON_FILTER_TABLE = 0x0038, 1271 ACX_BEACON_FILTER_TABLE = 0x0038,
1212 ACX_ARP_IP_FILTER = 0x0039, 1272 ACX_ARP_IP_FILTER = 0x0039,
1213 ACX_ROAMING_STATISTICS_TBL = 0x003B, 1273 ACX_ROAMING_STATISTICS_TBL = 0x003B,
@@ -1318,5 +1378,6 @@ int wl1271_acx_ap_max_tx_retry(struct wl1271 *wl);
1318int wl1271_acx_sta_max_tx_retry(struct wl1271 *wl); 1378int wl1271_acx_sta_max_tx_retry(struct wl1271 *wl);
1319int wl1271_acx_config_ps(struct wl1271 *wl); 1379int wl1271_acx_config_ps(struct wl1271 *wl);
1320int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr); 1380int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr);
1381int wl1271_acx_fm_coex(struct wl1271 *wl);
1321 1382
1322#endif /* __WL1271_ACX_H__ */ 1383#endif /* __WL1271_ACX_H__ */
diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h
index 5551d9d4016b..a4e0acff8674 100644
--- a/drivers/net/wireless/wl12xx/conf.h
+++ b/drivers/net/wireless/wl12xx/conf.h
@@ -1199,6 +1199,19 @@ struct conf_memory_settings {
1199 u8 tx_min; 1199 u8 tx_min;
1200}; 1200};
1201 1201
1202struct conf_fm_coex {
1203 u8 enable;
1204 u8 swallow_period;
1205 u8 n_divider_fref_set_1;
1206 u8 n_divider_fref_set_2;
1207 u16 m_divider_fref_set_1;
1208 u16 m_divider_fref_set_2;
1209 u32 coex_pll_stabilization_time;
1210 u16 ldo_stabilization_time;
1211 u8 fm_disturbed_band_margin;
1212 u8 swallow_clk_diff;
1213};
1214
1202struct conf_drv_settings { 1215struct conf_drv_settings {
1203 struct conf_sg_settings sg; 1216 struct conf_sg_settings sg;
1204 struct conf_rx_settings rx; 1217 struct conf_rx_settings rx;
@@ -1212,6 +1225,7 @@ struct conf_drv_settings {
1212 struct conf_ht_setting ht; 1225 struct conf_ht_setting ht;
1213 struct conf_memory_settings mem_wl127x; 1226 struct conf_memory_settings mem_wl127x;
1214 struct conf_memory_settings mem_wl128x; 1227 struct conf_memory_settings mem_wl128x;
1228 struct conf_fm_coex fm_coex;
1215 u8 hci_io_ds; 1229 u8 hci_io_ds;
1216}; 1230};
1217 1231
diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c
index ab3b1e21de29..46fd7212b238 100644
--- a/drivers/net/wireless/wl12xx/init.c
+++ b/drivers/net/wireless/wl12xx/init.c
@@ -356,6 +356,11 @@ static int wl1271_sta_hw_init(struct wl1271 *wl)
356 if (ret < 0) 356 if (ret < 0)
357 return ret; 357 return ret;
358 358
359 /* FM WLAN coexistence */
360 ret = wl1271_acx_fm_coex(wl);
361 if (ret < 0)
362 return ret;
363
359 /* Beacons and broadcast settings */ 364 /* Beacons and broadcast settings */
360 ret = wl1271_init_beacon_broadcast(wl); 365 ret = wl1271_init_beacon_broadcast(wl);
361 if (ret < 0) 366 if (ret < 0)
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 53a8e2357ccf..8a7a8c5fcf5b 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -320,6 +320,18 @@ static struct conf_drv_settings default_conf = {
320 .min_req_rx_blocks = 22, 320 .min_req_rx_blocks = 22,
321 .tx_min = 27, 321 .tx_min = 27,
322 }, 322 },
323 .fm_coex = {
324 .enable = true,
325 .swallow_period = 5,
326 .n_divider_fref_set_1 = 0xff, /* default */
327 .n_divider_fref_set_2 = 12,
328 .m_divider_fref_set_1 = 148,
329 .m_divider_fref_set_2 = 0xffff, /* default */
330 .coex_pll_stabilization_time = 0xffffffff, /* default */
331 .ldo_stabilization_time = 0xffff, /* default */
332 .fm_disturbed_band_margin = 0xff, /* default */
333 .swallow_clk_diff = 0xff, /* default */
334 },
323 .hci_io_ds = HCI_IO_DS_6MA, 335 .hci_io_ds = HCI_IO_DS_6MA,
324}; 336};
325 337
@@ -508,6 +520,11 @@ static int wl1271_plt_init(struct wl1271 *wl)
508 if (ret < 0) 520 if (ret < 0)
509 goto out_free_memmap; 521 goto out_free_memmap;
510 522
523 /* FM WLAN coexistence */
524 ret = wl1271_acx_fm_coex(wl);
525 if (ret < 0)
526 goto out_free_memmap;
527
511 /* Energy detection */ 528 /* Energy detection */
512 ret = wl1271_init_energy_detection(wl); 529 ret = wl1271_init_energy_detection(wl);
513 if (ret < 0) 530 if (ret < 0)