diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath11k/mac.c')
-rw-r--r-- | drivers/net/wireless/ath/ath11k/mac.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index aebb4b7dd8c0..07f499d5ec92 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -5571,6 +5571,63 @@ static int ath11k_mac_mgmt_tx(struct ath11k *ar, struct sk_buff *skb, return 0; } +int ath11k_mac_rfkill_config(struct ath11k *ar) +{ + struct ath11k_base *ab = ar->ab; + u32 param; + int ret; + + if (ab->hw_params.rfkill_pin == 0) + return -EOPNOTSUPP; + + ath11k_dbg(ab, ATH11K_DBG_MAC, + "mac rfkill_pin %d rfkill_cfg %d rfkill_on_level %d", + ab->hw_params.rfkill_pin, ab->hw_params.rfkill_cfg, + ab->hw_params.rfkill_on_level); + + param = FIELD_PREP(WMI_RFKILL_CFG_RADIO_LEVEL, + ab->hw_params.rfkill_on_level) | + FIELD_PREP(WMI_RFKILL_CFG_GPIO_PIN_NUM, + ab->hw_params.rfkill_pin) | + FIELD_PREP(WMI_RFKILL_CFG_PIN_AS_GPIO, + ab->hw_params.rfkill_cfg); + + ret = ath11k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_HW_RFKILL_CONFIG, + param, ar->pdev->pdev_id); + if (ret) { + ath11k_warn(ab, + "failed to set rfkill config 0x%x: %d\n", + param, ret); + return ret; + } + + return 0; +} + +int ath11k_mac_rfkill_enable_radio(struct ath11k *ar, bool enable) +{ + enum wmi_rfkill_enable_radio param; + int ret; + + if (enable) + param = WMI_RFKILL_ENABLE_RADIO_ON; + else + param = WMI_RFKILL_ENABLE_RADIO_OFF; + + ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac %d rfkill enable %d", + ar->pdev_idx, param); + + ret = ath11k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_RFKILL_ENABLE, + param, ar->pdev->pdev_id); + if (ret) { + ath11k_warn(ar->ab, "failed to set rfkill enable param %d: %d\n", + param, ret); + return ret; + } + + return 0; +} + static void ath11k_mac_op_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct sk_buff *skb) @@ -5803,6 +5860,7 @@ static void ath11k_mac_op_stop(struct ieee80211_hw *hw) cancel_delayed_work_sync(&ar->scan.timeout); cancel_work_sync(&ar->regd_update_work); cancel_work_sync(&ar->ab->update_11d_work); + cancel_work_sync(&ar->ab->rfkill_work); spin_lock_bh(&ar->data_lock); list_for_each_entry_safe(ppdu_stats, tmp, &ar->ppdu_stats_info, list) { |