Skip to content

Commit 42213f2

Browse files
Ping-Ke ShihKalle Valo
authored andcommitted
rtlwifi: btcoexist control to enter/leave LPS
To yield better user experience, have btcoex control LPS's parameters. Signed-off-by: Ping-Ke Shih <[email protected]> Signed-off-by: Larry Finger <[email protected]> Cc: Yan-Hsuan Chuang <[email protected]> Cc: Birming Chiu <[email protected]> Cc: Shaofu <[email protected]> Cc: Steven Ting <[email protected]> Signed-off-by: Kalle Valo <[email protected]>
1 parent c692205 commit 42213f2

File tree

8 files changed

+203
-26
lines changed

8 files changed

+203
-26
lines changed

drivers/net/wireless/realtek/rtlwifi/base.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1802,12 +1802,20 @@ void rtl_watchdog_wq_callback(void *data)
18021802
false;
18031803
}
18041804

1805+
/* PS is controlled by coex. */
1806+
if (rtlpriv->cfg->ops->get_btc_status() &&
1807+
rtlpriv->btcoexist.btc_ops->btc_is_bt_ctrl_lps(rtlpriv))
1808+
goto label_lps_done;
1809+
18051810
if (((rtlpriv->link_info.num_rx_inperiod +
18061811
rtlpriv->link_info.num_tx_inperiod) > 8) ||
18071812
(rtlpriv->link_info.num_rx_inperiod > 2))
18081813
rtl_lps_leave(hw);
18091814
else
18101815
rtl_lps_enter(hw);
1816+
1817+
label_lps_done:
1818+
;
18111819
}
18121820

18131821
rtlpriv->link_info.num_rx_inperiod = 0;

drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,14 +242,19 @@ static void halbtc_enter_lps(struct btc_coexist *btcoexist)
242242
}
243243

244244
btcoexist->bt_info.bt_ctrl_lps = true;
245-
btcoexist->bt_info.bt_lps_on = false;
245+
btcoexist->bt_info.bt_lps_on = true;
246246
rtl_lps_enter(rtlpriv->mac80211.hw);
247247
}
248248

249249
static void halbtc_normal_lps(struct btc_coexist *btcoexist)
250250
{
251+
struct rtl_priv *rtlpriv;
252+
253+
rtlpriv = btcoexist->adapter;
254+
251255
if (btcoexist->bt_info.bt_ctrl_lps) {
252256
btcoexist->bt_info.bt_lps_on = false;
257+
rtl_lps_leave(rtlpriv->mac80211.hw);
253258
btcoexist->bt_info.bt_ctrl_lps = false;
254259
}
255260
}

drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ static struct rtl_btc_ops rtl_btc_operation = {
4646
.btc_is_bt_disabled = rtl_btc_is_bt_disabled,
4747
.btc_special_packet_notify = rtl_btc_special_packet_notify,
4848
.btc_record_pwr_mode = rtl_btc_record_pwr_mode,
49+
.btc_get_lps_val = rtl_btc_get_lps_val,
50+
.btc_get_rpwm_val = rtl_btc_get_rpwm_val,
51+
.btc_is_bt_ctrl_lps = rtl_btc_is_bt_ctrl_lps,
4952
.btc_is_bt_lps_on = rtl_btc_is_bt_lps_on,
5053
.btc_get_ampdu_cfg = rtl_btc_get_ampdu_cfg,
5154
};
@@ -62,6 +65,21 @@ void rtl_btc_record_pwr_mode(struct rtl_priv *rtlpriv, u8 *buf, u8 len)
6265
memcpy(gl_bt_coexist.pwr_mode_val, buf, safe_len);
6366
}
6467

