2016-11-24 06:53:30

by Miaoqing Pan

[permalink] [raw]
Subject: [PATCH 1/3] ath9k: Add a module parameter to set btcoex duty cycle

From: Miaoqing Pan <[email protected]>

btcoex duty cyle allows user to balance the performance
between WLAN and BT.

Signed-off-by: Miaoqing Pan <[email protected]>
---
drivers/net/wireless/ath/ath9k/gpio.c | 4 +---
drivers/net/wireless/ath/ath9k/init.c | 10 ++++++++++
2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
index ddb2886..782a2f2 100644
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -278,7 +278,7 @@ static void ath_init_btcoex_timer(struct ath_softc *sc)
struct ath_btcoex *btcoex = &sc->btcoex;

btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD;
- btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) *
+ btcoex->btcoex_no_stomp = (100 - btcoex->duty_cycle) *
btcoex->btcoex_period / 100;
btcoex->btscan_no_stomp = (100 - ATH_BTCOEX_BTSCAN_DUTY_CYCLE) *
btcoex->btcoex_period / 100;
@@ -433,8 +433,6 @@ int ath9k_init_btcoex(struct ath_softc *sc)
break;
case ATH_BTCOEX_CFG_MCI:
ath_init_btcoex_timer(sc);
-
- sc->btcoex.duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE;
INIT_LIST_HEAD(&sc->btcoex.mci.info);
ath9k_hw_btcoex_init_mci(ah);

diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 368d9b3..8edd78b 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -73,6 +73,12 @@ struct ath9k_eeprom_ctx {

#endif /* CONFIG_ATH9K_CHANNEL_CONTEXT */

+#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
+static int ath9k_btcoex_duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE;
+module_param_named(btcoex_duty_cycle, ath9k_btcoex_duty_cycle, int, 0444);
+MODULE_PARM_DESC(btcoex_duty_cycle, "BT coexistence duty cycle");
+#endif
+
bool is_ath9k_unloaded;

#ifdef CONFIG_MAC80211_LEDS
@@ -587,6 +593,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
sc->sc_ah = ah;
sc->dfs_detector = dfs_pattern_detector_init(common, NL80211_DFS_UNSET);
sc->tx99_power = MAX_RATE_POWER + 1;
+
init_waitqueue_head(&sc->tx_wait);
sc->cur_chan = &sc->chanctx[0];
if (!ath9k_is_chanctx_enabled())
@@ -602,6 +609,9 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
common->btcoex_enabled = ath9k_btcoex_enable == 1;
common->disable_ani = false;

+#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
+ sc->btcoex.duty_cycle = ath9k_btcoex_duty_cycle;
+#endif
/*
* Platform quirks.
*/
--
1.9.1


2016-11-25 15:28:22

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 2/3] ath9k: export configurable parameters of PTA

[email protected] writes:

> From: Miaoqing Pan <[email protected]>
>
> Export time_extend, pritority_time, first_slot_time, wl_active_time
> and wl_qc_time those PTA(aka slotted mode) configurable parameters,
> allow user to change/debug the timing easily.
>
> Also set wl_active_time and wl_qc_time default value to 0, as in this
> period WLAN chip may send out ACK, and it will corrupt the BT(or other)
> received packet in the PTA cycle.
>
> Signed-off-by: Miaoqing Pan <[email protected]>

Please try to always write commit logs so that everyone will understand,
for example spelling out what PTA means would be nice.

