Commit ff86843d authored by Shahar Levi's avatar Shahar Levi Committed by Luciano Coelho

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: default avatarShahar Levi <shahar_levi@ti.com>
Signed-off-by: default avatarLuciano Coelho <coelho@ti.com>
parent cb5ae053
......@@ -1626,3 +1626,43 @@ int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr)
kfree(acx);
return ret;
}
int wl1271_acx_fm_coex(struct wl1271 *wl)
{
struct wl1271_acx_fm_coex *acx;
int ret;
wl1271_debug(DEBUG_ACX, "acx fm coex setting");
acx = kzalloc(sizeof(*acx), GFP_KERNEL);
if (!acx) {
ret = -ENOMEM;
goto out;
}
acx->enable = wl->conf.fm_coex.enable;
acx->swallow_period = wl->conf.fm_coex.swallow_period;
acx->n_divider_fref_set_1 = wl->conf.fm_coex.n_divider_fref_set_1;
acx->n_divider_fref_set_2 = wl->conf.fm_coex.n_divider_fref_set_2;
acx->m_divider_fref_set_1 =
cpu_to_le16(wl->conf.fm_coex.m_divider_fref_set_1);
acx->m_divider_fref_set_2 =
cpu_to_le16(wl->conf.fm_coex.m_divider_fref_set_2);
acx->coex_pll_stabilization_time =
cpu_to_le32(wl->conf.fm_coex.coex_pll_stabilization_time);
acx->ldo_stabilization_time =
cpu_to_le16(wl->conf.fm_coex.ldo_stabilization_time);
acx->fm_disturbed_band_margin =
wl->conf.fm_coex.fm_disturbed_band_margin;
acx->swallow_clk_diff = wl->conf.fm_coex.swallow_clk_diff;
ret = wl1271_cmd_configure(wl, ACX_FM_COEX_CFG, acx, sizeof(*acx));
if (ret < 0) {
wl1271_warning("acx fm coex setting failed: %d", ret);
goto out;
}
out:
kfree(acx);
return ret;
}
......@@ -1179,6 +1179,65 @@ struct wl1271_acx_inconnection_sta {
u8 padding1[2];
} __packed;
/*
* ACX_FM_COEX_CFG
* set the FM co-existence parameters.
*/
struct wl1271_acx_fm_coex {
struct acx_header header;
/* enable(1) / disable(0) the FM Coex feature */
u8 enable;
/*
* Swallow period used in COEX PLL swallowing mechanism.
* 0xFF = use FW default
*/
u8 swallow_period;
/*
* The N divider used in COEX PLL swallowing mechanism for Fref of
* 38.4/19.2 Mhz. 0xFF = use FW default
*/
u8 n_divider_fref_set_1;
/*
* The N divider used in COEX PLL swallowing mechanism for Fref of
* 26/52 Mhz. 0xFF = use FW default
*/
u8 n_divider_fref_set_2;
/*
* The M divider used in COEX PLL swallowing mechanism for Fref of
* 38.4/19.2 Mhz. 0xFFFF = use FW default
*/
__le16 m_divider_fref_set_1;
/*
* The M divider used in COEX PLL swallowing mechanism for Fref of
* 26/52 Mhz. 0xFFFF = use FW default
*/
__le16 m_divider_fref_set_2;
/*
* The time duration in uSec required for COEX PLL to stabilize.
* 0xFFFFFFFF = use FW default
*/
__le32 coex_pll_stabilization_time;
/*
* The time duration in uSec required for LDO to stabilize.
* 0xFFFFFFFF = use FW default
*/
__le16 ldo_stabilization_time;
/*
* The disturbed frequency band margin around the disturbed frequency
* center (single sided).
* For example, if 2 is configured, the following channels will be
* considered disturbed channel:
* 80 +- 0.1 MHz, 91 +- 0.1 MHz, 98 +- 0.1 MHz, 102 +- 0.1 MH
* 0xFF = use FW default
*/
u8 fm_disturbed_band_margin;
/*
* The swallow clock difference of the swallowing mechanism.
* 0xFF = use FW default
*/
u8 swallow_clk_diff;
} __packed;
enum {
ACX_WAKE_UP_CONDITIONS = 0x0002,
ACX_MEM_CFG = 0x0003,
......@@ -1208,6 +1267,7 @@ enum {
ACX_BCN_DTIM_OPTIONS = 0x0031,
ACX_SG_ENABLE = 0x0032,
ACX_SG_CFG = 0x0033,
ACX_FM_COEX_CFG = 0x0034,
ACX_BEACON_FILTER_TABLE = 0x0038,
ACX_ARP_IP_FILTER = 0x0039,
ACX_ROAMING_STATISTICS_TBL = 0x003B,
......@@ -1318,5 +1378,6 @@ int wl1271_acx_ap_max_tx_retry(struct wl1271 *wl);
int wl1271_acx_sta_max_tx_retry(struct wl1271 *wl);
int wl1271_acx_config_ps(struct wl1271 *wl);
int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr);
int wl1271_acx_fm_coex(struct wl1271 *wl);
#endif /* __WL1271_ACX_H__ */
......@@ -1199,6 +1199,19 @@ struct conf_memory_settings {
u8 tx_min;
};
struct conf_fm_coex {
u8 enable;
u8 swallow_period;
u8 n_divider_fref_set_1;
u8 n_divider_fref_set_2;
u16 m_divider_fref_set_1;
u16 m_divider_fref_set_2;
u32 coex_pll_stabilization_time;
u16 ldo_stabilization_time;
u8 fm_disturbed_band_margin;
u8 swallow_clk_diff;
};
struct conf_drv_settings {
struct conf_sg_settings sg;
struct conf_rx_settings rx;
......@@ -1212,6 +1225,7 @@ struct conf_drv_settings {
struct conf_ht_setting ht;
struct conf_memory_settings mem_wl127x;
struct conf_memory_settings mem_wl128x;
struct conf_fm_coex fm_coex;
u8 hci_io_ds;
};
......
......@@ -356,6 +356,11 @@ static int wl1271_sta_hw_init(struct wl1271 *wl)
if (ret < 0)
return ret;
/* FM WLAN coexistence */
ret = wl1271_acx_fm_coex(wl);
if (ret < 0)
return ret;
/* Beacons and broadcast settings */
ret = wl1271_init_beacon_broadcast(wl);
if (ret < 0)
......
......@@ -320,6 +320,18 @@ static struct conf_drv_settings default_conf = {
.min_req_rx_blocks = 22,
.tx_min = 27,
},
.fm_coex = {
.enable = true,
.swallow_period = 5,
.n_divider_fref_set_1 = 0xff, /* default */
.n_divider_fref_set_2 = 12,
.m_divider_fref_set_1 = 148,
.m_divider_fref_set_2 = 0xffff, /* default */
.coex_pll_stabilization_time = 0xffffffff, /* default */
.ldo_stabilization_time = 0xffff, /* default */
.fm_disturbed_band_margin = 0xff, /* default */
.swallow_clk_diff = 0xff, /* default */
},
.hci_io_ds = HCI_IO_DS_6MA,
};
......@@ -508,6 +520,11 @@ static int wl1271_plt_init(struct wl1271 *wl)
if (ret < 0)
goto out_free_memmap;
/* FM WLAN coexistence */
ret = wl1271_acx_fm_coex(wl);
if (ret < 0)
goto out_free_memmap;
/* Energy detection */
ret = wl1271_init_energy_detection(wl);
if (ret < 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment