Skip to content

Commit a343d97

Browse files
Karthikeyan PeriyasamyJeff Johnson
authored andcommitted
wifi: ath12k: move struct ath12k_hw from per device to group
Currently, hardware abstractions (ah) of different radio bands are tightly coupled to a single device (ab). But, with hardware device group abstraction (ag), multiple radios across different devices in a group can form different combinations of hardware abstractions (ah) within the group. Hence, the mapping between ah to ab can be removed and instead it can be mapped with struct ath12k_hw_group (ag). Current mapping between struct ath12k_hw (ah), struct ath12k_base (ab) and struct ath12k_hw_group (ag): +------------------------------------------------+ | +-------------------------------------+ | | | +---------------+ +---------------+ | | | | |ath12k_hw (ah) | |ath12k_hw (ah) | | | | | +---------------+ +---------------+ | | | | | | | | +-----------+ | +-----------+ | | | | | ar (2GHz) | | | ar (5GHz) | | | | | +-----------+ | +-----------+ | | | | Dual band device-1 (ab) | | | +-------------------------------------+ | | ath12k_hw_group (ag) based on group id | +------------------------------------------------+ After hardware device group abstraction moving ah array out of ab to ag: +----------------------------------------------+ | +---------------+ +---------------+ | | |ath12k_hw (ah) | |ath12k_hw (ah) | | | +---------------+ +---------------+ | | +-------------------------------------+ | | | +-----------+ +-----------+ | | | | | ar (2GHz) | | ar (5GHz) | | | | | +-----------+ +-----------+ | | | | Dual band device-1 (ab) | | | +-------------------------------------+ | | ath12k_hw_group (ag) based on group id | +----------------------------------------------+ This decoupling of struct ath12k_hw (ah) from struct ath12k_base (ab) and mapping it to struct ath12k_hw_group (ag) will help in forming different combinations of multi-link devices. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-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: Karthikeyan Periyasamy <[email protected]> Signed-off-by: Harshitha Prem <[email protected]> Signed-off-by: Kalle Valo <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jeff Johnson <[email protected]>
1 parent ee146e1 commit a343d97

File tree

6 files changed

+115
-82
lines changed

6 files changed

+115
-82
lines changed

drivers/net/wireless/ath/ath12k/core.c

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -861,8 +861,6 @@ static void ath12k_core_device_cleanup(struct ath12k_base *ab)
861861

862862
ath12k_hif_irq_disable(ab);
863863
ath12k_core_pdev_destroy(ab);
864-
ath12k_mac_unregister(ab);
865-
ath12k_mac_destroy(ab);
866864

867865
mutex_unlock(&ab->core_lock);
868866
}
@@ -874,12 +872,18 @@ static void ath12k_core_hw_group_stop(struct ath12k_hw_group *ag)
874872

875873
lockdep_assert_held(&ag->mutex);
876874

875+
clear_bit(ATH12K_GROUP_FLAG_REGISTERED, &ag->flags);
876+
877+
ath12k_mac_unregister(ag);
878+
877879
for (i = ag->num_devices - 1; i >= 0; i--) {
878880
ab = ag->ab[i];
879881
if (!ab)
880882
continue;
881883
ath12k_core_device_cleanup(ab);
882884
}
885+
886+
ath12k_mac_destroy(ag);
883887
}
884888

885889
static int ath12k_core_hw_group_start(struct ath12k_hw_group *ag)
@@ -889,36 +893,27 @@ static int ath12k_core_hw_group_start(struct ath12k_hw_group *ag)
889893

890894
lockdep_assert_held(&ag->mutex);
891895

