mirror of
https://github.com/torvalds/linux.git
synced 2026-05-24 23:22:31 +02:00
wifi: ath12k: Fix the assignment of logical link index
Per-link logical index is assigned from the global counter, ahsta->num_peer. This logical index is sent to firmware during peer association. If there is a failure in creating a link station, ath12k_mac_free_unassign_link_sta() clears the link, but does not decrement the logical link index. This will result in a higher logical link index for the next link station created. Also, if there is a leak in logical link index as we assign the incremented num_peer, then the index can exceed the maximum valid value of 15. As an example, let's say we have a 2 GHz + 5 GHz + 6 GHz MLO setup. So the logical link indices that they have are 0, 1 and 2, respectively. If the 5 GHz link is removed, logical link index 1 becomes available, and num_peer is not reduced to 2 and still remains at 3. If a new 5 GHz link is added later, it gets the index 3, instead of reusing link index 1. Also, num_peer is increased to 4, though only 3 links are present. To resolve these, create a bitmap, free_logical_link_idx, that tracks the available logical link indices. When a link station is created, select the first free logical index and when a link station is removed, mark its logical link index as available by setting the bit. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.6-01181-QCAHKSWPL_SILICONZ-1 Signed-off-by: Manish Dharanenthiran <manish.dharanenthiran@oss.qualcomm.com> Signed-off-by: Roopni Devanathan <roopni.devanathan@oss.qualcomm.com> Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com> Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com> Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com> Link: https://patch.msgid.link/20260226041911.2434999-1-roopni.devanathan@oss.qualcomm.com Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
This commit is contained in:
parent
1635ecc61a
commit
aecb569d7f
|
|
@ -523,7 +523,7 @@ struct ath12k_sta {
|
|||
u16 links_map;
|
||||
u8 assoc_link_id;
|
||||
u16 ml_peer_id;
|
||||
u8 num_peer;
|
||||
u16 free_logical_link_idx_map;
|
||||
|
||||
enum ieee80211_sta_state state;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -6786,6 +6786,8 @@ static void ath12k_mac_free_unassign_link_sta(struct ath12k_hw *ah,
|
|||
return;
|
||||
|
||||
ahsta->links_map &= ~BIT(link_id);
|
||||
ahsta->free_logical_link_idx_map |= BIT(arsta->link_idx);
|
||||
|
||||
rcu_assign_pointer(ahsta->link[link_id], NULL);
|
||||
synchronize_rcu();
|
||||
|
||||
|
|
@ -7104,6 +7106,7 @@ static int ath12k_mac_assign_link_sta(struct ath12k_hw *ah,
|
|||
struct ieee80211_sta *sta = ath12k_ahsta_to_sta(ahsta);
|
||||
struct ieee80211_link_sta *link_sta;
|
||||
struct ath12k_link_vif *arvif;
|
||||
int link_idx;
|
||||
|
||||
lockdep_assert_wiphy(ah->hw->wiphy);
|
||||
|
||||
|
|
@ -7122,8 +7125,16 @@ static int ath12k_mac_assign_link_sta(struct ath12k_hw *ah,
|
|||
|
||||
ether_addr_copy(arsta->addr, link_sta->addr);
|
||||
|
||||
/* logical index of the link sta in order of creation */
|
||||
arsta->link_idx = ahsta->num_peer++;
|
||||
if (!ahsta->free_logical_link_idx_map)
|
||||
return -ENOSPC;
|
||||
|
||||
/*
|
||||
* Allocate a logical link index by selecting the first available bit
|
||||
* from the free logical index map
|
||||
*/
|
||||
link_idx = __ffs(ahsta->free_logical_link_idx_map);
|
||||
ahsta->free_logical_link_idx_map &= ~BIT(link_idx);
|
||||
arsta->link_idx = link_idx;
|
||||
|
||||
arsta->link_id = link_id;
|
||||
ahsta->links_map |= BIT(arsta->link_id);
|
||||
|
|
@ -7632,6 +7643,7 @@ int ath12k_mac_op_sta_state(struct ieee80211_hw *hw,
|
|||
if (old_state == IEEE80211_STA_NOTEXIST &&
|
||||
new_state == IEEE80211_STA_NONE) {
|
||||
memset(ahsta, 0, sizeof(*ahsta));
|
||||
ahsta->free_logical_link_idx_map = U16_MAX;
|
||||
|
||||
arsta = &ahsta->deflink;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user