Commit ba12f08f authored by Karthikeyan Periyasamy's avatar Karthikeyan Periyasamy Committed by Kalle Valo

wifi: ath12k: add multiple radio support in a single MAC HW un/register

Currently MAC HW un/register helper function support the single radio.
To enable single/multi link operation in the future, the following helper
functions need to be refactored to accommodate multiple radios under a
single MAC HW un/register:

	* ath12k_ah_to_ar()
	* ath12k_mac_hw_allocate()
	* ath12k_mac_hw_register()
	* ath12k_mac_hw_unregister()

This refactoring will make it easier to scale these functionalities and
support Multi link operation.

                         Current Multi wiphy Model

 +---------------+          +---------------+            +---------------+
 |  Mac80211 hw  |          | Mac80211 hw   |            | Mac80211 hw   |
 |  private data |          | private data  |            | private data  |
 |               |          |               |            |               |
 |ath12k_hw (ah) |          |ath12k_hw (ah) |            |ath12k_hw (ah) |
 |               |          |               |            |               |
 | +-----------+ |          | +-----------+ |            | +-----------+ |
 | | ar (2GHz) | |          | | ar (5GHz) | |            | | ar (6GHz) | |
 | +-----------+ |          | +-----------+ |            | +-----------+ |
 |               |          |               |            |               |
 +---------------+          +---------------+            +---------------+

                           Single wiphy Model

                            +--------------+
                            | Mac80211 hw  |
                            | private data |
                            |              |
                            |ath12k hw (ah)|
                            | +----------+ |
                            | |ar (2GHz) | |
                            | +----------+ |
                            | |ar (5GHz) | |
                            | +----------+ |
                            | |ar (6GHz) | |
                            | +----------+ |
                            +--------------+

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3
Signed-off-by: default avatarKarthikeyan Periyasamy <quic_periyasa@quicinc.com>
Signed-off-by: default avatarSriram R <quic_srirrama@quicinc.com>
Signed-off-by: default avatarRameshkumar Sundaram <quic_ramess@quicinc.com>
Acked-by: default avatarJeff Johnson <quic_jjohnson@quicinc.com>
Signed-off-by: default avatarKalle Valo <quic_kvalo@quicinc.com>
Link: https://msgid.link/20240405194519.1337906-2-quic_ramess@quicinc.com
parent df1f2b94
...@@ -978,13 +978,21 @@ static inline struct ath12k_hw *ath12k_hw_to_ah(struct ieee80211_hw *hw) ...@@ -978,13 +978,21 @@ static inline struct ath12k_hw *ath12k_hw_to_ah(struct ieee80211_hw *hw)
return hw->priv; return hw->priv;
} }
static inline struct ath12k *ath12k_ah_to_ar(struct ath12k_hw *ah) static inline struct ath12k *ath12k_ah_to_ar(struct ath12k_hw *ah, u8 hw_link_id)
{ {
return ah->radio; if (WARN(hw_link_id >= ah->num_radio,
"bad hw link id %d, so switch to default link\n", hw_link_id))
hw_link_id = 0;
return &ah->radio[hw_link_id];
} }
static inline struct ieee80211_hw *ath12k_ar_to_hw(struct ath12k *ar) static inline struct ieee80211_hw *ath12k_ar_to_hw(struct ath12k *ar)
{ {
return ar->ah->hw; return ar->ah->hw;
} }
#define for_each_ar(ah, ar, index) \
for ((index) = 0; ((index) < (ah)->num_radio && \
((ar) = &(ah)->radio[(index)])); (index)++)
#endif /* _CORE_H_ */ #endif /* _CORE_H_ */
...@@ -1170,7 +1170,7 @@ static int ath12k_mac_op_config(struct ieee80211_hw *hw, u32 changed) ...@@ -1170,7 +1170,7 @@ static int ath12k_mac_op_config(struct ieee80211_hw *hw, u32 changed)
struct ath12k *ar; struct ath12k *ar;
int ret; int ret;
ar = ath12k_ah_to_ar(ah); ar = ath12k_ah_to_ar(ah, 0);
ret = ath12k_mac_config(ar, changed); ret = ath12k_mac_config(ar, changed);
if (ret) if (ret)
...@@ -2971,7 +2971,7 @@ static void ath12k_mac_op_bss_info_changed(struct ieee80211_hw *hw, ...@@ -2971,7 +2971,7 @@ static void ath12k_mac_op_bss_info_changed(struct ieee80211_hw *hw,
struct ath12k *ar; struct ath12k *ar;
struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif);
ar = ath12k_ah_to_ar(ah); ar = ath12k_ah_to_ar(ah, 0);
mutex_lock(&ar->conf_mutex); mutex_lock(&ar->conf_mutex);
...@@ -3156,7 +3156,7 @@ static int ath12k_mac_op_hw_scan(struct ieee80211_hw *hw, ...@@ -3156,7 +3156,7 @@ static int ath12k_mac_op_hw_scan(struct ieee80211_hw *hw,
int ret; int ret;
int i; int i;
ar = ath12k_ah_to_ar(ah); ar = ath12k_ah_to_ar(ah, 0);
mutex_lock(&ar->conf_mutex); mutex_lock(&ar->conf_mutex);
...@@ -3246,7 +3246,7 @@ static void ath12k_mac_op_cancel_hw_scan(struct ieee80211_hw *hw, ...@@ -3246,7 +3246,7 @@ static void ath12k_mac_op_cancel_hw_scan(struct ieee80211_hw *hw,
struct ath12k_hw *ah = ath12k_hw_to_ah(hw); struct ath12k_hw *ah = ath12k_hw_to_ah(hw);
struct ath12k *ar; struct ath12k *ar;
ar = ath12k_ah_to_ar(ah); ar = ath12k_ah_to_ar(ah, 0);
mutex_lock(&ar->conf_mutex); mutex_lock(&ar->conf_mutex);
ath12k_scan_abort(ar); ath12k_scan_abort(ar);
...@@ -3391,7 +3391,7 @@ static int ath12k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, ...@@ -3391,7 +3391,7 @@ static int ath12k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
key->cipher == WLAN_CIPHER_SUITE_BIP_CMAC_256) key->cipher == WLAN_CIPHER_SUITE_BIP_CMAC_256)
return 1; return 1;
ar = ath12k_ah_to_ar(ah); ar = ath12k_ah_to_ar(ah, 0);
ab = ar->ab; ab = ar->ab;
if (test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags)) if (test_bit(ATH12K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags))
...@@ -3981,7 +3981,7 @@ static int ath12k_mac_op_sta_state(struct ieee80211_hw *hw, ...@@ -3981,7 +3981,7 @@ static int ath12k_mac_op_sta_state(struct ieee80211_hw *hw,
new_state == IEEE80211_STA_NOTEXIST)) new_state == IEEE80211_STA_NOTEXIST))
cancel_work_sync(&arsta->update_wk); cancel_work_sync(&arsta->update_wk);
ar = ath12k_ah_to_ar(ah); ar = ath12k_ah_to_ar(ah, 0);
mutex_lock(&ar->conf_mutex); mutex_lock(&ar->conf_mutex);
...@@ -4110,7 +4110,7 @@ static int ath12k_mac_op_sta_set_txpwr(struct ieee80211_hw *hw, ...@@ -4110,7 +4110,7 @@ static int ath12k_mac_op_sta_set_txpwr(struct ieee80211_hw *hw,
if (txpwr > ATH12K_TX_POWER_MAX_VAL || txpwr < ATH12K_TX_POWER_MIN_VAL) if (txpwr > ATH12K_TX_POWER_MAX_VAL || txpwr < ATH12K_TX_POWER_MIN_VAL)
return -EINVAL; return -EINVAL;
ar = ath12k_ah_to_ar(ah); ar = ath12k_ah_to_ar(ah, 0);
mutex_lock(&ar->conf_mutex); mutex_lock(&ar->conf_mutex);
...@@ -4139,7 +4139,7 @@ static void ath12k_mac_op_sta_rc_update(struct ieee80211_hw *hw, ...@@ -4139,7 +4139,7 @@ static void ath12k_mac_op_sta_rc_update(struct ieee80211_hw *hw,
struct ath12k_peer *peer; struct ath12k_peer *peer;
u32 bw, smps; u32 bw, smps;
ar = ath12k_ah_to_ar(ah); ar = ath12k_ah_to_ar(ah, 0);
spin_lock_bh(&ar->ab->base_lock); spin_lock_bh(&ar->ab->base_lock);
...@@ -4320,7 +4320,7 @@ static int ath12k_mac_op_conf_tx(struct ieee80211_hw *hw, ...@@ -4320,7 +4320,7 @@ static int ath12k_mac_op_conf_tx(struct ieee80211_hw *hw,
struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif);
int ret; int ret;
ar = ath12k_ah_to_ar(ah); ar = ath12k_ah_to_ar(ah, 0);
mutex_lock(&ar->conf_mutex); mutex_lock(&ar->conf_mutex);
ret = ath12k_mac_conf_tx(arvif, link_id, ac, params); ret = ath12k_mac_conf_tx(arvif, link_id, ac, params);
...@@ -5447,7 +5447,7 @@ static int ath12k_mac_start(struct ath12k *ar) ...@@ -5447,7 +5447,7 @@ static int ath12k_mac_start(struct ath12k *ar)
static int ath12k_mac_op_start(struct ieee80211_hw *hw) static int ath12k_mac_op_start(struct ieee80211_hw *hw)
{ {
struct ath12k_hw *ah = ath12k_hw_to_ah(hw); struct ath12k_hw *ah = ath12k_hw_to_ah(hw);
struct ath12k *ar = ath12k_ah_to_ar(ah); struct ath12k *ar = ath12k_ah_to_ar(ah, 0);
struct ath12k_base *ab = ar->ab; struct ath12k_base *ab = ar->ab;
int ret; int ret;
...@@ -5556,7 +5556,7 @@ static void ath12k_mac_stop(struct ath12k *ar) ...@@ -5556,7 +5556,7 @@ static void ath12k_mac_stop(struct ath12k *ar)
static void ath12k_mac_op_stop(struct ieee80211_hw *hw) static void ath12k_mac_op_stop(struct ieee80211_hw *hw)
{ {
struct ath12k_hw *ah = ath12k_hw_to_ah(hw); struct ath12k_hw *ah = ath12k_hw_to_ah(hw);
struct ath12k *ar = ath12k_ah_to_ar(ah); struct ath12k *ar = ath12k_ah_to_ar(ah, 0);
ath12k_mac_drain_tx(ar); ath12k_mac_drain_tx(ar);
...@@ -5750,7 +5750,7 @@ static int ath12k_mac_op_add_interface(struct ieee80211_hw *hw, ...@@ -5750,7 +5750,7 @@ static int ath12k_mac_op_add_interface(struct ieee80211_hw *hw,
vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD; vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;
ar = ath12k_ah_to_ar(ah); ar = ath12k_ah_to_ar(ah, 0);
ab = ar->ab; ab = ar->ab;
mutex_lock(&ar->conf_mutex); mutex_lock(&ar->conf_mutex);
...@@ -6018,7 +6018,7 @@ static void ath12k_mac_op_remove_interface(struct ieee80211_hw *hw, ...@@ -6018,7 +6018,7 @@ static void ath12k_mac_op_remove_interface(struct ieee80211_hw *hw,
unsigned long time_left; unsigned long time_left;
int ret; int ret;
ar = ath12k_ah_to_ar(ah); ar = ath12k_ah_to_ar(ah, 0);
ab = ar->ab; ab = ar->ab;
mutex_lock(&ar->conf_mutex); mutex_lock(&ar->conf_mutex);
...@@ -6133,7 +6133,7 @@ static void ath12k_mac_op_configure_filter(struct ieee80211_hw *hw, ...@@ -6133,7 +6133,7 @@ static void ath12k_mac_op_configure_filter(struct ieee80211_hw *hw,
struct ath12k_hw *ah = ath12k_hw_to_ah(hw); struct ath12k_hw *ah = ath12k_hw_to_ah(hw);
struct ath12k *ar; struct ath12k *ar;
ar = ath12k_ah_to_ar(ah); ar = ath12k_ah_to_ar(ah, 0);
mutex_lock(&ar->conf_mutex); mutex_lock(&ar->conf_mutex);
...@@ -6148,7 +6148,7 @@ static int ath12k_mac_op_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 * ...@@ -6148,7 +6148,7 @@ static int ath12k_mac_op_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *
struct ath12k_hw *ah = ath12k_hw_to_ah(hw); struct ath12k_hw *ah = ath12k_hw_to_ah(hw);
struct ath12k *ar; struct ath12k *ar;
ar = ath12k_ah_to_ar(ah); ar = ath12k_ah_to_ar(ah, 0);
mutex_lock(&ar->conf_mutex); mutex_lock(&ar->conf_mutex);
...@@ -6166,7 +6166,7 @@ static int ath12k_mac_op_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx ...@@ -6166,7 +6166,7 @@ static int ath12k_mac_op_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx
struct ath12k *ar; struct ath12k *ar;
int ret; int ret;
ar = ath12k_ah_to_ar(ah); ar = ath12k_ah_to_ar(ah, 0);
mutex_lock(&ar->conf_mutex); mutex_lock(&ar->conf_mutex);
ret = __ath12k_set_antenna(ar, tx_ant, rx_ant); ret = __ath12k_set_antenna(ar, tx_ant, rx_ant);
...@@ -6214,7 +6214,7 @@ static int ath12k_mac_op_ampdu_action(struct ieee80211_hw *hw, ...@@ -6214,7 +6214,7 @@ static int ath12k_mac_op_ampdu_action(struct ieee80211_hw *hw,
struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif);
int ret = -EINVAL; int ret = -EINVAL;
ar = ath12k_ah_to_ar(ah); ar = ath12k_ah_to_ar(ah, 0);
mutex_lock(&ar->conf_mutex); mutex_lock(&ar->conf_mutex);
ret = ath12k_mac_ampdu_action(arvif, params); ret = ath12k_mac_ampdu_action(arvif, params);
...@@ -6234,7 +6234,7 @@ static int ath12k_mac_op_add_chanctx(struct ieee80211_hw *hw, ...@@ -6234,7 +6234,7 @@ static int ath12k_mac_op_add_chanctx(struct ieee80211_hw *hw,
struct ath12k *ar; struct ath12k *ar;
struct ath12k_base *ab; struct ath12k_base *ab;
ar = ath12k_ah_to_ar(ah); ar = ath12k_ah_to_ar(ah, 0);
ab = ar->ab; ab = ar->ab;
ath12k_dbg(ab, ATH12K_DBG_MAC, ath12k_dbg(ab, ATH12K_DBG_MAC,
...@@ -6262,7 +6262,7 @@ static void ath12k_mac_op_remove_chanctx(struct ieee80211_hw *hw, ...@@ -6262,7 +6262,7 @@ static void ath12k_mac_op_remove_chanctx(struct ieee80211_hw *hw,
struct ath12k *ar; struct ath12k *ar;
struct ath12k_base *ab; struct ath12k_base *ab;
ar = ath12k_ah_to_ar(ah); ar = ath12k_ah_to_ar(ah, 0);
ab = ar->ab; ab = ar->ab;
ath12k_dbg(ab, ATH12K_DBG_MAC, ath12k_dbg(ab, ATH12K_DBG_MAC,
...@@ -6642,7 +6642,7 @@ static void ath12k_mac_op_change_chanctx(struct ieee80211_hw *hw, ...@@ -6642,7 +6642,7 @@ static void ath12k_mac_op_change_chanctx(struct ieee80211_hw *hw,
struct ath12k *ar; struct ath12k *ar;
struct ath12k_base *ab; struct ath12k_base *ab;
ar = ath12k_ah_to_ar(ah); ar = ath12k_ah_to_ar(ah, 0);
ab = ar->ab; ab = ar->ab;
mutex_lock(&ar->conf_mutex); mutex_lock(&ar->conf_mutex);
...@@ -6713,7 +6713,7 @@ ath12k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, ...@@ -6713,7 +6713,7 @@ ath12k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
int ret; int ret;
struct ath12k_wmi_peer_create_arg param; struct ath12k_wmi_peer_create_arg param;
ar = ath12k_ah_to_ar(ah); ar = ath12k_ah_to_ar(ah, 0);
ab = ar->ab; ab = ar->ab;
mutex_lock(&ar->conf_mutex); mutex_lock(&ar->conf_mutex);
...@@ -6795,7 +6795,7 @@ ath12k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw, ...@@ -6795,7 +6795,7 @@ ath12k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif); struct ath12k_vif *arvif = ath12k_vif_to_arvif(vif);
int ret; int ret;
ar = ath12k_ah_to_ar(ah); ar = ath12k_ah_to_ar(ah, 0);
ab = ar->ab; ab = ar->ab;
mutex_lock(&ar->conf_mutex); mutex_lock(&ar->conf_mutex);
...@@ -6850,7 +6850,7 @@ ath12k_mac_op_switch_vif_chanctx(struct ieee80211_hw *hw, ...@@ -6850,7 +6850,7 @@ ath12k_mac_op_switch_vif_chanctx(struct ieee80211_hw *hw,
struct ath12k_hw *ah = ath12k_hw_to_ah(hw); struct ath12k_hw *ah = ath12k_hw_to_ah(hw);
struct ath12k *ar; struct ath12k *ar;
ar = ath12k_ah_to_ar(ah); ar = ath12k_ah_to_ar(ah, 0);
mutex_lock(&ar->conf_mutex); mutex_lock(&ar->conf_mutex);
...@@ -6896,7 +6896,7 @@ static int ath12k_mac_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value) ...@@ -6896,7 +6896,7 @@ static int ath12k_mac_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
struct ath12k *ar; struct ath12k *ar;
int param_id = WMI_VDEV_PARAM_RTS_THRESHOLD, ret; int param_id = WMI_VDEV_PARAM_RTS_THRESHOLD, ret;
ar = ath12k_ah_to_ar(ah); ar = ath12k_ah_to_ar(ah, 0);
ret = ath12k_set_vdev_param_to_all_vifs(ar, param_id, value); ret = ath12k_set_vdev_param_to_all_vifs(ar, param_id, value);
...@@ -6940,7 +6940,7 @@ static void ath12k_mac_op_flush(struct ieee80211_hw *hw, struct ieee80211_vif *v ...@@ -6940,7 +6940,7 @@ static void ath12k_mac_op_flush(struct ieee80211_hw *hw, struct ieee80211_vif *v
u32 queues, bool drop) u32 queues, bool drop)
{ {
struct ath12k_hw *ah = ath12k_hw_to_ah(hw); struct ath12k_hw *ah = ath12k_hw_to_ah(hw);
struct ath12k *ar = ath12k_ah_to_ar(ah); struct ath12k *ar = ath12k_ah_to_ar(ah, 0);
if (drop) if (drop)
return; return;
...@@ -7307,7 +7307,7 @@ ath12k_mac_op_reconfig_complete(struct ieee80211_hw *hw, ...@@ -7307,7 +7307,7 @@ ath12k_mac_op_reconfig_complete(struct ieee80211_hw *hw,
if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART) if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART)
return; return;
ar = ath12k_ah_to_ar(ah); ar = ath12k_ah_to_ar(ah, 0);
ab = ar->ab; ab = ar->ab;
mutex_lock(&ar->conf_mutex); mutex_lock(&ar->conf_mutex);
...@@ -7402,7 +7402,7 @@ static int ath12k_mac_op_get_survey(struct ieee80211_hw *hw, int idx, ...@@ -7402,7 +7402,7 @@ static int ath12k_mac_op_get_survey(struct ieee80211_hw *hw, int idx,
if (idx >= ATH12K_NUM_CHANS) if (idx >= ATH12K_NUM_CHANS)
return -ENOENT; return -ENOENT;
ar = ath12k_ah_to_ar(ah); ar = ath12k_ah_to_ar(ah, 0);
ar_survey = &ar->survey[idx]; ar_survey = &ar->survey[idx];
...@@ -7479,7 +7479,7 @@ static int ath12k_mac_op_cancel_remain_on_channel(struct ieee80211_hw *hw, ...@@ -7479,7 +7479,7 @@ static int ath12k_mac_op_cancel_remain_on_channel(struct ieee80211_hw *hw,
struct ath12k_hw *ah = ath12k_hw_to_ah(hw); struct ath12k_hw *ah = ath12k_hw_to_ah(hw);
struct ath12k *ar; struct ath12k *ar;
ar = ath12k_ah_to_ar(ah); ar = ath12k_ah_to_ar(ah, 0);
mutex_lock(&ar->conf_mutex); mutex_lock(&ar->conf_mutex);
...@@ -7509,7 +7509,7 @@ static int ath12k_mac_op_remain_on_channel(struct ieee80211_hw *hw, ...@@ -7509,7 +7509,7 @@ static int ath12k_mac_op_remain_on_channel(struct ieee80211_hw *hw,
u32 scan_time_msec; u32 scan_time_msec;
int ret; int ret;
ar = ath12k_ah_to_ar(ah); ar = ath12k_ah_to_ar(ah, 0);
mutex_lock(&ar->conf_mutex); mutex_lock(&ar->conf_mutex);
spin_lock_bh(&ar->data_lock); spin_lock_bh(&ar->data_lock);
...@@ -7758,10 +7758,12 @@ static int ath12k_mac_setup_channels_rates(struct ath12k *ar, ...@@ -7758,10 +7758,12 @@ static int ath12k_mac_setup_channels_rates(struct ath12k *ar,
static u16 ath12k_mac_get_ifmodes(struct ath12k_hw *ah) static u16 ath12k_mac_get_ifmodes(struct ath12k_hw *ah)
{ {
struct ath12k *ar = ath12k_ah_to_ar(ah); struct ath12k *ar;
int i;
u16 interface_modes = U16_MAX; u16 interface_modes = U16_MAX;
interface_modes &= ar->ab->hw_params->interface_modes; for_each_ar(ah, ar, i)
interface_modes &= ar->ab->hw_params->interface_modes;
return interface_modes == U16_MAX ? 0 : interface_modes; return interface_modes == U16_MAX ? 0 : interface_modes;
} }
...@@ -7769,15 +7771,19 @@ static u16 ath12k_mac_get_ifmodes(struct ath12k_hw *ah) ...@@ -7769,15 +7771,19 @@ static u16 ath12k_mac_get_ifmodes(struct ath12k_hw *ah)
static bool ath12k_mac_is_iface_mode_enable(struct ath12k_hw *ah, static bool ath12k_mac_is_iface_mode_enable(struct ath12k_hw *ah,
enum nl80211_iftype type) enum nl80211_iftype type)
{ {
struct ath12k *ar = ath12k_ah_to_ar(ah); struct ath12k *ar;
int i;
u16 interface_modes, mode; u16 interface_modes, mode;
bool is_enable = true; bool is_enable = true;
mode = BIT(type); mode = BIT(type);
for_each_ar(ah, ar, i) {
interface_modes = ar->ab->hw_params->interface_modes; interface_modes = ar->ab->hw_params->interface_modes;
if (!(interface_modes & mode)) if (!(interface_modes & mode)) {
is_enable = false; is_enable = false;
break;
}
}
return is_enable; return is_enable;
} }
...@@ -7907,13 +7913,16 @@ static void ath12k_mac_hw_unregister(struct ath12k_hw *ah) ...@@ -7907,13 +7913,16 @@ static void ath12k_mac_hw_unregister(struct ath12k_hw *ah)
{ {
struct ieee80211_hw *hw = ah->hw; struct ieee80211_hw *hw = ah->hw;
struct wiphy *wiphy = hw->wiphy; struct wiphy *wiphy = hw->wiphy;
struct ath12k *ar = ath12k_ah_to_ar(ah); struct ath12k *ar;
int i;
cancel_work_sync(&ar->regd_update_work); for_each_ar(ah, ar, i)
cancel_work_sync(&ar->regd_update_work);
ieee80211_unregister_hw(hw); ieee80211_unregister_hw(hw);
ath12k_mac_cleanup_unregister(ar); for_each_ar(ah, ar, i)
ath12k_mac_cleanup_unregister(ar);
kfree(wiphy->iface_combinations[0].limits); kfree(wiphy->iface_combinations[0].limits);
kfree(wiphy->iface_combinations); kfree(wiphy->iface_combinations);
...@@ -7953,7 +7962,7 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah) ...@@ -7953,7 +7962,7 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah)
{ {
struct ieee80211_hw *hw = ah->hw; struct ieee80211_hw *hw = ah->hw;
struct wiphy *wiphy = hw->wiphy; struct wiphy *wiphy = hw->wiphy;
struct ath12k *ar = ath12k_ah_to_ar(ah); struct ath12k *ar = ath12k_ah_to_ar(ah, 0);
struct ath12k_base *ab = ar->ab; struct ath12k_base *ab = ar->ab;
struct ath12k_pdev *pdev; struct ath12k_pdev *pdev;
struct ath12k_pdev_cap *cap; struct ath12k_pdev_cap *cap;
...@@ -7968,39 +7977,71 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah) ...@@ -7968,39 +7977,71 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah)
WLAN_CIPHER_SUITE_GCMP_256, WLAN_CIPHER_SUITE_GCMP_256,
WLAN_CIPHER_SUITE_CCMP_256, WLAN_CIPHER_SUITE_CCMP_256,
}; };
int ret; int ret, i, j;
u32 ht_cap = 0; u32 ht_cap = U32_MAX, antennas_rx = 0, antennas_tx = 0;
bool is_6ghz = false, is_raw_mode = false, is_monitor_disable = false;
u8 *mac_addr = NULL;
pdev = ar->pdev; wiphy->max_ap_assoc_sta = 0;
if (ab->pdevs_macaddr_valid) for_each_ar(ah, ar, i) {
ether_addr_copy(ar->mac_addr, pdev->mac_addr); u32 ht_cap_info = 0;
else
ether_addr_copy(ar->mac_addr, ab->mac_addr);
ret = ath12k_mac_setup_register(ar, &ht_cap, hw->wiphy->bands); pdev = ar->pdev;
if (ret) if (ar->ab->pdevs_macaddr_valid) {
goto out; ether_addr_copy(ar->mac_addr, pdev->mac_addr);
} else {
ether_addr_copy(ar->mac_addr, ar->ab->mac_addr);
ar->mac_addr[4] += ar->pdev_idx;
}
ret = ath12k_mac_setup_register(ar, &ht_cap_info, hw->wiphy->bands);
if (ret)
goto err_cleanup_unregister;
wiphy->max_ap_assoc_sta = ar->max_num_stations; ht_cap &= ht_cap_info;
wiphy->max_ap_assoc_sta += ar->max_num_stations;
/* Advertise the max antenna support of all radios, driver can handle
* per pdev specific antenna setting based on pdev cap when antenna
* changes are made
*/
cap = &pdev->cap;
cap = &pdev->cap; antennas_rx = max_t(u32, antennas_rx, cap->rx_chain_mask);
antennas_tx = max_t(u32, antennas_tx, cap->tx_chain_mask);
wiphy->available_antennas_rx = cap->rx_chain_mask; if (ar->supports_6ghz)
wiphy->available_antennas_tx = cap->tx_chain_mask; is_6ghz = true;
SET_IEEE80211_PERM_ADDR(hw, ar->mac_addr); if (test_bit(ATH12K_FLAG_RAW_MODE, &ar->ab->dev_flags))
is_raw_mode = true;
if (!ar->ab->hw_params->supports_monitor)
is_monitor_disable = true;
if (i == 0)
mac_addr = ar->mac_addr;
else
mac_addr = ab->mac_addr;
}
wiphy->available_antennas_rx = antennas_rx;
wiphy->available_antennas_tx = antennas_tx;
SET_IEEE80211_PERM_ADDR(hw, mac_addr);
SET_IEEE80211_DEV(hw, ab->dev); SET_IEEE80211_DEV(hw, ab->dev);
ret = ath12k_mac_setup_iface_combinations(ah); ret = ath12k_mac_setup_iface_combinations(ah);
if (ret) { if (ret) {
ath12k_err(ab, "failed to setup interface combinations: %d\n", ret); ath12k_err(ab, "failed to setup interface combinations: %d\n", ret);
goto err_cleanup_unregister; goto err_complete_cleanup_unregister;
} }
wiphy->interface_modes = ath12k_mac_get_ifmodes(ah); wiphy->interface_modes = ath12k_mac_get_ifmodes(ah);
if (wiphy->bands[NL80211_BAND_2GHZ] && if (ah->num_radio == 1 &&
wiphy->bands[NL80211_BAND_2GHZ] &&
wiphy->bands[NL80211_BAND_5GHZ] && wiphy->bands[NL80211_BAND_5GHZ] &&
wiphy->bands[NL80211_BAND_6GHZ]) wiphy->bands[NL80211_BAND_6GHZ])
ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS); ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS);
...@@ -8068,7 +8109,7 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah) ...@@ -8068,7 +8109,7 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah)
wiphy->iftype_ext_capab = ath12k_iftypes_ext_capa; wiphy->iftype_ext_capab = ath12k_iftypes_ext_capa;
wiphy->num_iftype_ext_capab = ARRAY_SIZE(ath12k_iftypes_ext_capa); wiphy->num_iftype_ext_capab = ARRAY_SIZE(ath12k_iftypes_ext_capa);
if (ar->supports_6ghz) { if (is_6ghz) {
wiphy_ext_feature_set(wiphy, wiphy_ext_feature_set(wiphy,
NL80211_EXT_FEATURE_FILS_DISCOVERY); NL80211_EXT_FEATURE_FILS_DISCOVERY);
wiphy_ext_feature_set(wiphy, wiphy_ext_feature_set(wiphy,
...@@ -8079,7 +8120,7 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah) ...@@ -8079,7 +8120,7 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah)
ath12k_reg_init(hw); ath12k_reg_init(hw);
if (!test_bit(ATH12K_FLAG_RAW_MODE, &ab->dev_flags)) { if (!is_raw_mode) {
hw->netdev_features = NETIF_F_HW_CSUM; hw->netdev_features = NETIF_F_HW_CSUM;
ieee80211_hw_set(hw, SW_CRYPTO_CONTROL); ieee80211_hw_set(hw, SW_CRYPTO_CONTROL);
ieee80211_hw_set(hw, SUPPORT_FAST_XMIT); ieee80211_hw_set(hw, SUPPORT_FAST_XMIT);
...@@ -8091,7 +8132,7 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah) ...@@ -8091,7 +8132,7 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah)
goto err_free_if_combs; goto err_free_if_combs;
} }
if (!ab->hw_params->supports_monitor) if (is_monitor_disable)
/* There's a race between calling ieee80211_register_hw() /* There's a race between calling ieee80211_register_hw()
* and here where the monitor mode is enabled for a little * and here where the monitor mode is enabled for a little
* while. But that time is so short and in practise it make * while. But that time is so short and in practise it make
...@@ -8099,11 +8140,13 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah) ...@@ -8099,11 +8140,13 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah)
*/ */
wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MONITOR); wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MONITOR);
/* Apply the regd received during initialization */ for_each_ar(ah, ar, i) {
ret = ath12k_regd_update(ar, true); /* Apply the regd received during initialization */
if (ret) { ret = ath12k_regd_update(ar, true);
ath12k_err(ar->ab, "ath12k regd update failed: %d\n", ret); if (ret) {
goto err_unregister_hw; ath12k_err(ar->ab, "ath12k regd update failed: %d\n", ret);
goto err_unregister_hw;
}
} }
ath12k_debugfs_register(ar); ath12k_debugfs_register(ar);
...@@ -8117,10 +8160,15 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah) ...@@ -8117,10 +8160,15 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah)
kfree(wiphy->iface_combinations[0].limits); kfree(wiphy->iface_combinations[0].limits);
kfree(wiphy->iface_combinations); kfree(wiphy->iface_combinations);
err_complete_cleanup_unregister:
i = ah->num_radio;
err_cleanup_unregister: err_cleanup_unregister:
ath12k_mac_cleanup_unregister(ar); for (j = 0; j < i; j++) {
ar = ath12k_ah_to_ar(ah, j);
ath12k_mac_cleanup_unregister(ar);
}
out:
SET_IEEE80211_DEV(hw, NULL); SET_IEEE80211_DEV(hw, NULL);
return ret; return ret;
...@@ -8246,7 +8294,7 @@ static struct ath12k_hw *ath12k_mac_hw_allocate(struct ath12k_base *ab, ...@@ -8246,7 +8294,7 @@ static struct ath12k_hw *ath12k_mac_hw_allocate(struct ath12k_base *ab,
pdev_idx = pdev_map[i].pdev_idx; pdev_idx = pdev_map[i].pdev_idx;
pdev = &ab->pdevs[pdev_idx]; pdev = &ab->pdevs[pdev_idx];
ar = ath12k_ah_to_ar(ah); ar = ath12k_ah_to_ar(ah, i);
ar->ah = ah; ar->ah = ah;
ar->ab = ab; ar->ab = ab;
ar->hw_link_id = i; ar->hw_link_id = i;
......
...@@ -49,7 +49,7 @@ ath12k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) ...@@ -49,7 +49,7 @@ ath12k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
struct ath12k_wmi_init_country_arg arg; struct ath12k_wmi_init_country_arg arg;
struct ath12k_hw *ah = ath12k_hw_to_ah(hw); struct ath12k_hw *ah = ath12k_hw_to_ah(hw);
struct ath12k *ar = ath12k_ah_to_ar(ah); struct ath12k *ar = ath12k_ah_to_ar(ah, 0);
int ret; int ret;
ath12k_dbg(ar->ab, ATH12K_DBG_REG, ath12k_dbg(ar->ab, ATH12K_DBG_REG,
......
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