diff options
-rw-r--r-- | drivers/net/wireless/ath/ath12k/core.c | 17 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath12k/core.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath12k/mac.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath12k/qmi.c | 6 |
4 files changed, 29 insertions, 5 deletions
diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index 18b29515c6ae..49d1ac15cb7a 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -1439,6 +1439,7 @@ static struct ath12k_hw_group *ath12k_core_hw_group_assign(struct ath12k_base *a ab->device_id = ag->num_probed++; ag->ab[ab->device_id] = ab; ab->ag = ag; + ag->mlo_capable = false; return ag; } @@ -1548,6 +1549,22 @@ static int ath12k_core_hw_group_create(struct ath12k_hw_group *ag) return 0; } +void ath12k_core_hw_group_set_mlo_capable(struct ath12k_hw_group *ag) +{ + lockdep_assert_held(&ag->mutex); + + /* If more than one devices are grouped, then inter MLO + * functionality can work still independent of whether internally + * each device supports single_chip_mlo or not. + * Only when there is one device, then it depends whether the + * device can support intra chip MLO or not + */ + if (ag->num_devices > 1) + ag->mlo_capable = true; + else + ag->mlo_capable = ag->ab[0]->single_chip_mlo_supp; +} + int ath12k_core_init(struct ath12k_base *ab) { struct ath12k_hw_group *ag; diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index 64252d6491cd..458e3d0071a8 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -844,6 +844,7 @@ struct ath12k_hw_group { */ struct ath12k_hw *ah[ATH12K_GROUP_MAX_RADIO]; u8 num_hw; + bool mlo_capable; }; /* Master structure to hold the hw data which may be used in core module */ @@ -1066,6 +1067,8 @@ u32 ath12k_core_get_max_station_per_radio(struct ath12k_base *ab); u32 ath12k_core_get_max_peers_per_radio(struct ath12k_base *ab); u32 ath12k_core_get_max_num_tids(struct ath12k_base *ab); +void ath12k_core_hw_group_set_mlo_capable(struct ath12k_hw_group *ag); + static inline const char *ath12k_scan_state_str(enum ath12k_scan_state state) { switch (state) { diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 1cf724a530b5..c4eab4c1c10e 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -10968,10 +10968,12 @@ int ath12k_mac_allocate(struct ath12k_hw_group *ag) /* All pdev get combined and register as single wiphy based on * hardware group which participate in multi-link operation else * each pdev get register separately. - * - * Currently, registering as single pdevs. */ - radio_per_hw = 1; + if (ag->mlo_capable) + radio_per_hw = total_radio; + else + radio_per_hw = 1; + num_hw = total_radio / radio_per_hw; if (WARN_ON(num_hw >= ATH12K_GROUP_MAX_RADIO)) diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c index 2591d132a3fc..ba3cd2342465 100644 --- a/drivers/net/wireless/ath/ath12k/qmi.c +++ b/drivers/net/wireless/ath/ath12k/qmi.c @@ -2023,9 +2023,9 @@ static void ath12k_host_cap_parse_mlo(struct ath12k_base *ab, u8 hw_link_id = 0; int i; - if (!ab->single_chip_mlo_supp) { + if (!ab->ag->mlo_capable) { ath12k_dbg(ab, ATH12K_DBG_QMI, - "intra device MLO is disabled hence skip QMI MLO cap"); + "MLO is disabled hence skip QMI MLO cap"); return; } @@ -3170,6 +3170,8 @@ int ath12k_qmi_event_server_arrive(struct ath12k_qmi *qmi) mutex_lock(&ag->mutex); if (ath12k_qmi_hw_group_host_cap_ready(ag)) { + ath12k_core_hw_group_set_mlo_capable(ag); + block_ab = ath12k_qmi_hw_group_find_blocked(ag); if (block_ab) ath12k_qmi_trigger_host_cap(block_ab); |