wifi: ath12k: MLO support part 8
cover wifi: ath12k: MLO support part 8
From: Kalle Valo <[email protected]>
Getting MLO to work with QCN9274 is getting close, this should be the second to last patchset. Small patches this time. Minor changes to data path to support MLO, some interface combination rework and few fixes.
Please review.
Aditya Kumar Singh (3):
wifi: ath12k: fix ath12k_qmi_alloc_chunk() to handle too large
allocations
wifi: ath12k: fix ar->supports_6ghz usage during hw register
wifi: ath12k: pass link ID during MLO while delivering skb
Karthikeyan Periyasamy (6):
wifi: ath12k: move to HW link id based reveive handling
wifi: ath12k: add partner device buffer support in receive data path
wifi: ath12k: add helper function to init partner cmem configuration
wifi: ath12k: introduce interface combination cleanup helper
wifi: ath12k: Refactor radio frequency information
wifi: ath12k: advertise multi device interface combination
drivers/net/wireless/ath/ath12k/core.c | 5 +- drivers/net/wireless/ath/ath12k/core.h | 17 +- drivers/net/wireless/ath/ath12k/dp.c | 14 ++ drivers/net/wireless/ath/ath12k/dp.h | 4 +- drivers/net/wireless/ath/ath12k/dp_mon.c | 8 +- drivers/net/wireless/ath/ath12k/dp_rx.c | 213 +++++++++++++------ drivers/net/wireless/ath/ath12k/mac.c | 247 +++++++++++++++++++---- drivers/net/wireless/ath/ath12k/peer.c | 2 + drivers/net/wireless/ath/ath12k/peer.h | 3 + drivers/net/wireless/ath/ath12k/qmi.c | 10 +- 10 files changed, 414 insertions(+), 109 deletions(-)
base-commit: 400568fb3b022247c1603fdbdd6444b3ef14ffce
prerequisite-patch-id: 721655de1e9eb1b723c3340c80f52be7ab6e73a7
prerequisite-patch-id: 99576487c570edbaf46b35e8ba6b9e20ad9bf85c
prerequisite-patch-id: f0a242859176e986640595256e7f488561683309
prerequisite-patch-id: 532325a3a8da40d6b43ef643f38dca5389750820
prerequisite-patch-id: 1a0adfd0f7ad52c7d0ddd6466659e7a8a229013b
prerequisite-patch-id: e1a1418434e24374ef1ad04a49249436de602dd8
prerequisite-patch-id: 8847add439503b799079f8cfa043b15b57691d7f
prerequisite-patch-id: 017994ce11ee18d218464d1bb5ffb50ac8d941a5
Signature · 1 line
2.39.5
PATCH 1/9 wifi: ath12k: move to HW link id based reveive handling
From: Karthikeyan Periyasamy <[email protected]>
Currently, all the rx processing treats the hardware link id as the MAC id. The HW link id is a unique identifier for all hardware links participating in the multi link group. Therefore, the current MAC id derivation is insufficient to process the partner rx buffer in the Multi-Link Operation. So derive the MAC id from the HW link id and implementing this change in rx processing will enable the scaling of partner buffer processing in Multi-Link Operation.
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
--- drivers/net/wireless/ath/ath12k/core.h | 8 +++- drivers/net/wireless/ath/ath12k/dp_rx.c | 49 +++++++++++++++---------- drivers/net/wireless/ath/ath12k/mac.c | 3 ++ 3 files changed, 39 insertions(+), 21 deletions(-)
drivers/net/wireless/ath/ath12k/core.h +7 -1
@@ -136,7 +136,7 @@ struct ath12k_skb_rxcb {struct hal_rx_desc *rx_desc;u8 err_rel_src;u8 err_code; -u8 mac_id; +u8 hw_link_id;u8 unmapped;u8 is_frag;u8 tid;
@@ -831,6 +831,11 @@ struct ath12k_mlo_memory {bool init_done; }; +struct ath12k_hw_link { +u8 device_id; +u8 pdev_idx; +}; +/* Holds info on the group of devices that are registered as a single * wiphy, protected with struct ath12k_hw_group::mutex. */
@@ -857,6 +862,7 @@ struct ath12k_hw_group {bool mlo_capable;struct device_node *wsi_node[ATH12K_MAX_SOCS ];struct ath12k_mlo_memory mlo_mem; +struct ath12k_hw_link hw_links[ATH12K_GROUP_MAX_RADIO ]; };/* Holds WSI info specific to each device, excluding WSI group info */
drivers/net/wireless/ath/ath12k/dp_rx.c +29 -20
141 lines not on this page · raw message
drivers/net/wireless/ath/ath12k/mac.c +3 -0
@@ -11050,6 +11050,9 @@ static struct ath12k_hw *ath12k_mac_hw_allocate(struct ath12k_hw_group *ag, ar->pdev_idx = pdev_idx; pdev->ar = ar; + ag->hw_links[ar->hw_link_id].device_id = ab->device_id; + ag->hw_links[ar->hw_link_id].pdev_idx = pdev_idx; +ath12k_mac_setup (ar);ath12k_dp_pdev_pre_alloc (ar); }
Signature · 1 line
2.39.5
Re: [PATCH 1/9] wifi: ath12k: move to HW link id based reveive handling
Subject nit: s/reveive/receive/
I'll fixup in 'pending' if there are no additional comments on this series
Re: [PATCH 1/9] wifi: ath12k: move to HW link id based reveive handling
Quoted 3 lines · Jeff Johnson
Subject nit: s/reveive/receive/
I'll fixup in 'pending' if there are no additional comments on this series
Great, thanks.
Signature · 3 lines
https://patchwork.kernel.org/project/linux-wireless/list/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
PATCH 2/9 wifi: ath12k: add partner device buffer support in receive data path
In reply to Kalle ValoFrom: Karthikeyan Periyasamy <[email protected]>
Currently, partner device buffer is not handled in the receive data path. In Multi-Link Operation, the partner device buffer is reported to the primary upper MAC rings. Therefore, add partner device buffer processing in the REO and Exception ring handler.
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
--- drivers/net/wireless/ath/ath12k/core.h | 6 + drivers/net/wireless/ath/ath12k/dp.c | 1 + drivers/net/wireless/ath/ath12k/dp.h | 3 +- drivers/net/wireless/ath/ath12k/dp_rx.c | 179 +++++++++++++++++------- 4 files changed, 140 insertions(+), 49 deletions(-)
drivers/net/wireless/ath/ath12k/core.h +6 -0
@@ -1229,4 +1229,10 @@ static inline void ath12k_core_stopped(struct ath12k_base *ab) ab->ag->num_started--; } +static inline struct ath12k_base *ath12k_ag_to_ab (struct ath12k_hw_group *ag, +u8 device_id) +{ +return ag->ab[device_id]; +} +#endif /* _CORE_H_ */
drivers/net/wireless/ath/ath12k/dp.c +1 -0
@@ -1445,6 +1445,7 @@ static int ath12k_dp_cc_desc_init(struct ath12k_base *ab)for (j =0 ; j <ATH12K_MAX_SPT_ENTRIES ; j++) { rx_descs[j].cookie =ath12k_dp_cc_cookie_gen (cookie_ppt_idx, j); rx_descs[j].magic =ATH12K_DP_RX_DESC_MAGIC ; + rx_descs[j].device_id = ab->device_id;list_add_tail (&rx_descs[j].list, &dp->rx_desc_free_list);/* Update descriptor VA in SPT */
drivers/net/wireless/ath/ath12k/dp.h +2 -1
@@ -287,7 +287,8 @@ struct ath12k_rx_desc_info {u32 cookie;u32 magic; u8 in_use : 1, - reserved : 7; + device_id : 3, + reserved : 4; };struct ath12k_tx_desc_info {
drivers/net/wireless/ath/ath12k/dp_rx.c +131 -48
357 lines not on this page · raw message
Signature · 1 line
2.39.5
PATCH 3/9 wifi: ath12k: add helper function to init partner cmem configuration
In reply to Kalle ValoFrom: Karthikeyan Periyasamy <[email protected]>
In the Inter Multi-Link Operation, the primary device is expected to receive the partner device buffer. Therefore, each device initializes the partner device buffer in their cmem configuration. So add a helper function to initialize the partner device buffer in their cmem configuration.
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
--- drivers/net/wireless/ath/ath12k/core.c | 5 ++++- drivers/net/wireless/ath/ath12k/dp.c | 13 +++++++++++++ drivers/net/wireless/ath/ath12k/dp.h | 1 + 3 files changed, 18 insertions(+), 1 deletion(-)
drivers/net/wireless/ath/ath12k/core.c +4 -1
@@ -930,7 +930,7 @@ int ath12k_mac_mlo_ready(struct ath12k_hw_group *ag)static int ath12k_core_mlo_setup (struct ath12k_hw_group *ag) { -int ret; +int ret, i;if (!ag->mlo_capable || ag->num_devices ==1 )return 0 ;
@@ -939,6 +939,9 @@ static int ath12k_core_mlo_setup(struct ath12k_hw_group *ag)if (ret)return ret; +for (i =0 ; i < ag->num_devices; i++) +ath12k_dp_partner_cc_init (ag->ab[i]); + ret =ath12k_mac_mlo_ready (ag);if (ret) goto err_mlo_teardown;
drivers/net/wireless/ath/ath12k/dp.c +13 -0
@@ -1522,6 +1522,19 @@ static int ath12k_dp_cmem_init(struct ath12k_base *ab,return 0 ; } +void ath12k_dp_partner_cc_init (struct ath12k_base *ab) +{ +struct ath12k_hw_group *ag = ab->ag; +int i; + +for (i =0 ; i < ag->num_devices; i++) { +if (ag->ab[i] == ab) +continue ; + +ath12k_dp_cmem_init (ab, &ag->ab[i]->dp,ATH12K_DP_RX_DESC ); + } +} +static int ath12k_dp_cc_init (struct ath12k_base *ab) {struct ath12k_dp *dp = &ab->dp;
drivers/net/wireless/ath/ath12k/dp.h +1 -0
@@ -1806,6 +1806,7 @@ void ath12k_dp_vdev_tx_attach(struct ath12k *ar, struct ath12k_link_vif *arvif);void ath12k_dp_free (struct ath12k_base *ab);int ath12k_dp_alloc (struct ath12k_base *ab);void ath12k_dp_cc_config (struct ath12k_base *ab); +void ath12k_dp_partner_cc_init (struct ath12k_base *ab);int ath12k_dp_pdev_alloc (struct ath12k_base *ab);void ath12k_dp_pdev_pre_alloc (struct ath12k *ar);void ath12k_dp_pdev_free (struct ath12k_base *ab);
Signature · 1 line
2.39.5
PATCH 4/9 wifi: ath12k: introduce interface combination cleanup helper
In reply to Kalle ValoFrom: Karthikeyan Periyasamy <[email protected]>
Introduce a cleanup helper function to avoid redundant code for interface combination cleanup. Remove the cleanup code from ath12k_mac_hw_unregister() and ath12k_mac_hw_register() and replace it with a new cleanup helper function.
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
--- drivers/net/wireless/ath/ath12k/mac.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-)
drivers/net/wireless/ath/ath12k/mac.c +13 -8
@@ -10351,6 +10351,14 @@ static bool ath12k_mac_is_iface_mode_enable(struct ath12k_hw *ah,return is_enable; } +static void ath12k_mac_cleanup_iface_combinations (struct ath12k_hw *ah) +{ +struct wiphy *wiphy = ah->hw->wiphy; + +kfree (wiphy->iface_combinations[0 ].limits); +kfree (wiphy->iface_combinations); +} +static int ath12k_mac_setup_iface_combinations (struct ath12k_hw *ah) {struct wiphy *wiphy = ah->hw->wiphy;
@@ -10479,7 +10487,6 @@ static void ath12k_mac_cleanup_unregister(struct ath12k *ar)static void ath12k_mac_hw_unregister (struct ath12k_hw *ah) {struct ieee80211_hw *hw = ah->hw; -struct wiphy *wiphy = hw->wiphy;struct ath12k *ar;int i;
@@ -10493,8 +10500,7 @@ static void ath12k_mac_hw_unregister(struct ath12k_hw *ah)for_each_ar (ah, ar, i)ath12k_mac_cleanup_unregister (ar); -kfree (wiphy->iface_combinations[0 ].limits); -kfree (wiphy->iface_combinations); +ath12k_mac_cleanup_iface_combinations (ah);SET_IEEE80211_DEV (hw,NULL ); }
@@ -10724,13 +10730,13 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah) ret =ath12k_wow_init (ar);if (ret) {ath12k_warn (ar->ab,"failed to init wow: %d\n" , ret); - goto err_free_if_combs; + goto err_cleanup_if_combs; } ret =ieee80211_register_hw (hw);if (ret) {ath12k_err (ab,"ieee80211 registration failed: %d\n" , ret); - goto err_free_if_combs; + goto err_cleanup_if_combs; }if (is_monitor_disable)
@@ -10760,9 +10766,8 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah)ieee80211_unregister_hw (hw); -err_free_if_combs: -kfree (wiphy->iface_combinations[0 ].limits); -kfree (wiphy->iface_combinations); +err_cleanup_if_combs: +ath12k_mac_cleanup_iface_combinations (ah); err_complete_cleanup_unregister: i = ah->num_radio;
Signature · 1 line
2.39.5
PATCH 5/9 wifi: ath12k: Refactor radio frequency information
In reply to Kalle ValoFrom: Karthikeyan Periyasamy <[email protected]>
Currently, radio stores the low frequency and high frequency information as separate variables. However, cfg80211 already provides a suitable data structure struct wiphy_radio_freq_range to store this information efficiently. Additionally, for multi radio per wiphy infrastructure, this frequency range information is essential. In future patches using struct wiphy_radio_freq_range makes the code simpler.
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
--- drivers/net/wireless/ath/ath12k/core.h | 3 +-- drivers/net/wireless/ath/ath12k/mac.c | 8 ++++---- 2 files changed, 5 insertions(+), 6 deletions(-)
drivers/net/wireless/ath/ath12k/core.h +1 -2
@@ -711,8 +711,7 @@ struct ath12k {bool monitor_started;int monitor_vdev_id; -u32 freq_low; -u32 freq_high; +struct wiphy_radio_freq_range freq_range;bool nlo_enabled;
drivers/net/wireless/ath/ath12k/mac.c +4 -4
@@ -708,8 +708,8 @@ static struct ath12k *ath12k_mac_get_ar_by_chan(struct ieee80211_hw *hw,return ar;for_each_ar (ah, ar, i) { -if (channel->center_freq >= ar->freq_low && - channel->center_freq <= ar->freq_high) +if (channel->center_freq >=KHZ_TO_MHZ (ar->freq_range.start_freq) && + channel->center_freq <=KHZ_TO_MHZ (ar->freq_range.end_freq))return ar; }return NULL ;
@@ -10203,8 +10203,8 @@ static void ath12k_mac_update_ch_list(struct ath12k *ar, band->channels[i].flags |=IEEE80211_CHAN_DISABLED ; } - ar->freq_low = freq_low; - ar->freq_high = freq_high; + ar->freq_range.start_freq =MHZ_TO_KHZ (freq_low); + ar->freq_range.end_freq =MHZ_TO_KHZ (freq_high); }static u32 ath12k_get_phy_id (struct ath12k *ar,u32 band)
Signature · 1 line
2.39.5
PATCH 6/9 wifi: ath12k: advertise multi device interface combination
In reply to Kalle ValoFrom: Karthikeyan Periyasamy <[email protected]>
The prerequisite for MLO support in cfg80211/mac80211 requires that all the links participating in MLO belong to the same wiphy/struct ieee80211_hw. The driver needs to group multiple discrete hardware components, each acting as a link in MLO, under one wiphy. Consequently, the driver advertises multi-hardware device interface combination capabilities specific to the radio, including supported frequencies. The global interface combination represent the combined interface capabilities.
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
--- drivers/net/wireless/ath/ath12k/mac.c | 222 +++++++++++++++++++++----- 1 file changed, 185 insertions(+), 37 deletions(-)
drivers/net/wireless/ath/ath12k/mac.c +185 -37
@@ -10336,14 +10336,20 @@ static bool ath12k_mac_is_iface_mode_enable(struct ath12k_hw *ah, {struct ath12k *ar;int i; -u16 interface_modes, mode; -bool is_enable = true; +u16 interface_modes, mode =0 ; +bool is_enable = false; + +if (type ==NL80211_IFTYPE_MESH_POINT ) { +if (IS_ENABLED (CONFIG_MAC80211_MESH )) + mode =BIT (type); + }else { + mode =BIT (type); + } - mode =BIT (type);for_each_ar (ah, ar, i) { interface_modes = ar->ab->hw_params->interface_modes; -if (!(interface_modes & mode)) { - is_enable = false; +if (interface_modes & mode) { + is_enable = true;break ; } }
@@ -10351,31 +10357,20 @@ static bool ath12k_mac_is_iface_mode_enable(struct ath12k_hw *ah,return is_enable; } -static void ath12k_mac_cleanup_iface_combinations (struct ath12k_hw *ah) +static int +ath12k_mac_setup_radio_iface_comb (struct ath12k *ar, +struct ieee80211_iface_combination *comb) { -struct wiphy *wiphy = ah->hw->wiphy; - -kfree (wiphy->iface_combinations[0 ].limits); -kfree (wiphy->iface_combinations); -} - -static int ath12k_mac_setup_iface_combinations (struct ath12k_hw *ah) -{ -struct wiphy *wiphy = ah->hw->wiphy; -struct ieee80211_iface_combination *combinations; +u16 interface_modes = ar->ab->hw_params->interface_modes;struct ieee80211_iface_limit *limits;int n_limits, max_interfaces;bool ap, mesh, p2p; - ap =ath12k_mac_is_iface_mode_enable (ah,NL80211_IFTYPE_AP ); - p2p =ath12k_mac_is_iface_mode_enable (ah,NL80211_IFTYPE_P2P_DEVICE ); + ap = interface_modes &BIT (NL80211_IFTYPE_AP ); + p2p = interface_modes &BIT (NL80211_IFTYPE_P2P_DEVICE ); mesh =IS_ENABLED (CONFIG_MAC80211_MESH ) && -ath12k_mac_is_iface_mode_enable (ah,NL80211_IFTYPE_MESH_POINT ); - - combinations =kzalloc (sizeof (*combinations),GFP_KERNEL ); -if (!combinations) -return -ENOMEM ; + (interface_modes &BIT (NL80211_IFTYPE_MESH_POINT ));if ((ap || mesh) && !p2p) { n_limits =2 ;
@@ -10392,10 +10387,8 @@ static int ath12k_mac_setup_iface_combinations(struct ath12k_hw *ah) } limits =kcalloc (n_limits,sizeof (*limits),GFP_KERNEL ); -if (!limits) { -kfree (combinations); +if (!limits)return -ENOMEM ; - } limits[0 ].max =1 ; limits[0 ].types |=BIT (NL80211_IFTYPE_STATION );
@@ -10411,26 +10404,181 @@ static int ath12k_mac_setup_iface_combinations(struct ath12k_hw *ah)if (p2p) { limits[1 ].types |=BIT (NL80211_IFTYPE_P2P_CLIENT ) | -BIT (NL80211_IFTYPE_P2P_GO ); +BIT (NL80211_IFTYPE_P2P_GO ); limits[2 ].max =1 ; limits[2 ].types |=BIT (NL80211_IFTYPE_P2P_DEVICE ); } - combinations[0 ].limits = limits; - combinations[0 ].n_limits = n_limits; - combinations[0 ].max_interfaces = max_interfaces; - combinations[0 ].num_different_channels =1 ; - combinations[0 ].beacon_int_infra_match = true; - combinations[0 ].beacon_int_min_gcd =100 ; - combinations[0 ].radar_detect_widths =BIT (NL80211_CHAN_WIDTH_20_NOHT ) | -BIT (NL80211_CHAN_WIDTH_20 ) | -BIT (NL80211_CHAN_WIDTH_40 ) | -BIT (NL80211_CHAN_WIDTH_80 ); + comb[0 ].limits = limits; + comb[0 ].n_limits = n_limits; + comb[0 ].max_interfaces = max_interfaces; + comb[0 ].num_different_channels =1 ; + comb[0 ].beacon_int_infra_match = true; + comb[0 ].beacon_int_min_gcd =100 ; + comb[0 ].radar_detect_widths =BIT (NL80211_CHAN_WIDTH_20_NOHT ) | +BIT (NL80211_CHAN_WIDTH_20 ) | +BIT (NL80211_CHAN_WIDTH_40 ) | +BIT (NL80211_CHAN_WIDTH_80 ); +return 0 ; +} + +static int +ath12k_mac_setup_global_iface_comb (struct ath12k_hw *ah, +struct wiphy_radio *radio, +u8 n_radio, +struct ieee80211_iface_combination *comb) +{ +const struct ieee80211_iface_combination *iter_comb; +struct ieee80211_iface_limit *limits; +int i, j, n_limits; +bool ap, mesh, p2p; + +if (!n_radio) +return 0 ; + + ap =ath12k_mac_is_iface_mode_enable (ah,NL80211_IFTYPE_AP ); + p2p =ath12k_mac_is_iface_mode_enable (ah,NL80211_IFTYPE_P2P_DEVICE ); + mesh =ath12k_mac_is_iface_mode_enable (ah,NL80211_IFTYPE_MESH_POINT ); + +if ((ap || mesh) && !p2p) + n_limits =2 ; +else if (p2p) + n_limits =3 ; +else + n_limits =1 ; + + limits =kcalloc (n_limits,sizeof (*limits),GFP_KERNEL ); +if (!limits) +return -ENOMEM ; + +for (i =0 ; i < n_radio; i++) { + iter_comb = radio[i].iface_combinations; +for (j =0 ; j < iter_comb->n_limits && j < n_limits; j++) { + limits[j].types |= iter_comb->limits[j].types; + limits[j].max += iter_comb->limits[j].max; + } + + comb->max_interfaces += iter_comb->max_interfaces; + comb->num_different_channels += iter_comb->num_different_channels; + comb->radar_detect_widths |= iter_comb->radar_detect_widths; + } + + comb->limits = limits; + comb->n_limits = n_limits; + comb->beacon_int_infra_match = true; + comb->beacon_int_min_gcd =100 ; + +return 0 ; +} + +static +void ath12k_mac_cleanup_iface_comb (const struct ieee80211_iface_combination *iface_comb) +{ +kfree (iface_comb[0 ].limits); +kfree (iface_comb); +} + +static void ath12k_mac_cleanup_iface_combinations (struct ath12k_hw *ah) +{ +struct wiphy *wiphy = ah->hw->wiphy; +const struct wiphy_radio *radio; +int i; + +if (wiphy->n_radio >0 ) { + radio = wiphy->radio; +for (i =0 ; i < wiphy->n_radio; i++) +ath12k_mac_cleanup_iface_comb (radio[i].iface_combinations); + +kfree (wiphy->radio); + } + +ath12k_mac_cleanup_iface_comb (wiphy->iface_combinations); +} + +static int ath12k_mac_setup_iface_combinations (struct ath12k_hw *ah) +{ +struct ieee80211_iface_combination *combinations, *comb; +struct wiphy *wiphy = ah->hw->wiphy; +struct wiphy_radio *radio; +struct ath12k *ar; +int i, ret; + + combinations =kzalloc (sizeof (*combinations),GFP_KERNEL ); +if (!combinations) +return -ENOMEM ; + +if (ah->num_radio ==1 ) { + ret =ath12k_mac_setup_radio_iface_comb (&ah->radio[0 ], + combinations); +if (ret) { +ath12k_hw_warn (ah,"failed to setup radio interface combinations for one radio: %d" , + ret); + goto err_free_combinations; + } + + goto out; + } + +/* there are multiple radios */ + + radio =kcalloc (ah->num_radio,sizeof (*radio),GFP_KERNEL ); +if (!radio) { + ret = -ENOMEM ; + goto err_free_combinations; + } + +for_each_ar (ah, ar, i) { + comb =kzalloc (sizeof (*comb),GFP_KERNEL ); +if (!comb) { + ret = -ENOMEM ; + goto err_free_radios; + } + + ret =ath12k_mac_setup_radio_iface_comb (ar, comb); +if (ret) { +ath12k_hw_warn (ah,"failed to setup radio interface combinations for radio %d: %d" , + i, ret); +kfree (comb); + goto err_free_radios; + } + + radio[i].freq_range = &ar->freq_range; + radio[i].n_freq_range =1 ; + + radio[i].iface_combinations = comb; + radio[i].n_iface_combinations =1 ; + } + + ret =ath12k_mac_setup_global_iface_comb (ah, radio, ah->num_radio, combinations); +if (ret) { +ath12k_hw_warn (ah,"failed to setup global interface combinations: %d" , + ret); + goto err_free_all_radios; + } + + wiphy->radio = radio; + wiphy->n_radio = ah->num_radio; + +out: wiphy->iface_combinations = combinations; wiphy->n_iface_combinations =1 ;return 0 ; + +err_free_all_radios: + i = ah->num_radio; + +err_free_radios: +while (i--) +ath12k_mac_cleanup_iface_comb (radio[i].iface_combinations); + +kfree (radio); + +err_free_combinations: +kfree (combinations); + +return ret; }static const u8 ath12k_if_types_ext_capa[] = {
Signature · 1 line
2.39.5
PATCH 7/9 wifi: ath12k: fix ath12k_qmi_alloc_chunk() to handle too large allocations
In reply to Kalle ValoFrom: Aditya Kumar Singh <[email protected]>
If the requested memory chunk is too large, an error message is logged, but the request continues to be processed. However, no actual memory is allocated to the firmware from this request. Instead, the firmware sends another request with smaller chunks, where memory will be allocated accordingly. Therefore, it is pointless to proceed with parsing the request if at least one of the requests cannot be fulfilled.
Hence, return -EAGAIN immediately and proceed to process the new request.
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
--- drivers/net/wireless/ath/ath12k/qmi.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
drivers/net/wireless/ath/ath12k/qmi.c +9 -1
@@ -2497,7 +2497,7 @@ static int ath12k_qmi_alloc_chunk(struct ath12k_base *ab, chunk->size, chunk->type);ath12k_qmi_free_target_mem_chunk (ab); -return 0 ; +return -EAGAIN ; }ath12k_warn (ab,"memory allocation failure for %u size: %d\n" , chunk->type, chunk->size);
@@ -2600,6 +2600,14 @@ static int ath12k_qmi_alloc_target_mem_chunk(struct ath12k_base *ab)mutex_unlock (&ag->mutex); +/* The firmware will attempt to request memory in smaller chunks +* on the next try. However, the current caller should be notified +* that this instance of request parsing was successful. +* Therefore, return 0 only. +*/ +if (ret == -EAGAIN ) + ret =0 ; +return ret; }
Signature · 1 line
2.39.5
PATCH 8/9 wifi: ath12k: fix ar->supports_6ghz usage during hw register
In reply to Kalle ValoFrom: Aditya Kumar Singh <[email protected]>
In the ath12k_mac_hw_register() function's context, ar is an iterator variable, and there is no assurance that the last ar will be the one with 6 GHz enabled. Therefore, checking directly ar->supports_6ghz outside the loop is not appropriate.
Additionally, 6 GHz lacks HT capabilities. To obtain the super set of HT capabilities across all grouped radios, 6 GHz should be excluded.
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
--- drivers/net/wireless/ath/ath12k/mac.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/net/wireless/ath/ath12k/mac.c +6 -3
@@ -10723,7 +10723,10 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah)if (ret) goto err_cleanup_unregister; - ht_cap &= ht_cap_info; +/* 6 GHz does not support HT Cap, hence do not consider it */ +if (!ar->supports_6ghz) + 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
@@ -10787,7 +10790,7 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah)ieee80211_hw_set (hw,SUPPORTS_TX_FRAG );ieee80211_hw_set (hw,REPORTS_LOW_ACK ); -if ((ht_cap &WMI_HT_CAP_ENABLED ) || ar->supports_6ghz) { +if ((ht_cap &WMI_HT_CAP_ENABLED ) || is_6ghz) {ieee80211_hw_set (hw,AMPDU_AGGREGATION );ieee80211_hw_set (hw,TX_AMPDU_SETUP_IN_HW );ieee80211_hw_set (hw,SUPPORTS_REORDERING_BUFFER );
@@ -10803,7 +10806,7 @@ static int ath12k_mac_hw_register(struct ath12k_hw *ah)* handle it when the ht capability different for each band. */ if (ht_cap &WMI_HT_CAP_DYNAMIC_SMPS || - (ar->supports_6ghz && ab->hw_params->supports_dynamic_smps_6ghz)) + (is_6ghz && ab->hw_params->supports_dynamic_smps_6ghz)) wiphy->features |=NL80211_FEATURE_DYNAMIC_SMPS ; wiphy->max_scan_ssids =WLAN_SCAN_PARAMS_MAX_SSID ;
Signature · 1 line
2.39.5
PATCH 9/9 wifi: ath12k: pass link ID during MLO while delivering skb
In reply to Kalle ValoFrom: Aditya Kumar Singh <[email protected]>
mac80211 expects link_id in some scenarios or else the packet might get dropped. Hence, add link_id information before delivering the skb.
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
--- drivers/net/wireless/ath/ath12k/dp_mon.c | 8 +++++++- drivers/net/wireless/ath/ath12k/dp_rx.c | 5 +++++ drivers/net/wireless/ath/ath12k/peer.c | 2 ++ drivers/net/wireless/ath/ath12k/peer.h | 3 +++ 4 files changed, 17 insertions(+), 1 deletion(-)
drivers/net/wireless/ath/ath12k/dp_mon.c +7 -1
@@ -1093,8 +1093,14 @@ static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k *ar, struct napi_struct decap =ath12k_dp_rx_h_decap_type (ar->ab, rxcb->rx_desc);spin_lock_bh (&ar->ab->base_lock); peer =ath12k_dp_rx_h_find_peer (ar->ab, msdu); -if (peer && peer->sta) +if (peer && peer->sta) { pubsta = peer->sta; +if (pubsta->valid_links) { + status->link_valid =1 ; + status->link_id = peer->link_id; + } + } +spin_unlock_bh (&ar->ab->base_lock); ath12k_dbg(ar->ab, ATH12K_DBG_DATA,
drivers/net/wireless/ath/ath12k/dp_rx.c +5 -0
@@ -2474,6 +2474,11 @@ static void ath12k_dp_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *nap pubsta = peer ? peer->sta :NULL ; +if (pubsta && pubsta->valid_links) { + status->link_valid =1 ; + status->link_id = peer->link_id; + } +spin_unlock_bh (&ab->base_lock); ath12k_dbg(ab, ATH12K_DBG_DATA,
drivers/net/wireless/ath/ath12k/peer.c +2 -0
@@ -388,6 +388,8 @@ int ath12k_peer_create(struct ath12k *ar, struct ath12k_link_vif *arvif, arsta =wiphy_dereference (ath12k_ar_to_hw (ar)->wiphy, ahsta->link[link_id]); + peer->link_id = arsta->link_id; +/* Fill ML info into created peer */ if (sta->mlo) { ml_peer_id = ahsta->ml_peer_id;
drivers/net/wireless/ath/ath12k/peer.h +3 -0
@@ -59,6 +59,9 @@ struct ath12k_peer {/* To ensure only certain work related to dp is done once */ bool primary_link; + +/* for reference to ath12k_link_sta */ +u8 link_id; };struct ath12k_ml_peer {
Signature · 1 line
2.39.5
Quoted 7 lines · Kalle Valo
From: Kalle Valo <[email protected]>
Getting MLO to work with QCN9274 is getting close, this should be the second to last patchset. Small patches this time. Minor changes to data path to support MLO, some interface combination rework and few fixes.
Please review.
I forgot to mention that this (naturally) depends on part 7:
https://patchwork.kernel.org/project/linux-wireless/cover/[email protected]/
Signature · 3 lines
https://patchwork.kernel.org/project/linux-wireless/list/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
Jeff Johnson
AppliedQuoted 6 lines · Kalle Valo
Getting MLO to work with QCN9274 is getting close, this should be the second to last patchset. Small patches this time. Minor changes to data path to support MLO, some interface combination rework and few fixes.
Please review.
Quoted 7 lines
Aditya Kumar Singh (3):
wifi: ath12k: fixath12k_qmi_alloc_chunk()to handle too large
allocations
wifi: ath12k: fixar->supports_6ghzusage during hw register
wifi: ath12k: pass link ID during MLO while delivering skb[...]
Applied, thanks!
[1/9] wifi: ath12k: move to HW link id based reveive handling
commit: e536c8690cf423f47e5e2f491134d3511edbbaf2
[2/9] wifi: ath12k: add partner device buffer support in receive data path
commit: fc1e7e004b1808da38c862d57fccfad631a1445a
[3/9] wifi: ath12k: add helper function to init partner cmem configuration
commit: 5a8abdf88deac066c4c4a224e45b80088ea94ff0
[4/9] wifi: ath12k: introduce interface combination cleanup helper
commit: 2e4b8a49191ea9df8430cb6e8af7429eadd54709
[5/9] wifi: ath12k: Refactor radio frequency information
commit: 4b861d256235c0c94d1a09e4dd888accc0eec5e9
[6/9] wifi: ath12k: advertise multi device interface combination
commit: 03156d08d9ae768bffc0eba5eeeede868f52331f
[7/9] wifi: ath12k: fix ath12k_qmi_alloc_chunk() to handle too large allocations
commit: c14725f359ef982923f3bc7e222c7687ffe4e496
[8/9] wifi: ath12k: fix ar->supports_6ghz usage during hw register
commit: 95740fb0d3dbe276bf414c44cea0c35948407800
[9/9] wifi: ath12k: pass link ID during MLO while delivering skb
commit: 1d015d783da57b002fda75b29aa3b886724c0129Best regards,
Signature · 1 line
Jeff Johnson <[email protected]>