From 2646db08267e807f59323d5542cc4caa5681540d Mon Sep 17 00:00:00 2001 From: John Crispin Date: Mon, 28 Aug 2023 12:16:57 +0200 Subject: [PATCH] ipq807x: update NSS patch Signed-off-by: John Crispin --- .../patches/pending/290-deadlock_fix.patch | 124 ++++++++++++ .../patches/pending/290-mcs_nss_cap.patch | 176 ++++++++++++++++++ .../patches/pending/290-mcs_nss_cap.patch | 26 +-- 3 files changed, 315 insertions(+), 11 deletions(-) create mode 100644 feeds/ipq807x_v5.4/mac80211/patches/pending/290-deadlock_fix.patch create mode 100644 feeds/ipq807x_v5.4/mac80211/patches/pending/290-mcs_nss_cap.patch diff --git a/feeds/ipq807x_v5.4/mac80211/patches/pending/290-deadlock_fix.patch b/feeds/ipq807x_v5.4/mac80211/patches/pending/290-deadlock_fix.patch new file mode 100644 index 000000000..67bf88c39 --- /dev/null +++ b/feeds/ipq807x_v5.4/mac80211/patches/pending/290-deadlock_fix.patch @@ -0,0 +1,124 @@ +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -3973,7 +3973,7 @@ static int nl80211_set_interface(struct + return err; + } + +-static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) ++static int _nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) + { + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct vif_params params; +@@ -3982,9 +3982,6 @@ static int nl80211_new_interface(struct + int err; + enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED; + +- /* to avoid failing a new interface creation due to pending removal */ +- cfg80211_destroy_ifaces(rdev); +- + memset(¶ms, 0, sizeof(params)); + + if (!info->attrs[NL80211_ATTR_IFNAME]) +@@ -4072,6 +4069,21 @@ static int nl80211_new_interface(struct + return genlmsg_reply(msg, info); + } + ++static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) ++{ ++ struct cfg80211_registered_device *rdev = info->user_ptr[0]; ++ int ret; ++ ++ /* to avoid failing a new interface creation due to pending removal */ ++ cfg80211_destroy_ifaces(rdev); ++ ++ wiphy_lock(&rdev->wiphy); ++ ret = _nl80211_new_interface(skb, info); ++ wiphy_unlock(&rdev->wiphy); ++ ++ return ret; ++} ++ + static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info) + { + struct cfg80211_registered_device *rdev = info->user_ptr[0]; +@@ -15037,6 +15049,7 @@ static int nl80211_color_change(struct s + #define NL80211_FLAG_NEED_WDEV_UP (NL80211_FLAG_NEED_WDEV |\ + NL80211_FLAG_CHECK_NETDEV_UP) + #define NL80211_FLAG_CLEAR_SKB 0x20 ++#define NL80211_FLAG_NO_WIPHY_MTX 0x40 + + static int nl80211_pre_doit(__genl_const struct genl_ops *ops, + struct sk_buff *skb, +@@ -15089,7 +15102,7 @@ static int nl80211_pre_doit(__genl_const + info->user_ptr[0] = rdev; + } + +- if (rdev) { ++ if (rdev && !(ops->internal_flags & NL80211_FLAG_NO_WIPHY_MTX)) { + wiphy_lock(&rdev->wiphy); + /* we keep the mutex locked until post_doit */ + __release(&rdev->wiphy.mtx); +@@ -15115,7 +15128,8 @@ static void nl80211_post_doit(__genl_con + } + } + +- if (info->user_ptr[0]) { ++ if (info->user_ptr[0] && ++ !(ops->internal_flags & NL80211_FLAG_NO_WIPHY_MTX)) { + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + + /* we kept the mutex locked since pre_doit */ +@@ -15286,7 +15300,9 @@ static const struct genl_small_ops nl802 + .doit = nl80211_new_interface, + .flags = GENL_UNS_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_WIPHY | +- NL80211_FLAG_NEED_RTNL, ++ NL80211_FLAG_NEED_RTNL | ++ /* we take the wiphy mutex later ourselves */ ++ NL80211_FLAG_NO_WIPHY_MTX, + }, + { + .cmd = NL80211_CMD_DEL_INTERFACE, +@@ -15581,7 +15597,9 @@ static const struct genl_small_ops nl802 + .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, + .doit = nl80211_wiphy_netns, + .flags = GENL_UNS_ADMIN_PERM, +- .internal_flags = NL80211_FLAG_NEED_WIPHY, ++ .internal_flags = NL80211_FLAG_NEED_WIPHY | ++ NL80211_FLAG_NEED_RTNL | ++ NL80211_FLAG_NO_WIPHY_MTX, + }, + { + .cmd = NL80211_CMD_GET_SURVEY, +--- a/net/wireless/core.c ++++ b/net/wireless/core.c +@@ -334,11 +334,17 @@ void cfg80211_destroy_ifaces(struct cfg8 + struct wireless_dev *wdev, *tmp; + + ASSERT_RTNL(); +- lockdep_assert_wiphy(&rdev->wiphy); + + list_for_each_entry_safe(wdev, tmp, &rdev->wiphy.wdev_list, list) { +- if (wdev->nl_owner_dead) ++ if (wdev->nl_owner_dead) { ++ if (wdev->netdev) ++ dev_close(wdev->netdev); ++ ++ wiphy_lock(&rdev->wiphy); ++ cfg80211_leave(rdev, wdev); + rdev_del_virtual_intf(rdev, wdev); ++ wiphy_unlock(&rdev->wiphy); ++ } + } + } + +@@ -350,9 +356,7 @@ static void cfg80211_destroy_iface_wk(st + destroy_work); + + rtnl_lock(); +- wiphy_lock(&rdev->wiphy); + cfg80211_destroy_ifaces(rdev); +- wiphy_unlock(&rdev->wiphy); + rtnl_unlock(); + } + diff --git a/feeds/ipq807x_v5.4/mac80211/patches/pending/290-mcs_nss_cap.patch b/feeds/ipq807x_v5.4/mac80211/patches/pending/290-mcs_nss_cap.patch new file mode 100644 index 000000000..41e1593d8 --- /dev/null +++ b/feeds/ipq807x_v5.4/mac80211/patches/pending/290-mcs_nss_cap.patch @@ -0,0 +1,176 @@ +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -5602,12 +5602,13 @@ static void ath11k_set_vht_txbf_cap(stru + } + + static struct ieee80211_sta_vht_cap +-ath11k_create_vht_cap(struct ath11k *ar, u32 rate_cap_tx_chainmask, +- u32 rate_cap_rx_chainmask) ++ath11k_create_vht_cap(struct ath11k *ar, struct ath11k_pdev_cap *cap) + { + struct ieee80211_sta_vht_cap vht_cap = {0}; + u16 txmcs_map, rxmcs_map; + int i; ++ u32 rate_cap_tx_chainmask; ++ u32 rate_cap_rx_chainmask; + + vht_cap.vht_supported = 1; + vht_cap.cap = ar->pdev->cap.vht_cap; +@@ -5616,16 +5617,34 @@ ath11k_create_vht_cap(struct ath11k *ar, + + rxmcs_map = 0; + txmcs_map = 0; +- for (i = 0; i < 8; i++) { +- if (i < ar->num_tx_chains && rate_cap_tx_chainmask & BIT(i)) +- txmcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2); +- else +- txmcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2); +- +- if (i < ar->num_rx_chains && rate_cap_rx_chainmask & BIT(i)) +- rxmcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2); +- else +- rxmcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2); ++ ++ rate_cap_tx_chainmask = ar->cfg_tx_chainmask >> cap->tx_chain_mask_shift; ++ rate_cap_rx_chainmask = ar->cfg_rx_chainmask >> cap->rx_chain_mask_shift; ++ if (cap->tx_chain_mask_shift == 4) { ++ for (i = 0; i < 8; i++) { ++ if (i < ar->num_tx_chains && ar->cfg_tx_chainmask & BIT(7 - i)) ++ txmcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2); ++ else ++ txmcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2); ++ ++ if (i < ar->num_rx_chains && ar->cfg_rx_chainmask & BIT(7 - i)) ++ rxmcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2); ++ else ++ rxmcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2); ++ } ++ } else { ++ for (i = 0; i < 8; i++) { ++ if (i < ar->num_tx_chains && rate_cap_tx_chainmask & BIT(i)) ++ txmcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2); ++ else ++ txmcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2); ++ ++ if (i < ar->num_rx_chains && rate_cap_rx_chainmask & BIT(i)) ++ rxmcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2); ++ else ++ rxmcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2); ++ } ++ + } + + if (rate_cap_tx_chainmask <= 1) +@@ -5634,6 +5653,9 @@ ath11k_create_vht_cap(struct ath11k *ar, + vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(rxmcs_map); + vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(txmcs_map); + ++ if (ieee80211_hw_check(ar->hw, SUPPORTS_VHT_EXT_NSS_BW)) ++ vht_cap.vht_mcs.tx_highest |= cpu_to_le16(IEEE80211_VHT_EXT_NSS_BW_CAPABLE); ++ + /* Check if the HW supports 1:1 NSS ratio and reset + * EXT NSS BW Support field to 0 to indicate 1:1 ratio + */ +@@ -5663,8 +5685,7 @@ static void ath11k_mac_setup_ht_vht_cap( + band->ht_cap = ath11k_create_ht_cap(ar, ht_cap, + rate_cap_rx_chainmask); + +- band->vht_cap = ath11k_create_vht_cap(ar, rate_cap_tx_chainmask, +- rate_cap_rx_chainmask); ++ band->vht_cap = ath11k_create_vht_cap(ar, cap); + } + + if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP && !ar->supports_6ghz) { +@@ -5674,8 +5695,7 @@ static void ath11k_mac_setup_ht_vht_cap( + *ht_cap_info = ht_cap; + band->ht_cap = ath11k_create_ht_cap(ar, ht_cap, + rate_cap_rx_chainmask); +- band->vht_cap = ath11k_create_vht_cap(ar, rate_cap_tx_chainmask, +- rate_cap_rx_chainmask); ++ band->vht_cap = ath11k_create_vht_cap(ar, cap); + } + } + +@@ -5827,30 +5847,58 @@ static void ath11k_mac_set_hemcsmap(stru + u8 maxtxnss_160 = ath11k_get_nss_160MHz(ar, ar->num_tx_chains); + u8 maxrxnss_160 = ath11k_get_nss_160MHz(ar, ar->num_rx_chains); + +- for (i = 0; i < 8; i++) { +- if (i < ar->num_tx_chains && +- (ar->cfg_tx_chainmask >> cap->tx_chain_mask_shift) & BIT(i)) +- txmcs_map |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2); +- else +- txmcs_map |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2); +- +- if (i < ar->num_rx_chains && +- (ar->cfg_rx_chainmask >> cap->tx_chain_mask_shift) & BIT(i)) +- rxmcs_map |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2); +- else +- rxmcs_map |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2); +- +- if (i < maxtxnss_160 && +- (ar->cfg_tx_chainmask >> cap->tx_chain_mask_shift) & BIT(i)) +- txmcs_map_160 |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2); +- else +- txmcs_map_160 |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2); +- +- if (i < maxrxnss_160 && +- (ar->cfg_tx_chainmask >> cap->tx_chain_mask_shift) & BIT(i)) +- rxmcs_map_160 |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2); +- else +- rxmcs_map_160 |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2); ++ if (cap->tx_chain_mask_shift == 4) { ++ for (i = 0; i < 8; i++) { ++ if (i < ar->num_tx_chains && ++ (ar->cfg_tx_chainmask & BIT(7 - i))) ++ txmcs_map |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2); ++ else ++ txmcs_map |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2); ++ ++ if (i < ar->num_rx_chains && ++ (ar->cfg_rx_chainmask & BIT(7 - i))) ++ rxmcs_map |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2); ++ else ++ rxmcs_map |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2); ++ ++ if (i < maxtxnss_160 && ++ (ar->cfg_tx_chainmask & BIT(7 - i))) ++ txmcs_map_160 |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2); ++ else ++ txmcs_map_160 |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2); ++ ++ if (i < maxrxnss_160 && ++ (ar->cfg_rx_chainmask & BIT(7 - i))) ++ rxmcs_map_160 |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2); ++ else ++ rxmcs_map_160 |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2); ++ } ++ } else { ++ for (i = 0; i < 8; i++) { ++ if (i < ar->num_tx_chains && ++ (ar->cfg_tx_chainmask >> cap->tx_chain_mask_shift) & BIT(i)) ++ txmcs_map |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2); ++ else ++ txmcs_map |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2); ++ ++ if (i < ar->num_rx_chains && ++ (ar->cfg_rx_chainmask >> cap->tx_chain_mask_shift) & BIT(i)) ++ rxmcs_map |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2); ++ else ++ rxmcs_map |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2); ++ ++ if (i < maxtxnss_160 && ++ (ar->cfg_tx_chainmask >> cap->tx_chain_mask_shift) & BIT(i)) ++ txmcs_map_160 |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2); ++ else ++ txmcs_map_160 |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2); ++ ++ if (i < maxrxnss_160 && ++ (ar->cfg_tx_chainmask >> cap->tx_chain_mask_shift) & BIT(i)) ++ rxmcs_map_160 |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2); ++ else ++ rxmcs_map_160 |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2); ++ } + } + he_cap->he_mcs_nss_supp.rx_mcs_80 = + cpu_to_le16(rxmcs_map & 0xffff); diff --git a/feeds/wifi-ax/mac80211/patches/pending/290-mcs_nss_cap.patch b/feeds/wifi-ax/mac80211/patches/pending/290-mcs_nss_cap.patch index 8b8a37437..41e1593d8 100644 --- a/feeds/wifi-ax/mac80211/patches/pending/290-mcs_nss_cap.patch +++ b/feeds/wifi-ax/mac80211/patches/pending/290-mcs_nss_cap.patch @@ -1,7 +1,5 @@ -Index: backports-20210222_001-4.4.60-b157d2276/drivers/net/wireless/ath/ath11k/mac.c -=================================================================== ---- backports-20210222_001-4.4.60-b157d2276.orig/drivers/net/wireless/ath/ath11k/mac.c -+++ backports-20210222_001-4.4.60-b157d2276/drivers/net/wireless/ath/ath11k/mac.c +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -5602,12 +5602,13 @@ static void ath11k_set_vht_txbf_cap(stru } @@ -63,7 +61,17 @@ Index: backports-20210222_001-4.4.60-b157d2276/drivers/net/wireless/ath/ath11k/m } if (rate_cap_tx_chainmask <= 1) -@@ -5663,8 +5682,7 @@ static void ath11k_mac_setup_ht_vht_cap( +@@ -5634,6 +5653,9 @@ ath11k_create_vht_cap(struct ath11k *ar, + vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(rxmcs_map); + vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(txmcs_map); + ++ if (ieee80211_hw_check(ar->hw, SUPPORTS_VHT_EXT_NSS_BW)) ++ vht_cap.vht_mcs.tx_highest |= cpu_to_le16(IEEE80211_VHT_EXT_NSS_BW_CAPABLE); ++ + /* Check if the HW supports 1:1 NSS ratio and reset + * EXT NSS BW Support field to 0 to indicate 1:1 ratio + */ +@@ -5663,8 +5685,7 @@ static void ath11k_mac_setup_ht_vht_cap( band->ht_cap = ath11k_create_ht_cap(ar, ht_cap, rate_cap_rx_chainmask); @@ -73,21 +81,17 @@ Index: backports-20210222_001-4.4.60-b157d2276/drivers/net/wireless/ath/ath11k/m } if (cap->supported_bands & WMI_HOST_WLAN_5G_CAP && !ar->supports_6ghz) { -@@ -5674,8 +5692,11 @@ static void ath11k_mac_setup_ht_vht_cap( +@@ -5674,8 +5695,7 @@ static void ath11k_mac_setup_ht_vht_cap( *ht_cap_info = ht_cap; band->ht_cap = ath11k_create_ht_cap(ar, ht_cap, rate_cap_rx_chainmask); - band->vht_cap = ath11k_create_vht_cap(ar, rate_cap_tx_chainmask, - rate_cap_rx_chainmask); + band->vht_cap = ath11k_create_vht_cap(ar, cap); -+ if (ar->hw->wiphy->bands[NL80211_BAND_5GHZ]) { -+ ar->hw->wiphy->bands[NL80211_BAND_5GHZ]->vht_cap.vht_mcs.rx_mcs_map = band->vht_cap.vht_mcs.rx_mcs_map; -+ ar->hw->wiphy->bands[NL80211_BAND_5GHZ]->vht_cap.vht_mcs.tx_mcs_map = band->vht_cap.vht_mcs.tx_mcs_map; -+ } } } -@@ -5827,30 +5848,58 @@ static void ath11k_mac_set_hemcsmap(stru +@@ -5827,30 +5847,58 @@ static void ath11k_mac_set_hemcsmap(stru u8 maxtxnss_160 = ath11k_get_nss_160MHz(ar, ar->num_tx_chains); u8 maxrxnss_160 = ath11k_get_nss_160MHz(ar, ar->num_rx_chains);