NACK/Cmnt: [SRU][U/O][PATCH v2 1/1] wifi: rtw89: add support for hardware rfkill
Kuan-Ying Lee
kuan-ying.lee at canonical.com
Thu Sep 5 08:42:04 UTC 2024
On Wed, Aug 28, 2024 at 11:11:25AM +0800, En-Wei Wu wrote:
> From: Kuan-Chung Chen <damon.chen at realtek.com>
>
> BugLink: https://bugs.launchpad.net/bugs/2077384
>
> Add support for ieee80211::rfkill_poll ops. This enables periodic
> monitoring of the hardware rfkill state, triggering updates when the
> status changes.
>
> Signed-off-by: Kuan-Chung Chen <damon.chen at realtek.com>
> Signed-off-by: Ping-Ke Shih <pkshih at realtek.com>
> Link: https://patch.msgid.link/20240724052626.12774-3-pkshih@realtek.com
> (backported from commit 0b38e6277aed8a59ccb64fcc1172d962c1f11b4c linux-next)
For backported patch, there must be a brief explanation after
the above line, between square brackets, with the name of
the person who introduced the change.
Thanks,
Kuan-Ying Lee
> Signed-off-by: En-Wei Wu <en-wei.wu at canonical.com>
> ---
> drivers/net/wireless/realtek/rtw89/core.c | 68 +++++++++++++++++++
> drivers/net/wireless/realtek/rtw89/core.h | 9 +++
> drivers/net/wireless/realtek/rtw89/mac80211.c | 17 +++++
> drivers/net/wireless/realtek/rtw89/reg.h | 24 +++++++
> drivers/net/wireless/realtek/rtw89/rtw8851b.c | 11 +++
> drivers/net/wireless/realtek/rtw89/rtw8852a.c | 11 +++
> drivers/net/wireless/realtek/rtw89/rtw8852b.c | 11 +++
> drivers/net/wireless/realtek/rtw89/rtw8852c.c | 11 +++
> drivers/net/wireless/realtek/rtw89/rtw8922a.c | 11 +++
> 9 files changed, 173 insertions(+)
>
> diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
> index 7019f7d482a8..c3218714d279 100644
> --- a/drivers/net/wireless/realtek/rtw89/core.c
> +++ b/drivers/net/wireless/realtek/rtw89/core.c
> @@ -3189,6 +3189,7 @@ static void rtw89_track_work(struct work_struct *work)
> rtw89_phy_edcca_track(rtwdev);
> rtw89_tas_track(rtwdev);
> rtw89_chanctx_track(rtwdev);
> + rtw89_core_rfkill_poll(rtwdev, false);
>
> if (rtwdev->lps_enabled && !rtwdev->btc.lps)
> rtw89_enter_lps_track(rtwdev);
> @@ -4470,6 +4471,70 @@ static int rtw89_chip_board_info_setup(struct rtw89_dev *rtwdev)
> return 0;
> }
>
> +static bool rtw89_chip_has_rfkill(struct rtw89_dev *rtwdev)
> +{
> + return !!rtwdev->chip->rfkill_init;
> +}
> +
> +static void rtw89_core_rfkill_init(struct rtw89_dev *rtwdev)
> +{
> + const struct rtw89_rfkill_regs *regs = rtwdev->chip->rfkill_init;
> +
> + rtw89_write16_mask(rtwdev, regs->pinmux.addr,
> + regs->pinmux.mask, regs->pinmux.data);
> + rtw89_write16_mask(rtwdev, regs->mode.addr,
> + regs->mode.mask, regs->mode.data);
> +}
> +
> +static bool rtw89_core_rfkill_get(struct rtw89_dev *rtwdev)
> +{
> + const struct rtw89_reg_def *reg = &rtwdev->chip->rfkill_get;
> +
> + return !rtw89_read8_mask(rtwdev, reg->addr, reg->mask);
> +}
> +
> +static void rtw89_rfkill_polling_init(struct rtw89_dev *rtwdev)
> +{
> + if (!rtw89_chip_has_rfkill(rtwdev))
> + return;
> +
> + rtw89_core_rfkill_init(rtwdev);
> + rtw89_core_rfkill_poll(rtwdev, true);
> + wiphy_rfkill_start_polling(rtwdev->hw->wiphy);
> +}
> +
> +static void rtw89_rfkill_polling_deinit(struct rtw89_dev *rtwdev)
> +{
> + if (!rtw89_chip_has_rfkill(rtwdev))
> + return;
> +
> + wiphy_rfkill_stop_polling(rtwdev->hw->wiphy);
> +}
> +
> +void rtw89_core_rfkill_poll(struct rtw89_dev *rtwdev, bool force)
> +{
> + bool prev, blocked;
> +
> + if (!rtw89_chip_has_rfkill(rtwdev))
> + return;
> +
> + prev = test_bit(RTW89_FLAG_HW_RFKILL_STATE, rtwdev->flags);
> + blocked = rtw89_core_rfkill_get(rtwdev);
> +
> + if (!force && prev == blocked)
> + return;
> +
> + rtw89_info(rtwdev, "rfkill hardware state changed to %s\n",
> + blocked ? "disable" : "enable");
> +
> + if (blocked)
> + set_bit(RTW89_FLAG_HW_RFKILL_STATE, rtwdev->flags);
> + else
> + clear_bit(RTW89_FLAG_HW_RFKILL_STATE, rtwdev->flags);
> +
> + wiphy_rfkill_set_hw_state(rtwdev->hw->wiphy, blocked);
> +}
> +
> int rtw89_chip_info_setup(struct rtw89_dev *rtwdev)
> {
> int ret;
> @@ -4625,6 +4690,8 @@ static int rtw89_core_register_hw(struct rtw89_dev *rtwdev)
> goto err_unregister_hw;
> }
>
> + rtw89_rfkill_polling_init(rtwdev);
> +
> return 0;
>
> err_unregister_hw:
> @@ -4639,6 +4706,7 @@ static void rtw89_core_unregister_hw(struct rtw89_dev *rtwdev)
> {
> struct ieee80211_hw *hw = rtwdev->hw;
>
> + rtw89_rfkill_polling_deinit(rtwdev);
> ieee80211_unregister_hw(hw);
> rtw89_core_clr_supported_band(rtwdev);
> }
> diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
> index 11fa003a9788..802ce9aa7238 100644
> --- a/drivers/net/wireless/realtek/rtw89/core.h
> +++ b/drivers/net/wireless/realtek/rtw89/core.h
> @@ -4066,6 +4066,11 @@ struct rtw89_rrsr_cfgs {
> struct rtw89_reg3_def rsc;
> };
>
> +struct rtw89_rfkill_regs {
> + struct rtw89_reg3_def pinmux;
> + struct rtw89_reg3_def mode;
> +};
> +
> struct rtw89_dig_regs {
> u32 seg0_pd_reg;
> u32 pd_lower_bound_mask;
> @@ -4257,6 +4262,8 @@ struct rtw89_chip_info {
> const struct rtw89_rrsr_cfgs *rrsr_cfgs;
> struct rtw89_reg_def bss_clr_vld;
> u32 bss_clr_map_reg;
> + const struct rtw89_rfkill_regs *rfkill_init;
> + struct rtw89_reg_def rfkill_get;
> u32 dma_ch_mask;
> const struct rtw89_edcca_regs *edcca_regs;
> const struct wiphy_wowlan_support *wowlan_stub;
> @@ -4615,6 +4622,7 @@ enum rtw89_flags {
> RTW89_FLAG_WOWLAN,
> RTW89_FLAG_FORBIDDEN_TRACK_WROK,
> RTW89_FLAG_CHANGING_INTERFACE,
> + RTW89_FLAG_HW_RFKILL_STATE,
>
> NUM_OF_RTW89_FLAGS,
> };
> @@ -6503,6 +6511,7 @@ int rtw89_core_sta_remove(struct rtw89_dev *rtwdev,
> void rtw89_core_set_tid_config(struct rtw89_dev *rtwdev,
> struct ieee80211_sta *sta,
> struct cfg80211_tid_config *tid_config);
> +void rtw89_core_rfkill_poll(struct rtw89_dev *rtwdev, bool force);
> void rtw89_check_quirks(struct rtw89_dev *rtwdev, const struct dmi_system_id *quirks);
> int rtw89_core_init(struct rtw89_dev *rtwdev);
> void rtw89_core_deinit(struct rtw89_dev *rtwdev);
> diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c
> index 1508693032cb..b95fa288c5f5 100644
> --- a/drivers/net/wireless/realtek/rtw89/mac80211.c
> +++ b/drivers/net/wireless/realtek/rtw89/mac80211.c
> @@ -1147,6 +1147,22 @@ static void rtw89_set_rekey_data(struct ieee80211_hw *hw,
> }
> #endif
>
> +static void rtw89_ops_rfkill_poll(struct ieee80211_hw *hw)
> +{
> + struct rtw89_dev *rtwdev = hw->priv;
> +
> + mutex_lock(&rtwdev->mutex);
> +
> + /* wl_disable GPIO get floating when entering LPS */
> + if (test_bit(RTW89_FLAG_RUNNING, rtwdev->flags))
> + goto out;
> +
> + rtw89_core_rfkill_poll(rtwdev, false);
> +
> +out:
> + mutex_unlock(&rtwdev->mutex);
> +}
> +
> const struct ieee80211_ops rtw89_ops = {
> .tx = rtw89_ops_tx,
> .wake_tx_queue = rtw89_ops_wake_tx_queue,
> @@ -1193,5 +1209,6 @@ const struct ieee80211_ops rtw89_ops = {
> .set_wakeup = rtw89_ops_set_wakeup,
> .set_rekey_data = rtw89_set_rekey_data,
> #endif
> + .rfkill_poll = rtw89_ops_rfkill_poll,
> };
> EXPORT_SYMBOL(rtw89_ops);
> diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h
> index 7df36f3bff0b..618917e46967 100644
> --- a/drivers/net/wireless/realtek/rtw89/reg.h
> +++ b/drivers/net/wireless/realtek/rtw89/reg.h
> @@ -107,6 +107,15 @@
> #define B_AX_DBG_SEL0_16BIT BIT(11)
> #define B_AX_DBG_SEL0 GENMASK(7, 0)
>
> +#define R_AX_GPIO_EXT_CTRL 0x0060
> +#define B_AX_GPIO_MOD_15_TO_8_MASK GENMASK(31, 24)
> +#define B_AX_GPIO_MOD_9 BIT(25)
> +#define B_AX_GPIO_IO_SEL_15_TO_8_MASK GENMASK(23, 16)
> +#define B_AX_GPIO_IO_SEL_9 BIT(17)
> +#define B_AX_GPIO_OUT_15_TO_8_MASK GENMASK(15, 8)
> +#define B_AX_GPIO_IN_15_TO_8_MASK GENMASK(7, 0)
> +#define B_AX_GPIO_IN_9 BIT(1)
> +
> #define R_AX_SYS_SDIO_CTRL 0x0070
> #define B_AX_PCIE_DIS_L2_CTRL_LDO_HCI BIT(15)
> #define B_AX_PCIE_DIS_WLSUS_AFT_PDN BIT(14)
> @@ -267,6 +276,9 @@
>
> #define R_AX_GPIO0_7_FUNC_SEL 0x02D0
>
> +#define R_AX_GPIO8_15_FUNC_SEL 0x02D4
> +#define B_AX_PINMUX_GPIO9_FUNC_SEL_MASK GENMASK(7, 4)
> +
> #define R_AX_EECS_EESK_FUNC_SEL 0x02D8
> #define B_AX_PINMUX_EESK_FUNC_SEL_MASK GENMASK(7, 4)
>
> @@ -3854,6 +3866,15 @@
> #define R_BE_EFUSE_CTRL_1_V1 0x0034
> #define B_BE_EF_DATA_MASK GENMASK(31, 0)
>
> +#define R_BE_GPIO_EXT_CTRL 0x0060
> +#define B_BE_GPIO_MOD_15_TO_8_MASK GENMASK(31, 24)
> +#define B_BE_GPIO_MOD_9 BIT(25)
> +#define B_BE_GPIO_IO_SEL_15_TO_8_MASK GENMASK(23, 16)
> +#define B_BE_GPIO_IO_SEL_9 BIT(17)
> +#define B_BE_GPIO_OUT_15_TO_8_MASK GENMASK(15, 8)
> +#define B_BE_GPIO_IN_15_TO_8_MASK GENMASK(7, 0)
> +#define B_BE_GPIO_IN_9 BIT(1)
> +
> #define R_BE_WL_BT_PWR_CTRL 0x0068
> #define B_BE_ISO_BD2PP BIT(31)
> #define B_BE_LDOV12B_EN BIT(30)
> @@ -4299,6 +4320,9 @@
> #define B_BE_REG_CK40M_EN BIT(1)
> #define B_BE_REG_CK640M_EN BIT(0)
>
> +#define R_BE_GPIO8_15_FUNC_SEL 0x02D4
> +#define B_BE_PINMUX_GPIO9_FUNC_SEL_MASK GENMASK(7, 4)
> +
> #define R_BE_WLAN_XTAL_SI_CTRL 0x0270
> #define B_BE_WL_XTAL_SI_CMD_POLL BIT(31)
> #define B_BE_WL_XTAL_SI_CHIPID_MASK GENMASK(30, 28)
> diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851b.c b/drivers/net/wireless/realtek/rtw89/rtw8851b.c
> index 40cf84a79c46..b8f57a602dcf 100644
> --- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c
> +++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c
> @@ -185,6 +185,15 @@ static const struct rtw89_rrsr_cfgs rtw8851b_rrsr_cfgs = {
> .rsc = {R_AX_TRXPTCL_RRSR_CTL_0, B_AX_WMAC_RESP_RSC_MASK, 2},
> };
>
> +static const struct rtw89_rfkill_regs rtw8851b_rfkill_regs = {
> + .pinmux = {R_AX_GPIO8_15_FUNC_SEL,
> + B_AX_PINMUX_GPIO9_FUNC_SEL_MASK,
> + 0xf},
> + .mode = {R_AX_GPIO_EXT_CTRL + 2,
> + (B_AX_GPIO_MOD_9 | B_AX_GPIO_IO_SEL_9) >> 16,
> + 0x0},
> +};
> +
> static const struct rtw89_dig_regs rtw8851b_dig_regs = {
> .seg0_pd_reg = R_SEG0R_PD_V1,
> .pd_lower_bound_mask = B_SEG0R_PD_LOWER_BOUND_MSK,
> @@ -2524,6 +2533,8 @@ const struct rtw89_chip_info rtw8851b_chip_info = {
> .rrsr_cfgs = &rtw8851b_rrsr_cfgs,
> .bss_clr_vld = {R_BSS_CLR_MAP_V1, B_BSS_CLR_MAP_VLD0},
> .bss_clr_map_reg = R_BSS_CLR_MAP_V1,
> + .rfkill_init = &rtw8851b_rfkill_regs,
> + .rfkill_get = {R_AX_GPIO_EXT_CTRL, B_AX_GPIO_IN_9},
> .dma_ch_mask = BIT(RTW89_DMA_ACH4) | BIT(RTW89_DMA_ACH5) |
> BIT(RTW89_DMA_ACH6) | BIT(RTW89_DMA_ACH7) |
> BIT(RTW89_DMA_B1MG) | BIT(RTW89_DMA_B1HI),
> diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
> index 08e148328c62..88f8f2f4c6e2 100644
> --- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c
> +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
> @@ -478,6 +478,15 @@ static const struct rtw89_rrsr_cfgs rtw8852a_rrsr_cfgs = {
> .rsc = {R_AX_TRXPTCL_RRSR_CTL_0, B_AX_WMAC_RESP_RSC_MASK, 2},
> };
>
> +static const struct rtw89_rfkill_regs rtw8852a_rfkill_regs = {
> + .pinmux = {R_AX_GPIO8_15_FUNC_SEL,
> + B_AX_PINMUX_GPIO9_FUNC_SEL_MASK,
> + 0xf},
> + .mode = {R_AX_GPIO_EXT_CTRL + 2,
> + (B_AX_GPIO_MOD_9 | B_AX_GPIO_IO_SEL_9) >> 16,
> + 0x0},
> +};
> +
> static const struct rtw89_dig_regs rtw8852a_dig_regs = {
> .seg0_pd_reg = R_SEG0R_PD,
> .pd_lower_bound_mask = B_SEG0R_PD_LOWER_BOUND_MSK,
> @@ -2240,6 +2249,8 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
> .rrsr_cfgs = &rtw8852a_rrsr_cfgs,
> .bss_clr_vld = {R_BSS_CLR_MAP, B_BSS_CLR_MAP_VLD0},
> .bss_clr_map_reg = R_BSS_CLR_MAP,
> + .rfkill_init = &rtw8852a_rfkill_regs,
> + .rfkill_get = {R_AX_GPIO_EXT_CTRL, B_AX_GPIO_IN_9},
> .dma_ch_mask = 0,
> .edcca_regs = &rtw8852a_edcca_regs,
> #ifdef CONFIG_PM
> diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c
> index a22847a311ad..ef888545d988 100644
> --- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c
> +++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c
> @@ -150,6 +150,15 @@ static const struct rtw89_rrsr_cfgs rtw8852b_rrsr_cfgs = {
> .rsc = {R_AX_TRXPTCL_RRSR_CTL_0, B_AX_WMAC_RESP_RSC_MASK, 2},
> };
>
> +static const struct rtw89_rfkill_regs rtw8852b_rfkill_regs = {
> + .pinmux = {R_AX_GPIO8_15_FUNC_SEL,
> + B_AX_PINMUX_GPIO9_FUNC_SEL_MASK,
> + 0xf},
> + .mode = {R_AX_GPIO_EXT_CTRL + 2,
> + (B_AX_GPIO_MOD_9 | B_AX_GPIO_IO_SEL_9) >> 16,
> + 0x0},
> +};
> +
> static const struct rtw89_dig_regs rtw8852b_dig_regs = {
> .seg0_pd_reg = R_SEG0R_PD_V1,
> .pd_lower_bound_mask = B_SEG0R_PD_LOWER_BOUND_MSK,
> @@ -880,6 +889,8 @@ const struct rtw89_chip_info rtw8852b_chip_info = {
> .rrsr_cfgs = &rtw8852b_rrsr_cfgs,
> .bss_clr_vld = {R_BSS_CLR_MAP_V1, B_BSS_CLR_MAP_VLD0},
> .bss_clr_map_reg = R_BSS_CLR_MAP_V1,
> + .rfkill_init = &rtw8852b_rfkill_regs,
> + .rfkill_get = {R_AX_GPIO_EXT_CTRL, B_AX_GPIO_IN_9},
> .dma_ch_mask = BIT(RTW89_DMA_ACH4) | BIT(RTW89_DMA_ACH5) |
> BIT(RTW89_DMA_ACH6) | BIT(RTW89_DMA_ACH7) |
> BIT(RTW89_DMA_B1MG) | BIT(RTW89_DMA_B1HI),
> diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
> index 193168dc7b6c..8e500d0eb70b 100644
> --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c
> +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
> @@ -147,6 +147,15 @@ static const struct rtw89_rrsr_cfgs rtw8852c_rrsr_cfgs = {
> .rsc = {R_AX_PTCL_RRSR1, B_AX_RSC_MASK, 2},
> };
>
> +static const struct rtw89_rfkill_regs rtw8852c_rfkill_regs = {
> + .pinmux = {R_AX_GPIO8_15_FUNC_SEL,
> + B_AX_PINMUX_GPIO9_FUNC_SEL_MASK,
> + 0xf},
> + .mode = {R_AX_GPIO_EXT_CTRL + 2,
> + (B_AX_GPIO_MOD_9 | B_AX_GPIO_IO_SEL_9) >> 16,
> + 0x0},
> +};
> +
> static const struct rtw89_dig_regs rtw8852c_dig_regs = {
> .seg0_pd_reg = R_SEG0R_PD,
> .pd_lower_bound_mask = B_SEG0R_PD_LOWER_BOUND_MSK,
> @@ -3022,6 +3031,8 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
> .rrsr_cfgs = &rtw8852c_rrsr_cfgs,
> .bss_clr_vld = {R_BSS_CLR_MAP, B_BSS_CLR_MAP_VLD0},
> .bss_clr_map_reg = R_BSS_CLR_MAP,
> + .rfkill_init = &rtw8852c_rfkill_regs,
> + .rfkill_get = {R_AX_GPIO_EXT_CTRL, B_AX_GPIO_IN_9},
> .dma_ch_mask = 0,
> .edcca_regs = &rtw8852c_edcca_regs,
> #ifdef CONFIG_PM
> diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922a.c b/drivers/net/wireless/realtek/rtw89/rtw8922a.c
> index 2af568a3264d..c763b14d43e9 100644
> --- a/drivers/net/wireless/realtek/rtw89/rtw8922a.c
> +++ b/drivers/net/wireless/realtek/rtw89/rtw8922a.c
> @@ -165,6 +165,15 @@ static const struct rtw89_rrsr_cfgs rtw8922a_rrsr_cfgs = {
> .rsc = {R_BE_PTCL_RRSR1, B_BE_RSC_MASK, 2},
> };
>
> +static const struct rtw89_rfkill_regs rtw8922a_rfkill_regs = {
> + .pinmux = {R_BE_GPIO8_15_FUNC_SEL,
> + B_BE_PINMUX_GPIO9_FUNC_SEL_MASK,
> + 0xf},
> + .mode = {R_BE_GPIO_EXT_CTRL + 2,
> + (B_BE_GPIO_MOD_9 | B_BE_GPIO_IO_SEL_9) >> 16,
> + 0x0},
> +};
> +
> static const struct rtw89_dig_regs rtw8922a_dig_regs = {
> .seg0_pd_reg = R_SEG0R_PD_V2,
> .pd_lower_bound_mask = B_SEG0R_PD_LOWER_BOUND_MSK,
> @@ -2624,6 +2633,8 @@ const struct rtw89_chip_info rtw8922a_chip_info = {
> .rrsr_cfgs = &rtw8922a_rrsr_cfgs,
> .bss_clr_vld = {R_BSS_CLR_VLD_V2, B_BSS_CLR_VLD0_V2},
> .bss_clr_map_reg = R_BSS_CLR_MAP_V2,
> + .rfkill_init = &rtw8922a_rfkill_regs,
> + .rfkill_get = {R_BE_GPIO_EXT_CTRL, B_BE_GPIO_IN_9},
> .dma_ch_mask = 0,
> .edcca_regs = &rtw8922a_edcca_regs,
> #ifdef CONFIG_PM
More information about the kernel-team
mailing list