896+
if (test_bit(ATH12K_GROUP_FLAG_REGISTERED, &ag->flags))
897+
goto core_pdev_create;
898+
899+
ret = ath12k_mac_allocate(ag);
900+
if (WARN_ON(ret))
901+
return ret;
902+
903+
ret = ath12k_mac_register(ag);
904+
if (WARN_ON(ret))
905+
goto err_mac_destroy;
906+
907+
set_bit(ATH12K_GROUP_FLAG_REGISTERED, &ag->flags);
908+
909+
core_pdev_create:
892910
for (i = 0; i < ag->num_devices; i++) {
893911
ab = ag->ab[i];
894912
if (!ab)
895913
continue;
896914

897915
mutex_lock(&ab->core_lock);
898916

899-
/* Check if already registered or not, since same flow
900-
* execute for HW restart case.
901-
*/
902-
if (test_bit(ATH12K_FLAG_REGISTERED, &ab->dev_flags))
903-
goto core_pdev_create;
904-
905-
ret = ath12k_mac_allocate(ab);
906-
if (ret) {
907-
ath12k_err(ab, "failed to create new hw device with mac80211 :%d\n",
908-
ret);
909-
mutex_unlock(&ab->core_lock);
910-
return ret;
911-
}
912-
913-
ret = ath12k_mac_register(ab);
914-
if (ret) {
915-
ath12k_err(ab, "failed to register radio with mac80211: %d\n",
916-
ret);
917-
mutex_unlock(&ab->core_lock);
918-
goto err;
919-
}
920-
921-
core_pdev_create:
922917
ret = ath12k_core_pdev_create(ab);
923918
if (ret) {
924919
ath12k_err(ab, "failed to create pdev core %d\n", ret);
@@ -941,6 +936,10 @@ static int ath12k_core_hw_group_start(struct ath12k_hw_group *ag)
941936

942937
err:
943938
ath12k_core_hw_group_stop(ag);
939+
return ret;
940+
941+
err_mac_destroy:
942+
ath12k_mac_destroy(ag);
944943

945944
return ret;
946945
}

drivers/net/wireless/ath/ath12k/core.h

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
#define ATH12K_RECOVER_START_TIMEOUT_HZ (20 * HZ)
6565

6666
#define ATH12K_MAX_SOCS 3
67+
#define ATH12K_GROUP_MAX_RADIO (ATH12K_MAX_SOCS * MAX_RADIOS)
6768
#define ATH12K_INVALID_GROUP_ID 0xFF
6869
#define ATH12K_INVALID_DEVICE_ID 0xFF
6970

@@ -216,6 +217,10 @@ enum ath12k_scan_state {
216217
ATH12K_SCAN_ABORTING,
217218
};
218219

220+
enum ath12k_hw_group_flags {
221+
ATH12K_GROUP_FLAG_REGISTERED,
222+
};
223+
219224
enum ath12k_dev_flags {
220225
ATH12K_CAC_RUNNING,
221226
ATH12K_FLAG_CRASH_FLUSH,
@@ -830,6 +835,15 @@ struct ath12k_hw_group {
830835

831836
/* protects access to this struct */
832837
struct mutex mutex;
838+
839+
/* Holds information of wiphy (hw) registration.
840+
*
841+
* In Multi/Single Link Operation case, all pdevs are registered as
842+
* a single wiphy. In other (legacy/Non-MLO) cases, each pdev is
843+
* registered as separate wiphys.
844+
*/
845+
struct ath12k_hw *ah[ATH12K_GROUP_MAX_RADIO];
846+
u8 num_hw;
833847
};
834848

835849
/* Master structure to hold the hw data which may be used in core module */
@@ -895,15 +909,6 @@ struct ath12k_base {
895909

896910
struct ath12k_pdev __rcu *pdevs_active[MAX_RADIOS];
897911

898-
/* Holds information of wiphy (hw) registration.
899-
*
900-
* In Multi/Single Link Operation case, all pdevs are registered as
901-
* a single wiphy. In other (legacy/Non-MLO) cases, each pdev is
902-
* registered as separate wiphys.
903-
*/
904-
struct ath12k_hw *ah[MAX_RADIOS];
905-
u8 num_hw;
906-
907912
struct ath12k_wmi_hal_reg_capabilities_ext_arg hal_reg_cap[MAX_RADIOS];
908913
unsigned long long free_vdev_map;
909914
unsigned long long free_vdev_stats_id_map;
@@ -1164,18 +1169,18 @@ static inline struct ieee80211_hw *ath12k_ar_to_hw(struct ath12k *ar)
11641169

11651170
static inline struct ath12k_hw *ath12k_ab_to_ah(struct ath12k_base *ab, int idx)
11661171
{
1167-
return ab->ah[idx];
1172+
return ab->ag->ah[idx];
11681173
}
11691174

11701175
static inline void ath12k_ab_set_ah(struct ath12k_base *ab, int idx,
11711176
struct ath12k_hw *ah)
11721177
{
1173-
ab->ah[idx] = ah;
1178+
ab->ag->ah[idx] = ah;
11741179
}
11751180

11761181
static inline int ath12k_get_num_hw(struct ath12k_base *ab)
11771182
{
1178-
return ab->num_hw;
1183+
return ab->ag->num_hw;
11791184
}
11801185

11811186
static inline struct ath12k_hw_group *ath12k_ab_to_ag(struct ath12k_base *ab)

drivers/net/wireless/ath/ath12k/dp.c

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -991,21 +991,14 @@ void ath12k_dp_pdev_free(struct ath12k_base *ab)
991991
ath12k_dp_rx_pdev_free(ab, i);
992992
}
993993

994-
void ath12k_dp_pdev_pre_alloc(struct ath12k_base *ab)
994+
void ath12k_dp_pdev_pre_alloc(struct ath12k *ar)
995995
{
996-
struct ath12k *ar;
997-
struct ath12k_pdev_dp *dp;
998-
int i;
996+
struct ath12k_pdev_dp *dp = &ar->dp;
999997

1000-
for (i = 0; i < ab->num_radios; i++) {
1001-
ar = ab->pdevs[i].ar;
1002-
dp = &ar->dp;
1003-
dp->mac_id = i;
1004-
atomic_set(&dp->num_tx_pending, 0);
1005-
init_waitqueue_head(&dp->tx_empty_waitq);
1006-
1007-
/* TODO: Add any RXDMA setup required per pdev */
1008-
}
998+
dp->mac_id = ar->pdev_idx;
999+
atomic_set(&dp->num_tx_pending, 0);
1000+
init_waitqueue_head(&dp->tx_empty_waitq);
1001+
/* TODO: Add any RXDMA setup required per pdev */
10091002
}
10101003

10111004
bool ath12k_dp_wmask_compaction_rx_tlv_supported(struct ath12k_base *ab)

drivers/net/wireless/ath/ath12k/dp.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1806,7 +1806,7 @@ void ath12k_dp_free(struct ath12k_base *ab);
18061806
int ath12k_dp_alloc(struct ath12k_base *ab);
18071807
void ath12k_dp_cc_config(struct ath12k_base *ab);
18081808
int ath12k_dp_pdev_alloc(struct ath12k_base *ab);
1809-
void ath12k_dp_pdev_pre_alloc(struct ath12k_base *ab);
1809+
void ath12k_dp_pdev_pre_alloc(struct ath12k *ar);
18101810
void ath12k_dp_pdev_free(struct ath12k_base *ab);
18111811
int ath12k_dp_tx_htt_srng_setup(struct ath12k_base *ab, u32 ring_id,
18121812
int mac_id, enum hal_ring_type ring_type);

drivers/net/wireless/ath/ath12k/mac.c

Lines changed: 62 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10818,19 +10818,13 @@ static void ath12k_mac_setup(struct ath12k *ar)
1081810818
skb_queue_head_init(&ar->wmi_mgmt_tx_queue);
1081910819
}
1082010820

10821-
int ath12k_mac_register(struct ath12k_base *ab)
10821+
int ath12k_mac_register(struct ath12k_hw_group *ag)
1082210822
{
10823+
struct ath12k_base *ab = ag->ab[0];
1082310824
struct ath12k_hw *ah;
1082410825
int i;
1082510826
int ret;
1082610827

10827-
if (test_bit(ATH12K_FLAG_REGISTERED, &ab->dev_flags))
10828-
return 0;
10829-
10830-
/* Initialize channel counters frequency value in hertz */
10831-
ab->cc_freq_hz = 320000;
10832-
ab->free_vdev_map = (1LL << (ab->num_radios * TARGET_NUM_VDEVS)) - 1;
10833-
1083410828
for (i = 0; i < ath12k_get_num_hw(ab); i++) {
1083510829
ah = ath12k_ab_to_ah(ab, i);
1083610830

@@ -10855,8 +10849,9 @@ int ath12k_mac_register(struct ath12k_base *ab)
1085510849
return ret;
1085610850
}
1085710851

10858-
void ath12k_mac_unregister(struct ath12k_base *ab)
10852+
void ath12k_mac_unregister(struct ath12k_hw_group *ag)
1085910853
{
10854+
struct ath12k_base *ab = ag->ab[0];
1086010855
struct ath12k_hw *ah;
1086110856
int i;
1086210857

@@ -10876,12 +10871,13 @@ static void ath12k_mac_hw_destroy(struct ath12k_hw *ah)
1087610871
ieee80211_free_hw(ah->hw);
1087710872
}
1087810873

10879-
static struct ath12k_hw *ath12k_mac_hw_allocate(struct ath12k_base *ab,
10874+
static struct ath12k_hw *ath12k_mac_hw_allocate(struct ath12k_hw_group *ag,
1088010875
struct ath12k_pdev_map *pdev_map,
1088110876
u8 num_pdev_map)
1088210877
{
1088310878
struct ieee80211_hw *hw;
1088410879
struct ath12k *ar;
10880+
struct ath12k_base *ab;
1088510881
struct ath12k_pdev *pdev;
1088610882
struct ath12k_hw *ah;
1088710883
int i;
@@ -10913,23 +10909,30 @@ static struct ath12k_hw *ath12k_mac_hw_allocate(struct ath12k_base *ab,
1091310909
pdev->ar = ar;
1091410910

1091510911
ath12k_mac_setup(ar);
10912+
ath12k_dp_pdev_pre_alloc(ar);
1091610913
}
1091710914

1091810915
return ah;
1091910916
}
1092010917

10921-
void ath12k_mac_destroy(struct ath12k_base *ab)
10918+
void ath12k_mac_destroy(struct ath12k_hw_group *ag)
1092210919
{
1092310920
struct ath12k_pdev *pdev;
10921+
struct ath12k_base *ab = ag->ab[0];
10922+
int i, j;
1092410923
struct ath12k_hw *ah;
10925-
int i;
1092610924

10927-
for (i = 0; i < ab->num_radios; i++) {
10928-
pdev = &ab->pdevs[i];
10929-
if (!pdev->ar)
10925+
for (i = 0; i < ag->num_devices; i++) {
10926+
ab = ag->ab[i];
10927+
if (!ab)
1093010928
continue;
1093110929

10932-
pdev->ar = NULL;
10930+
for (j = 0; j < ab->num_radios; j++) {
10931+
pdev = &ab->pdevs[j];
10932+
if (!pdev->ar)
10933+
continue;
10934+
pdev->ar = NULL;
10935+
}
1093310936
}
1093410937

1093510938
for (i = 0; i < ath12k_get_num_hw(ab); i++) {
@@ -10942,26 +10945,59 @@ void ath12k_mac_destroy(struct ath12k_base *ab)
1094210945
}
1094310946
}
1094410947

10945-
int ath12k_mac_allocate(struct ath12k_base *ab)
10948+
static void ath12k_mac_set_device_defaults(struct ath12k_base *ab)
10949+
{
10950+
/* Initialize channel counters frequency value in hertz */
10951+
ab->cc_freq_hz = 320000;
10952+
ab->free_vdev_map = (1LL << (ab->num_radios * TARGET_NUM_VDEVS)) - 1;
10953+
}
10954+
10955+
int ath12k_mac_allocate(struct ath12k_hw_group *ag)
1094610956
{
10957+
struct ath12k_pdev_map pdev_map[ATH12K_GROUP_MAX_RADIO];
10958+
int mac_id, device_id, total_radio, num_hw;
10959+
struct ath12k_base *ab;
1094710960
struct ath12k_hw *ah;
10948-
struct ath12k_pdev_map pdev_map[MAX_RADIOS];
1094910961
int ret, i, j;
1095010962
u8 radio_per_hw;
1095110963

10952-
if (test_bit(ATH12K_FLAG_REGISTERED, &ab->dev_flags))
10953-
return 0;
10964+
total_radio = 0;
10965+
for (i = 0; i < ag->num_devices; i++)
10966+
total_radio += ag->ab[i]->num_radios;
1095410967

10955-
ab->num_hw = ab->num_radios;
10968+
/* All pdev get combined and register as single wiphy based on
10969+
* hardware group which participate in multi-link operation else
10970+
* each pdev get register separately.
10971+
*
10972+
* Currently, registering as single pdevs.
10973+
*/
1095610974
radio_per_hw = 1;
10975+
num_hw = total_radio / radio_per_hw;
1095710976

10958-
for (i = 0; i < ath12k_get_num_hw(ab); i++) {
10977+
if (WARN_ON(num_hw >= ATH12K_GROUP_MAX_RADIO))
10978+
return -ENOSPC;
10979+
10980+
ag->num_hw = 0;
10981+
device_id = 0;
10982+
mac_id = 0;
10983+
for (i = 0; i < num_hw; i++) {
1095910984
for (j = 0; j < radio_per_hw; j++) {
10985+
ab = ag->ab[device_id];
1096010986
pdev_map[j].ab = ab;
10961-
pdev_map[j].pdev_idx = (i * radio_per_hw) + j;
10987+
pdev_map[j].pdev_idx = mac_id;
10988+
mac_id++;
10989+
10990+
/* If mac_id falls beyond the current device MACs then
10991+
* move to next device
10992+
*/
10993+
if (mac_id >= ab->num_radios) {
10994+
mac_id = 0;
10995+
device_id++;
10996+
ath12k_mac_set_device_defaults(ab);
10997+
}
1096210998
}
1096310999

10964-
ah = ath12k_mac_hw_allocate(ab, pdev_map, radio_per_hw);
11000+
ah = ath12k_mac_hw_allocate(ag, pdev_map, radio_per_hw);
1096511001
if (!ah) {
1096611002
ath12k_warn(ab, "failed to allocate mac80211 hw device for hw_idx %d\n",
1096711003
i);
@@ -10971,11 +11007,10 @@ int ath12k_mac_allocate(struct ath12k_base *ab)
1097111007

1097211008
ah->dev = ab->dev;
1097311009

10974-
ath12k_ab_set_ah(ab, i, ah);
11010+
ag->ah[i] = ah;
11011+
ag->num_hw++;
1097511012
}
1097611013

10977-
ath12k_dp_pdev_pre_alloc(ab);
10978-
1097911014
return 0;
1098011015

1098111016
err:

drivers/net/wireless/ath/ath12k/mac.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
struct ath12k;
1515
struct ath12k_base;
1616
struct ath12k_hw;
17+
struct ath12k_hw_group;
1718
struct ath12k_pdev_map;
1819

1920
struct ath12k_generic_iter {
@@ -60,10 +61,10 @@ enum ath12k_supported_bw {
6061

6162
extern const struct htt_rx_ring_tlv_filter ath12k_mac_mon_status_filter_default;
6263

63-
void ath12k_mac_destroy(struct ath12k_base *ab);
64-
void ath12k_mac_unregister(struct ath12k_base *ab);
65-
int ath12k_mac_register(struct ath12k_base *ab);
66-
int ath12k_mac_allocate(struct ath12k_base *ab);
64+
void ath12k_mac_destroy(struct ath12k_hw_group *ag);
65+
void ath12k_mac_unregister(struct ath12k_hw_group *ag);
66+
int ath12k_mac_register(struct ath12k_hw_group *ag);
67+
int ath12k_mac_allocate(struct ath12k_hw_group *ag);
6768
int ath12k_mac_hw_ratecode_to_legacy_rate(u8 hw_rc, u8 preamble, u8 *rateidx,
6869
u16 *rate);
6970
u8 ath12k_mac_bitrate_to_idx(const struct ieee80211_supported_band *sband,

0 commit comments

Comments
 (0)