> --- a/drivers/net/wireless/ath/ath9k/init.c
> +++ b/drivers/net/wireless/ath/ath9k/init.c
> @@ -77,6 +77,26 @@ struct ath9k_eeprom_ctx {
> static int ath9k_btcoex_duty_cycle =3D ATH_BTCOEX_DEF_DUTY_CYCLE;
> module_param_named(btcoex_duty_cycle, ath9k_btcoex_duty_cycle, int, 0444=
);
> MODULE_PARM_DESC(btcoex_duty_cycle, "BT coexistence duty cycle");
> +
> +static int ath9k_btcoex_time_extend;
> +module_param_named(btcoex_time_extend, ath9k_btcoex_time_extend, int, 04=
44);
> +MODULE_PARM_DESC(btcoex_time_extend, "BT coexistence time extend");
> +
> +static int ath9k_btcoex_priority_time =3D 2;
> +module_param_named(btcoex_priority_time, ath9k_btcoex_priority_time, int=
, 0444);
> +MODULE_PARM_DESC(btcoex_priority_time, "BT coexistence priority time");
> +
> +static int ath9k_btcoex_first_slot_time =3D 5;
> +module_param_named(btcoex_first_slot_time, ath9k_btcoex_first_slot_time,=
int, 0444);
> +MODULE_PARM_DESC(btcoex_first_slot_time, "BT coexistence first slot time=
");
> +
> +static int ath9k_btcoex_wl_active_time;
> +module_param_named(btcoex_wl_active_time, ath9k_btcoex_wl_active_time, i=
nt, 0444);
> +MODULE_PARM_DESC(btcoex_wl_active_time, "BT coexistence wlan active time=
");
> +
> +static int ath9k_btcoex_wl_qc_time;
> +module_param_named(btcoex_wl_qc_time, ath9k_btcoex_wl_qc_time, int, 0444=
);
> +MODULE_PARM_DESC(btcoex_wl_qc_time, "BT coexistence wlan quiet collision=
time");
> #endif

Same as with the previous patch, I don't think these should be set via
module parameters.

--=20
Kalle Valo=

2016-11-24 06:53:40

by Miaoqing Pan

[permalink] [raw]
Subject: [PATCH 3/3] ath9k: disable ACK_CTS for SOC chips in PTA mode

From: Miaoqing Pan <[email protected]>

If the ACK_CTS is enabled, MAC will send an ACK or CTS in response
to a received frame, but it is a interfering packet for the BT(or other)
in the PTA cycle, which will sufficient corrupt the received packets.

Only disable it for SOC chips in PTA(slotted) mode.

Signed-off-by: Miaoqing Pan <[email protected]>
---
drivers/net/wireless/ath/ath9k/btcoex.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c
index 6d15dd3..7e24640 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.c
+++ b/drivers/net/wireless/ath/ath9k/btcoex.c
@@ -290,6 +290,7 @@ static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah)
struct ath_btcoex_hw *btcoex = &ah->btcoex_hw;
u32 val;
int i;
+ int coex_mode = MS(btcoex->bt_coex_mode, AR_BT_MODE);

/*
* Program coex mode and weight registers to
@@ -319,7 +320,11 @@ static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah)
REG_WRITE(ah, 0x50040, val);
}

- REG_RMW_FIELD(ah, AR_QUIET1, AR_QUIET1_QUIET_ACK_CTS_ENABLE, 1);
+ if (AR_SREV_SOC(ah) && (coex_mode == ATH_BT_COEX_MODE_SLOTTED))
+ REG_RMW_FIELD(ah, AR_QUIET1, AR_QUIET1_QUIET_ACK_CTS_ENABLE, 0);
+ else
+ REG_RMW_FIELD(ah, AR_QUIET1, AR_QUIET1_QUIET_ACK_CTS_ENABLE, 1);
+
REG_RMW_FIELD(ah, AR_PCU_MISC, AR_PCU_BT_ANT_PREVENT_RX, 0);

ath9k_hw_gpio_request_out(ah, btcoex->wlanactive_gpio,
--
1.9.1

2016-11-25 15:25:53

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 1/3] ath9k: Add a module parameter to set btcoex duty cycle

[email protected] writes:

> From: Miaoqing Pan <[email protected]>
>
> btcoex duty cyle allows user to balance the performance
> between WLAN and BT.
>
> Signed-off-by: Miaoqing Pan <[email protected]>

[...]

> --- a/drivers/net/wireless/ath/ath9k/init.c
> +++ b/drivers/net/wireless/ath/ath9k/init.c
> @@ -73,6 +73,12 @@ struct ath9k_eeprom_ctx {
> =20
> #endif /* CONFIG_ATH9K_CHANNEL_CONTEXT */
> =20
> +#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
> +static int ath9k_btcoex_duty_cycle =3D ATH_BTCOEX_DEF_DUTY_CYCLE;
> +module_param_named(btcoex_duty_cycle, ath9k_btcoex_duty_cycle, int, 0444=
);
> +MODULE_PARM_DESC(btcoex_duty_cycle, "BT coexistence duty cycle");
> +#endif

I don't think module parameters are really meant for providing protocol
settings like this, especially as these would be global for all radios.
nl80211 (if used in production) or debugfs (if used only in testing) are
much better choises.

--=20
Kalle Valo=

2016-11-24 06:53:36

by Miaoqing Pan

[permalink] [raw]
Subject: [PATCH 2/3] ath9k: export configurable parameters of PTA

From: Miaoqing Pan <[email protected]>

Export time_extend, pritority_time, first_slot_time, wl_active_time
and wl_qc_time those PTA(aka slotted mode) configurable parameters,
allow user to change/debug the timing easily.

Also set wl_active_time and wl_qc_time default value to 0, as in this
period WLAN chip may send out ACK, and it will corrupt the BT(or other)
received packet in the PTA cycle.

Signed-off-by: Miaoqing Pan <[email protected]>
---
drivers/net/wireless/ath/ath9k/btcoex.c | 62 ++++++++-------------------------
drivers/net/wireless/ath/ath9k/btcoex.h | 9 +++++
drivers/net/wireless/ath/ath9k/init.c | 26 ++++++++++++++
3 files changed, 50 insertions(+), 47 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c
index 618c9df..6d15dd3 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.c
+++ b/drivers/net/wireless/ath/ath9k/btcoex.c
@@ -26,20 +26,6 @@ enum ath_bt_mode {
ATH_BT_COEX_MODE_DISABLED, /* coexistence disabled */
};

-struct ath_btcoex_config {
- u8 bt_time_extend;
- bool bt_txstate_extend;
- bool bt_txframe_extend;
- enum ath_bt_mode bt_mode; /* coexistence mode */
- bool bt_quiet_collision;
- bool bt_rxclear_polarity; /* invert rx_clear as WLAN_ACTIVE*/
- u8 bt_priority_time;
- u8 bt_first_slot_time;
- bool bt_hold_rx_clear;
- u8 wl_active_time;
- u8 wl_qc_time;
-};
-
static const u32 ar9003_wlan_weights[ATH_BTCOEX_STOMP_MAX]
[AR9300_NUM_WLAN_WEIGHTS] = {
{ 0xfffffff0, 0xfffffff0, 0xfffffff0, 0xfffffff0 }, /* STOMP_ALL */
@@ -59,33 +45,16 @@ struct ath_btcoex_config {
void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum)
{
struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
- const struct ath_btcoex_config ath_bt_config = {
- .bt_time_extend = 0,
- .bt_txstate_extend = true,
- .bt_txframe_extend = true,
- .bt_mode = ATH_BT_COEX_MODE_SLOTTED,
- .bt_quiet_collision = true,
- .bt_rxclear_polarity = true,
- .bt_priority_time = 2,
- .bt_first_slot_time = 5,
- .bt_hold_rx_clear = true,
- .wl_active_time = 0x20,
- .wl_qc_time = 0x20,
- };
- bool rxclear_polarity = ath_bt_config.bt_rxclear_polarity;
- u8 time_extend = ath_bt_config.bt_time_extend;
- u8 first_slot_time = ath_bt_config.bt_first_slot_time;
+ struct ath_btcoex_config *config = &btcoex_hw->config;
+ bool rxclear_polarity = true;

if (AR_SREV_9300_20_OR_LATER(ah))
- rxclear_polarity = !ath_bt_config.bt_rxclear_polarity;
+ rxclear_polarity = false;

if (AR_SREV_SOC(ah)) {
- first_slot_time = 0x1d;
- time_extend = 0xa;
-
btcoex_hw->bt_coex_mode3 =
- SM(ath_bt_config.wl_active_time, AR_BT_WL_ACTIVE_TIME) |
- SM(ath_bt_config.wl_qc_time, AR_BT_WL_QC_TIME);
+ SM(config->wl_active_time, AR_BT_WL_ACTIVE_TIME) |
+ SM(config->wl_qc_time, AR_BT_WL_QC_TIME);

btcoex_hw->bt_coex_mode2 =
AR_BT_PROTECT_BT_AFTER_WAKEUP |
@@ -93,21 +62,20 @@ void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum)
}

btcoex_hw->bt_coex_mode =
- (btcoex_hw->bt_coex_mode & AR_BT_QCU_THRESH) |
- SM(time_extend, AR_BT_TIME_EXTEND) |
- SM(ath_bt_config.bt_txstate_extend, AR_BT_TXSTATE_EXTEND) |
- SM(ath_bt_config.bt_txframe_extend, AR_BT_TX_FRAME_EXTEND) |
- SM(ath_bt_config.bt_mode, AR_BT_MODE) |
- SM(ath_bt_config.bt_quiet_collision, AR_BT_QUIET) |
+ AR_BT_TXSTATE_EXTEND |
+ AR_BT_TX_FRAME_EXTEND |
+ AR_BT_QUIET |
+ SM(ATH_BT_COEX_MODE_SLOTTED, AR_BT_MODE) |
SM(rxclear_polarity, AR_BT_RX_CLEAR_POLARITY) |
- SM(ath_bt_config.bt_priority_time, AR_BT_PRIORITY_TIME) |
- SM(first_slot_time, AR_BT_FIRST_SLOT_TIME) |
+ SM(config->bt_time_extend, AR_BT_TIME_EXTEND) |
+ SM(config->bt_priority_time, AR_BT_PRIORITY_TIME) |
+ SM(config->bt_first_slot_time, AR_BT_FIRST_SLOT_TIME) |
SM(qnum, AR_BT_QCU_THRESH);

btcoex_hw->bt_coex_mode2 |=
- SM(ath_bt_config.bt_hold_rx_clear, AR_BT_HOLD_RX_CLEAR) |
- SM(ATH_BTCOEX_BMISS_THRESH, AR_BT_BCN_MISS_THRESH) |
- AR_BT_DISABLE_BT_ANT;
+ AR_BT_HOLD_RX_CLEAR |
+ AR_BT_DISABLE_BT_ANT |
+ SM(ATH_BTCOEX_BMISS_THRESH, AR_BT_BCN_MISS_THRESH);
}
EXPORT_SYMBOL(ath9k_hw_init_btcoex_hw);

diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h
index 1bdfa84..fb1ef04 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.h
+++ b/drivers/net/wireless/ath/ath9k/btcoex.h
@@ -104,6 +104,14 @@ struct ath9k_hw_aic {
u32 aic_cal_start_time;
};

+struct ath_btcoex_config {
+ u8 bt_time_extend;
+ u8 bt_priority_time;
+ u8 bt_first_slot_time;
+ u8 wl_active_time;
+ u8 wl_qc_time;
+};
+
struct ath_btcoex_hw {
enum ath_btcoex_scheme scheme;
struct ath9k_hw_mci mci;
@@ -119,6 +127,7 @@ struct ath_btcoex_hw {
u32 bt_weight[AR9300_NUM_BT_WEIGHTS];
u32 wlan_weight[AR9300_NUM_WLAN_WEIGHTS];
u8 tx_prio[ATH_BTCOEX_STOMP_MAX];
+ struct ath_btcoex_config config;
};

void ath9k_hw_btcoex_init_scheme(struct ath_hw *ah);
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 8edd78b..74d2b7b 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -77,6 +77,26 @@ struct ath9k_eeprom_ctx {
static int ath9k_btcoex_duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE;
module_param_named(btcoex_duty_cycle, ath9k_btcoex_duty_cycle, int, 0444);
MODULE_PARM_DESC(btcoex_duty_cycle, "BT coexistence duty cycle");
+
+static int ath9k_btcoex_time_extend;
+module_param_named(btcoex_time_extend, ath9k_btcoex_time_extend, int, 0444);
+MODULE_PARM_DESC(btcoex_time_extend, "BT coexistence time extend");
+
+static int ath9k_btcoex_priority_time = 2;
+module_param_named(btcoex_priority_time, ath9k_btcoex_priority_time, int, 0444);
+MODULE_PARM_DESC(btcoex_priority_time, "BT coexistence priority time");
+
+static int ath9k_btcoex_first_slot_time = 5;
+module_param_named(btcoex_first_slot_time, ath9k_btcoex_first_slot_time, int, 0444);
+MODULE_PARM_DESC(btcoex_first_slot_time, "BT coexistence first slot time");
+
+static int ath9k_btcoex_wl_active_time;
+module_param_named(btcoex_wl_active_time, ath9k_btcoex_wl_active_time, int, 0444);
+MODULE_PARM_DESC(btcoex_wl_active_time, "BT coexistence wlan active time");
+
+static int ath9k_btcoex_wl_qc_time;
+module_param_named(btcoex_wl_qc_time, ath9k_btcoex_wl_qc_time, int, 0444);
+MODULE_PARM_DESC(btcoex_wl_qc_time, "BT coexistence wlan quiet collision time");
#endif

bool is_ath9k_unloaded;
@@ -611,7 +631,13 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,

#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
sc->btcoex.duty_cycle = ath9k_btcoex_duty_cycle;
+ ah->btcoex_hw.config.bt_time_extend = ath9k_btcoex_time_extend;
+ ah->btcoex_hw.config.bt_priority_time = ath9k_btcoex_priority_time;
+ ah->btcoex_hw.config.bt_first_slot_time = ath9k_btcoex_first_slot_time;
+ ah->btcoex_hw.config.wl_active_time = ath9k_btcoex_wl_active_time;
+ ah->btcoex_hw.config.wl_qc_time = ath9k_btcoex_wl_qc_time;
#endif
+
/*
* Platform quirks.
*/
--
1.9.1