diff options
-rw-r--r-- | drivers/net/wireless/wl12xx/acx.c | 40 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/acx.h | 61 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/conf.h | 14 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/init.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/main.c | 17 |
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 | |||
1630 | int 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 | |||
1665 | out: | ||
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 | */ | ||
1186 | struct 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 | |||
1182 | enum { | 1241 | enum { |
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); | |||
1318 | int wl1271_acx_sta_max_tx_retry(struct wl1271 *wl); | 1378 | int wl1271_acx_sta_max_tx_retry(struct wl1271 *wl); |
1319 | int wl1271_acx_config_ps(struct wl1271 *wl); | 1379 | int wl1271_acx_config_ps(struct wl1271 *wl); |
1320 | int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr); | 1380 | int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr); |
1381 | int 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 | ||
1202 | struct 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 | |||
1202 | struct conf_drv_settings { | 1215 | struct 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) |