68+
u8 rtl_btc_get_lps_val(struct rtl_priv *rtlpriv)
69+
{
70+
return gl_bt_coexist.bt_info.lps_val;
71+
}
72+
73+
u8 rtl_btc_get_rpwm_val(struct rtl_priv *rtlpriv)
74+
{
75+
return gl_bt_coexist.bt_info.rpwm_val;
76+
}
77+
78+
bool rtl_btc_is_bt_ctrl_lps(struct rtl_priv *rtlpriv)
79+
{
80+
return gl_bt_coexist.bt_info.bt_ctrl_lps;
81+
}
82+
6583
bool rtl_btc_is_bt_lps_on(struct rtl_priv *rtlpriv)
6684
{
6785
return gl_bt_coexist.bt_info.bt_lps_on;

drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ bool rtl_btc_is_disable_edca_turbo(struct rtl_priv *rtlpriv);
4444
bool rtl_btc_is_bt_disabled(struct rtl_priv *rtlpriv);
4545
void rtl_btc_special_packet_notify(struct rtl_priv *rtlpriv, u8 pkt_type);
4646
void rtl_btc_record_pwr_mode(struct rtl_priv *rtlpriv, u8 *buf, u8 len);
47+
u8 rtl_btc_get_lps_val(struct rtl_priv *rtlpriv);
48+
u8 rtl_btc_get_rpwm_val(struct rtl_priv *rtlpriv);
49+
bool rtl_btc_is_bt_ctrl_lps(struct rtl_priv *rtlpriv);
4750
bool rtl_btc_is_bt_lps_on(struct rtl_priv *rtlpriv);
4851
void rtl_btc_get_ampdu_cfg(struct rtl_priv *rtlpriv, u8 *reject_agg,
4952
u8 *ctrl_agg_size, u8 *agg_size);

drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.c

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -422,24 +422,71 @@ void rtl92ee_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
422422
struct rtl_priv *rtlpriv = rtl_priv(hw);
423423
u8 u1_h2c_set_pwrmode[H2C_92E_PWEMODE_LENGTH] = { 0 };
424424
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
425-
u8 rlbm, power_state = 0, byte5 = 0x40;
425+
u8 rlbm, power_state = 0, byte5 = 0;
426+
u8 awake_intvl; /* DTIM = (awake_intvl - 1) */
426427
struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops;
428+
bool bt_ctrl_lps = (rtlpriv->cfg->ops->get_btc_status() ?
429+
btc_ops->btc_is_bt_ctrl_lps(rtlpriv) : false);
427430

428-
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD , "FW LPS mode = %d\n", mode);
431+
RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, "FW LPS mode = %d (coex:%d)\n",
432+
mode, bt_ctrl_lps);
433+
434+
switch (mode) {
435+
case FW_PS_MIN_MODE:
436+
rlbm = 0;
437+
awake_intvl = 2;
438+
break;
439+
case FW_PS_MAX_MODE:
440+
rlbm = 1;
441+
awake_intvl = 2;
442+
break;
443+
case FW_PS_DTIM_MODE:
444+
rlbm = 2;
445+
awake_intvl = ppsc->reg_max_lps_awakeintvl;
446+
/* hw->conf.ps_dtim_period or mac->vif->bss_conf.dtim_period
447+
* is only used in swlps.
448+
*/
449+
break;
450+
default:
451+
rlbm = 2;
452+
awake_intvl = 4;
453+
break;
454+
}
455+
456+
if (rtlpriv->mac80211.p2p) {
457+
awake_intvl = 2;
458+
rlbm = 1;
459+
}
460+
461+
if (mode == FW_PS_ACTIVE_MODE) {
462+
byte5 = 0x40;
463+
power_state = FW_PWR_STATE_ACTIVE;
464+
} else {
465+
if (bt_ctrl_lps) {
466+
byte5 = btc_ops->btc_get_lps_val(rtlpriv);
467+
power_state = btc_ops->btc_get_rpwm_val(rtlpriv);
468+
469+
if ((rlbm == 2) && (byte5 & BIT(4))) {
470+
/* Keep awake interval to 1 to prevent from
471+
* decreasing coex performance
472+
*/
473+
awake_intvl = 2;
474+
rlbm = 2;
475+
}
476+
} else {
477+
byte5 = 0x40;
478+
power_state = FW_PWR_STATE_RF_OFF;
479+
}
480+
}
429481

430482
SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, ((mode) ? 1 : 0));
431-
rlbm = 0;/*YJ,temp,120316. FW now not support RLBM=2.*/
432483
SET_H2CCMD_PWRMODE_PARM_RLBM(u1_h2c_set_pwrmode, rlbm);
433484
SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode,
434485
(rtlpriv->mac80211.p2p) ?
435486
ppsc->smart_ps : 1);
436487
SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(u1_h2c_set_pwrmode,
437-
ppsc->reg_max_lps_awakeintvl);
488+
awake_intvl);
438489
SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1_h2c_set_pwrmode, 0);
439-
if (mode == FW_PS_ACTIVE_MODE)
440-
power_state |= FW_PWR_STATE_ACTIVE;
441-
else
442-
power_state |= FW_PWR_STATE_RF_OFF;
443490
SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1_h2c_set_pwrmode, power_state);
444491
SET_H2CCMD_PWRMODE_PARM_BYTE5(u1_h2c_set_pwrmode, byte5);
445492

drivers/net/wireless/realtek/rtlwifi/rtl8723be/fw.c

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -240,24 +240,71 @@ void rtl8723be_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
240240
struct rtl_priv *rtlpriv = rtl_priv(hw);
241241
u8 u1_h2c_set_pwrmode[H2C_PWEMODE_LENGTH] = { 0 };
242242
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
243-
u8 rlbm, power_state = 0, byte5 = 0x40;
243+
u8 rlbm, power_state = 0, byte5 = 0;
244+
u8 awake_intvl; /* DTIM = (awake_intvl - 1) */
244245
struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops;
246+
bool bt_ctrl_lps = (rtlpriv->cfg->ops->get_btc_status() ?
247+
btc_ops->btc_is_bt_ctrl_lps(rtlpriv) : false);
245248

246-
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode);
249+
RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, "FW LPS mode = %d (coex:%d)\n",
250+
mode, bt_ctrl_lps);
251+
252+
switch (mode) {
253+
case FW_PS_MIN_MODE:
254+
rlbm = 0;
255+
awake_intvl = 2;
256+
break;
257+
case FW_PS_MAX_MODE:
258+
rlbm = 1;
259+
awake_intvl = 2;
260+
break;
261+
case FW_PS_DTIM_MODE:
262+
rlbm = 2;
263+
awake_intvl = ppsc->reg_max_lps_awakeintvl;
264+
/* hw->conf.ps_dtim_period or mac->vif->bss_conf.dtim_period
265+
* is only used in swlps.
266+
*/
267+
break;
268+
default:
269+
rlbm = 2;
270+
awake_intvl = 4;
271+
break;
272+
}
273+
274+
if (rtlpriv->mac80211.p2p) {
275+
awake_intvl = 2;
276+
rlbm = 1;
277+
}
278+
279+
if (mode == FW_PS_ACTIVE_MODE) {
280+
byte5 = 0x40;
281+
power_state = FW_PWR_STATE_ACTIVE;
282+
} else {
283+
if (bt_ctrl_lps) {
284+
byte5 = btc_ops->btc_get_lps_val(rtlpriv);
285+
power_state = btc_ops->btc_get_rpwm_val(rtlpriv);
286+
287+
if ((rlbm == 2) && (byte5 & BIT(4))) {
288+
/* Keep awake interval to 1 to prevent from
289+
* decreasing coex performance
290+
*/
291+
awake_intvl = 2;
292+
rlbm = 2;
293+
}
294+
} else {
295+
byte5 = 0x40;
296+
power_state = FW_PWR_STATE_RF_OFF;
297+
}
298+
}
247299

248300
SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, ((mode) ? 1 : 0));
249-
rlbm = 0;/*YJ,temp,120316. FW now not support RLBM=2.*/
250301
SET_H2CCMD_PWRMODE_PARM_RLBM(u1_h2c_set_pwrmode, rlbm);
251302
SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode,
252303
(rtlpriv->mac80211.p2p) ?
253304
ppsc->smart_ps : 1);
254305
SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(u1_h2c_set_pwrmode,
255-
ppsc->reg_max_lps_awakeintvl);
306+
awake_intvl);
256307
SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1_h2c_set_pwrmode, 0);
257-
if (mode == FW_PS_ACTIVE_MODE)
258-
power_state |= FW_PWR_STATE_ACTIVE;
259-
else
260-
power_state |= FW_PWR_STATE_RF_OFF;
261308
SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1_h2c_set_pwrmode, power_state);
262309
SET_H2CCMD_PWRMODE_PARM_BYTE5(u1_h2c_set_pwrmode, byte5);
263310

drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c

Lines changed: 55 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -489,25 +489,71 @@ void rtl8821ae_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
489489
struct rtl_priv *rtlpriv = rtl_priv(hw);
490490
u8 u1_h2c_set_pwrmode[H2C_8821AE_PWEMODE_LENGTH] = { 0 };
491491
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
492-
u8 rlbm, power_state = 0, byte5 = 0x40;
492+
u8 rlbm, power_state = 0, byte5 = 0;
493+
u8 awake_intvl; /* DTIM = (awake_intvl - 1) */
493494
struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops;
495+
bool bt_ctrl_lps = (rtlpriv->cfg->ops->get_btc_status() ?
496+
btc_ops->btc_is_bt_ctrl_lps(rtlpriv) : false);
494497

495-
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode);
498+
RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, "FW LPS mode = %d (coex:%d)\n",
499+
mode, bt_ctrl_lps);
500+
501+
switch (mode) {
502+
case FW_PS_MIN_MODE:
503+
rlbm = 0;
504+
awake_intvl = 2;
505+
break;
506+
case FW_PS_MAX_MODE:
507+
rlbm = 1;
508+
awake_intvl = 2;
509+
break;
510+
case FW_PS_DTIM_MODE:
511+
rlbm = 2;
512+
awake_intvl = ppsc->reg_max_lps_awakeintvl;
513+
/* hw->conf.ps_dtim_period or mac->vif->bss_conf.dtim_period
514+
* is only used in swlps.
515+
*/
516+
break;
517+
default:
518+
rlbm = 2;
519+
awake_intvl = 4;
520+
break;
521+
}
522+
523+
if (rtlpriv->mac80211.p2p) {
524+
awake_intvl = 2;
525+
rlbm = 1;
526+
}
527+
528+
if (mode == FW_PS_ACTIVE_MODE) {
529+
byte5 = 0x40;
530+
power_state = FW_PWR_STATE_ACTIVE;
531+
} else {
532+
if (bt_ctrl_lps) {
533+
byte5 = btc_ops->btc_get_lps_val(rtlpriv);
534+
power_state = btc_ops->btc_get_rpwm_val(rtlpriv);
535+
536+
if ((rlbm == 2) && (byte5 & BIT(4))) {
537+
/* Keep awake interval to 1 to prevent from
538+
* decreasing coex performance
539+
*/
540+
awake_intvl = 2;
541+
rlbm = 2;
542+
}
543+
} else {
544+
byte5 = 0x40;
545+
power_state = FW_PWR_STATE_RF_OFF;
546+
}
547+
}
496548

497549
SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, ((mode) ? 1 : 0));
498-
rlbm = 0;/*YJ,temp,120316. FW now not support RLBM=2.*/
499550
SET_H2CCMD_PWRMODE_PARM_RLBM(u1_h2c_set_pwrmode, rlbm);
500551
SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode,
501552
(rtlpriv->mac80211.p2p) ?
502553
ppsc->smart_ps : 1);
503554
SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(u1_h2c_set_pwrmode,
504-
ppsc->reg_max_lps_awakeintvl);
555+
awake_intvl);
505556
SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1_h2c_set_pwrmode, 0);
506-
if (mode == FW_PS_ACTIVE_MODE)
507-
power_state |= FW_PWR_STATE_ACTIVE;
508-
else
509-
power_state |= FW_PWR_STATE_RF_OFF;
510-
511557
SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1_h2c_set_pwrmode, power_state);
512558
SET_H2CCMD_PWRMODE_PARM_BYTE5(u1_h2c_set_pwrmode, byte5);
513559

drivers/net/wireless/realtek/rtlwifi/wifi.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2561,6 +2561,9 @@ struct rtl_btc_ops {
25612561
void (*btc_special_packet_notify)(struct rtl_priv *rtlpriv,
25622562
u8 pkt_type);
25632563
void (*btc_record_pwr_mode)(struct rtl_priv *rtlpriv, u8 *buf, u8 len);
2564+
u8 (*btc_get_lps_val)(struct rtl_priv *rtlpriv);
2565+
u8 (*btc_get_rpwm_val)(struct rtl_priv *rtlpriv);
2566+
bool (*btc_is_bt_ctrl_lps)(struct rtl_priv *rtlpriv);
25642567
void (*btc_get_ampdu_cfg)(struct rtl_priv *rtlpriv, u8 *reject_agg,
25652568
u8 *ctrl_agg_size, u8 *agg_size);
25662569
bool (*btc_is_bt_lps_on)(struct rtl_priv *rtlpriv);

0 commit comments

Comments
 (0)