From 4d78e032fee5d532e189cdb2c3c76112094e9751 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 30 Mar 2023 11:00:00 +0200 Subject: [PATCH 01/37] wifi: mac80211: drop bogus static keywords in A-MSDU rx These were unintentional copy&paste mistakes. Cc: stable@vger.kernel.org Fixes: 986e43b19ae9 ("wifi: mac80211: fix receiving A-MSDU frames on mesh interfaces") Signed-off-by: Felix Fietkau Link: https://lore.kernel.org/r/20230330090001.60750-1-nbd@nbd.name Signed-off-by: Johannes Berg --- net/mac80211/rx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index e8de500eb9f3..9353616b528f 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2896,7 +2896,7 @@ __ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx, u8 data_offset) struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; __le16 fc = hdr->frame_control; struct sk_buff_head frame_list; - static ieee80211_rx_result res; + ieee80211_rx_result res; struct ethhdr ethhdr; const u8 *check_da = ethhdr.h_dest, *check_sa = ethhdr.h_source; @@ -3037,7 +3037,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx) struct net_device *dev = sdata->dev; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; __le16 fc = hdr->frame_control; - static ieee80211_rx_result res; + ieee80211_rx_result res; bool port_control; int err; From a16fc38315f2c69c520ee769976ecb9c706b8560 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 30 Mar 2023 11:00:01 +0200 Subject: [PATCH 02/37] wifi: mac80211: fix potential null pointer dereference rx->sta->amsdu_mesh_control is being passed to ieee80211_amsdu_to_8023s without checking rx->sta. Since it doesn't make sense to accept A-MSDU packets without a sta, simply add a check earlier. Fixes: 6e4c0d0460bd ("wifi: mac80211: add a workaround for receiving non-standard mesh A-MSDU") Signed-off-by: Felix Fietkau Link: https://lore.kernel.org/r/20230330090001.60750-2-nbd@nbd.name Signed-off-by: Johannes Berg --- net/mac80211/rx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 9353616b528f..78351895c3c6 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2930,7 +2930,7 @@ __ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx, u8 data_offset) data_offset, true)) return RX_DROP_UNUSABLE; - if (rx->sta && rx->sta->amsdu_mesh_control < 0) { + if (rx->sta->amsdu_mesh_control < 0) { bool valid_std = ieee80211_is_valid_amsdu(skb, true); bool valid_nonstd = ieee80211_is_valid_amsdu(skb, false); @@ -3006,7 +3006,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) } } - if (is_multicast_ether_addr(hdr->addr1)) + if (is_multicast_ether_addr(hdr->addr1) || !rx->sta) return RX_DROP_UNUSABLE; if (rx->key) { From dd01579e5ed922dcfcb8fec53fa03b81c7649a04 Mon Sep 17 00:00:00 2001 From: Ryder Lee Date: Tue, 28 Mar 2023 01:07:41 +0800 Subject: [PATCH 03/37] wifi: mac80211: fix the size calculation of ieee80211_ie_len_eht_cap() Here should return the size of ieee80211_eht_cap_elem_fixed, so fix it. Fixes: 820acc810fb6 ("mac80211: Add EHT capabilities to association/probe request") Signed-off-by: Ryder Lee Link: https://lore.kernel.org/r/06c13635fc03bcff58a647b8e03e9f01a74294bd.1679935259.git.ryder.lee@mediatek.com Signed-off-by: Johannes Berg --- net/mac80211/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 3aceb3b731bf..8c397650b96f 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -4906,7 +4906,7 @@ u8 ieee80211_ie_len_eht_cap(struct ieee80211_sub_if_data *sdata, u8 iftype) &eht_cap->eht_cap_elem, is_ap); return 2 + 1 + - sizeof(he_cap->he_cap_elem) + n + + sizeof(eht_cap->eht_cap_elem) + n + ieee80211_eht_ppe_size(eht_cap->eht_ppe_thres[0], eht_cap->eht_cap_elem.phy_cap_info); return 0; From e26c0946a5c1aa4d27f8dfe78f2a72b4550df91f Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 26 Mar 2023 17:17:09 +0200 Subject: [PATCH 04/37] wifi: mac80211: fix receiving mesh packets in forwarding=0 networks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When forwarding is set to 0, frames are typically sent with ttl=1. Move the ttl decrement check below the check for local receive in order to fix packet drops. Reported-by: Thomas Hühn Reported-by: Nick Hainke Fixes: 986e43b19ae9 ("wifi: mac80211: fix receiving A-MSDU frames on mesh interfaces") Signed-off-by: Felix Fietkau Link: https://lore.kernel.org/r/20230326151709.17743-1-nbd@nbd.name Signed-off-by: Johannes Berg --- net/mac80211/rx.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 78351895c3c6..7bd5aa2d5a95 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2769,14 +2769,6 @@ ieee80211_rx_mesh_data(struct ieee80211_sub_if_data *sdata, struct sta_info *sta if (sdata->crypto_tx_tailroom_needed_cnt) tailroom = IEEE80211_ENCRYPT_TAILROOM; - if (!--mesh_hdr->ttl) { - if (multicast) - goto rx_accept; - - IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl); - return RX_DROP_MONITOR; - } - if (mesh_hdr->flags & MESH_FLAGS_AE) { struct mesh_path *mppath; char *proxied_addr; @@ -2807,6 +2799,14 @@ ieee80211_rx_mesh_data(struct ieee80211_sub_if_data *sdata, struct sta_info *sta if (ether_addr_equal(sdata->vif.addr, eth->h_dest)) goto rx_accept; + if (!--mesh_hdr->ttl) { + if (multicast) + goto rx_accept; + + IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl); + return RX_DROP_MONITOR; + } + if (!ifmsh->mshcfg.dot11MeshForwarding) { if (is_multicast_ether_addr(eth->h_dest)) goto rx_accept; From 8f0149a8ac59c12cd47271ac625c27dac5621d3a Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 24 Mar 2023 13:09:22 +0100 Subject: [PATCH 05/37] wifi: mac80211: fix mesh forwarding Linearize packets (needed for forwarding A-MSDU subframes). Fixes: 986e43b19ae9 ("wifi: mac80211: fix receiving A-MSDU frames on mesh interfaces") Signed-off-by: Felix Fietkau Link: https://lore.kernel.org/r/20230324120924.38412-1-nbd@nbd.name Signed-off-by: Johannes Berg --- net/mac80211/rx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 7bd5aa2d5a95..10efa429e946 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2833,6 +2833,9 @@ ieee80211_rx_mesh_data(struct ieee80211_sub_if_data *sdata, struct sta_info *sta if (skb_cow_head(fwd_skb, hdrlen - sizeof(struct ethhdr))) return RX_DROP_UNUSABLE; + + if (skb_linearize(fwd_skb)) + return RX_DROP_UNUSABLE; } fwd_hdr = skb_push(fwd_skb, hdrlen - sizeof(struct ethhdr)); From 899c2c11810cfe38cb01c847d0df98e181ea5728 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 24 Mar 2023 13:09:23 +0100 Subject: [PATCH 06/37] wifi: mac80211: fix flow dissection for forwarded packets Adjust the network header to point at the correct payload offset Fixes: 986e43b19ae9 ("wifi: mac80211: fix receiving A-MSDU frames on mesh interfaces") Signed-off-by: Felix Fietkau Link: https://lore.kernel.org/r/20230324120924.38412-2-nbd@nbd.name Signed-off-by: Johannes Berg --- net/mac80211/rx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 10efa429e946..af57616d2f1d 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2850,7 +2850,7 @@ ieee80211_rx_mesh_data(struct ieee80211_sub_if_data *sdata, struct sta_info *sta hdrlen += ETH_ALEN; else fwd_skb->protocol = htons(fwd_skb->len - hdrlen); - skb_set_network_header(fwd_skb, hdrlen); + skb_set_network_header(fwd_skb, hdrlen + 2); info = IEEE80211_SKB_CB(fwd_skb); memset(info, 0, sizeof(*info)); From 12b220a6171faf10638ab683a975cadcf1a352d6 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 24 Mar 2023 13:09:24 +0100 Subject: [PATCH 07/37] wifi: mac80211: fix invalid drv_sta_pre_rcu_remove calls for non-uploaded sta Avoid potential data corruption issues caused by uninitialized driver private data structures. Reported-by: Brian Coverstone Fixes: 6a9d1b91f34d ("mac80211: add pre-RCU-sync sta removal driver operation") Signed-off-by: Felix Fietkau Link: https://lore.kernel.org/r/20230324120924.38412-3-nbd@nbd.name Signed-off-by: Johannes Berg --- net/mac80211/sta_info.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 7d68dbc872d7..941bda9141fa 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -1264,7 +1264,8 @@ static int __must_check __sta_info_destroy_part1(struct sta_info *sta) list_del_rcu(&sta->list); sta->removed = true; - drv_sta_pre_rcu_remove(local, sta->sdata, sta); + if (sta->uploaded) + drv_sta_pre_rcu_remove(local, sta->sdata, sta); if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN && rcu_access_pointer(sdata->u.vlan.sta) == sta) From df1875c4f345092716f1529d6e8c43e7fc7f250a Mon Sep 17 00:00:00 2001 From: Ryder Lee Date: Tue, 28 Mar 2023 01:07:42 +0800 Subject: [PATCH 08/37] wifi: mac80211: enable EHT mesh support Similar to AP beacon, this enables the basic mesh EHT mode, including EHT operation IE and the fixed field of EHT operation information IE. As for the optional part (i.e. preamble puncturing bitmap) will be added in future patch. Tested-by: Lian Chen Signed-off-by: Ryder Lee Link: https://lore.kernel.org/r/1e0ddb9001312451c3e99c4eed2072caf8075f61.1679935259.git.ryder.lee@mediatek.com Signed-off-by: Johannes Berg --- net/mac80211/ieee80211_i.h | 2 ++ net/mac80211/mesh.c | 73 ++++++++++++++++++++++++++++++++++++-- net/mac80211/mesh.h | 4 +++ net/mac80211/mesh_plink.c | 16 +++++++-- net/mac80211/util.c | 71 ++++++++++++++++++++++++++++++++++++ 5 files changed, 162 insertions(+), 4 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 8c058351e629..9b7e184430b8 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -2479,6 +2479,8 @@ void ieee80211_ie_build_he_6ghz_cap(struct ieee80211_sub_if_data *sdata, enum ieee80211_smps_mode smps_mode, struct sk_buff *skb); u8 *ieee80211_ie_build_he_oper(u8 *pos, struct cfg80211_chan_def *chandef); +u8 *ieee80211_ie_build_eht_oper(u8 *pos, struct cfg80211_chan_def *chandef, + const struct ieee80211_sta_eht_cap *eht_cap); int ieee80211_parse_bitrates(enum nl80211_chan_width width, const struct ieee80211_supported_band *sband, const u8 *srates, int srates_len, u32 *rates); diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 6b94cf2a4046..f72333201903 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -105,7 +105,7 @@ bool mesh_matches_local(struct ieee80211_sub_if_data *sdata, ieee80211_chandef_vht_oper(&sdata->local->hw, vht_cap_info, ie->vht_operation, ie->ht_operation, &sta_chan_def); - ieee80211_chandef_he_6ghz_oper(sdata, ie->he_operation, NULL, + ieee80211_chandef_he_6ghz_oper(sdata, ie->he_operation, ie->eht_operation, &sta_chan_def); if (!cfg80211_chandef_compatible(&sdata->vif.bss_conf.chandef, @@ -639,6 +639,65 @@ int mesh_add_he_6ghz_cap_ie(struct ieee80211_sub_if_data *sdata, return 0; } +int mesh_add_eht_cap_ie(struct ieee80211_sub_if_data *sdata, + struct sk_buff *skb, u8 ie_len) +{ + const struct ieee80211_sta_he_cap *he_cap; + const struct ieee80211_sta_eht_cap *eht_cap; + struct ieee80211_supported_band *sband; + u8 *pos; + + sband = ieee80211_get_sband(sdata); + if (!sband) + return -EINVAL; + + he_cap = ieee80211_get_he_iftype_cap(sband, NL80211_IFTYPE_MESH_POINT); + eht_cap = ieee80211_get_eht_iftype_cap(sband, NL80211_IFTYPE_MESH_POINT); + if (!he_cap || !eht_cap || + sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT || + sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_5 || + sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_10) + return 0; + + if (skb_tailroom(skb) < ie_len) + return -ENOMEM; + + pos = skb_put(skb, ie_len); + ieee80211_ie_build_eht_cap(pos, he_cap, eht_cap, pos + ie_len, false); + + return 0; +} + +int mesh_add_eht_oper_ie(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) +{ + const struct ieee80211_sta_eht_cap *eht_cap; + struct ieee80211_supported_band *sband; + u32 len; + u8 *pos; + + sband = ieee80211_get_sband(sdata); + if (!sband) + return -EINVAL; + + eht_cap = ieee80211_get_eht_iftype_cap(sband, NL80211_IFTYPE_MESH_POINT); + if (!eht_cap || + sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT || + sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_5 || + sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_10) + return 0; + + len = 2 + 1 + offsetof(struct ieee80211_eht_operation, optional) + + offsetof(struct ieee80211_eht_operation_info, optional); + + if (skb_tailroom(skb) < len) + return -ENOMEM; + + pos = skb_put(skb, len); + ieee80211_ie_build_eht_oper(pos, &sdata->vif.bss_conf.chandef, eht_cap); + + return 0; +} + static void ieee80211_mesh_path_timer(struct timer_list *t) { struct ieee80211_sub_if_data *sdata = @@ -697,6 +756,9 @@ ieee80211_mesh_update_bss_params(struct ieee80211_sub_if_data *sdata, if (he_oper) sdata->vif.bss_conf.he_oper.params = __le32_to_cpu(he_oper->he_oper_params); + + sdata->vif.bss_conf.eht_support = + !!ieee80211_get_eht_iftype_cap(sband, NL80211_IFTYPE_MESH_POINT); } bool ieee80211_mesh_xmit_fast(struct ieee80211_sub_if_data *sdata, @@ -903,7 +965,7 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh) struct ieee80211_chanctx_conf *chanctx_conf; struct mesh_csa_settings *csa; enum nl80211_band band; - u8 ie_len_he_cap; + u8 ie_len_he_cap, ie_len_eht_cap; u8 *pos; struct ieee80211_sub_if_data *sdata; int hdr_len = offsetofend(struct ieee80211_mgmt, u.beacon); @@ -916,6 +978,8 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh) ie_len_he_cap = ieee80211_ie_len_he_cap(sdata, NL80211_IFTYPE_MESH_POINT); + ie_len_eht_cap = ieee80211_ie_len_eht_cap(sdata, + NL80211_IFTYPE_MESH_POINT); head_len = hdr_len + 2 + /* NULL SSID */ /* Channel Switch Announcement */ @@ -939,6 +1003,9 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh) 2 + 1 + sizeof(struct ieee80211_he_operation) + sizeof(struct ieee80211_he_6ghz_oper) + 2 + 1 + sizeof(struct ieee80211_he_6ghz_capa) + + ie_len_eht_cap + + 2 + 1 + offsetof(struct ieee80211_eht_operation, optional) + + offsetof(struct ieee80211_eht_operation_info, optional) + ifmsh->ie_len; bcn = kzalloc(sizeof(*bcn) + head_len + tail_len, GFP_KERNEL); @@ -1059,6 +1126,8 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh) mesh_add_he_cap_ie(sdata, skb, ie_len_he_cap) || mesh_add_he_oper_ie(sdata, skb) || mesh_add_he_6ghz_cap_ie(sdata, skb) || + mesh_add_eht_cap_ie(sdata, skb, ie_len_eht_cap) || + mesh_add_eht_oper_ie(sdata, skb) || mesh_add_vendor_ies(sdata, skb)) goto out_free; diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index 13f394e677ae..022f41292a05 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h @@ -234,6 +234,10 @@ int mesh_add_he_oper_ie(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); int mesh_add_he_6ghz_cap_ie(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); +int mesh_add_eht_cap_ie(struct ieee80211_sub_if_data *sdata, + struct sk_buff *skb, u8 ie_len); +int mesh_add_eht_oper_ie(struct ieee80211_sub_if_data *sdata, + struct sk_buff *skb); void mesh_rmc_free(struct ieee80211_sub_if_data *sdata); int mesh_rmc_init(struct ieee80211_sub_if_data *sdata); void ieee80211s_init(void); diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index ddfe5102b9a4..8f168bc4e4b8 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -219,12 +219,14 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, bool include_plid = false; u16 peering_proto = 0; u8 *pos, ie_len = 4; - u8 ie_len_he_cap; + u8 ie_len_he_cap, ie_len_eht_cap; int hdr_len = offsetofend(struct ieee80211_mgmt, u.action.u.self_prot); int err = -ENOMEM; ie_len_he_cap = ieee80211_ie_len_he_cap(sdata, NL80211_IFTYPE_MESH_POINT); + ie_len_eht_cap = ieee80211_ie_len_eht_cap(sdata, + NL80211_IFTYPE_MESH_POINT); skb = dev_alloc_skb(local->tx_headroom + hdr_len + 2 + /* capability info */ @@ -241,6 +243,9 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, 2 + 1 + sizeof(struct ieee80211_he_operation) + sizeof(struct ieee80211_he_6ghz_oper) + 2 + 1 + sizeof(struct ieee80211_he_6ghz_capa) + + ie_len_eht_cap + + 2 + 1 + offsetof(struct ieee80211_eht_operation, optional) + + offsetof(struct ieee80211_eht_operation_info, optional) + 2 + 8 + /* peering IE */ sdata->u.mesh.ie_len); if (!skb) @@ -332,7 +337,9 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, mesh_add_vht_oper_ie(sdata, skb) || mesh_add_he_cap_ie(sdata, skb, ie_len_he_cap) || mesh_add_he_oper_ie(sdata, skb) || - mesh_add_he_6ghz_cap_ie(sdata, skb)) + mesh_add_he_6ghz_cap_ie(sdata, skb) || + mesh_add_eht_cap_ie(sdata, skb, ie_len_eht_cap) || + mesh_add_eht_oper_ie(sdata, skb)) goto free; } @@ -451,6 +458,11 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata, elems->he_6ghz_capa, &sta->deflink); + ieee80211_eht_cap_ie_to_sta_eht_cap(sdata, sband, elems->he_cap, + elems->he_cap_len, + elems->eht_cap, elems->eht_cap_len, + &sta->deflink); + if (bw != sta->sta.deflink.bandwidth) changed |= IEEE80211_RC_BW_CHANGED; diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 9f5cc16538f3..1527d6aafc14 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -3485,6 +3485,77 @@ out: return pos; } +u8 *ieee80211_ie_build_eht_oper(u8 *pos, struct cfg80211_chan_def *chandef, + const struct ieee80211_sta_eht_cap *eht_cap) + +{ + const struct ieee80211_eht_mcs_nss_supp_20mhz_only *eht_mcs_nss = + &eht_cap->eht_mcs_nss_supp.only_20mhz; + struct ieee80211_eht_operation *eht_oper; + struct ieee80211_eht_operation_info *eht_oper_info; + u8 eht_oper_len = offsetof(struct ieee80211_eht_operation, optional); + u8 eht_oper_info_len = + offsetof(struct ieee80211_eht_operation_info, optional); + u8 chan_width = 0; + + *pos++ = WLAN_EID_EXTENSION; + *pos++ = 1 + eht_oper_len + eht_oper_info_len; + *pos++ = WLAN_EID_EXT_EHT_OPERATION; + + eht_oper = (struct ieee80211_eht_operation *)pos; + + memcpy(&eht_oper->basic_mcs_nss, eht_mcs_nss, sizeof(*eht_mcs_nss)); + eht_oper->params |= IEEE80211_EHT_OPER_INFO_PRESENT; + pos += eht_oper_len; + + eht_oper_info = + (struct ieee80211_eht_operation_info *)eht_oper->optional; + + eht_oper_info->ccfs0 = + ieee80211_frequency_to_channel(chandef->center_freq1); + if (chandef->center_freq2) + eht_oper_info->ccfs1 = + ieee80211_frequency_to_channel(chandef->center_freq2); + else + eht_oper_info->ccfs1 = 0; + + switch (chandef->width) { + case NL80211_CHAN_WIDTH_320: + chan_width = IEEE80211_EHT_OPER_CHAN_WIDTH_320MHZ; + eht_oper_info->ccfs1 = eht_oper_info->ccfs0; + if (chandef->chan->center_freq < chandef->center_freq1) + eht_oper_info->ccfs0 -= 16; + else + eht_oper_info->ccfs0 += 16; + break; + case NL80211_CHAN_WIDTH_160: + eht_oper_info->ccfs1 = eht_oper_info->ccfs0; + if (chandef->chan->center_freq < chandef->center_freq1) + eht_oper_info->ccfs0 -= 8; + else + eht_oper_info->ccfs0 += 8; + fallthrough; + case NL80211_CHAN_WIDTH_80P80: + chan_width = IEEE80211_EHT_OPER_CHAN_WIDTH_160MHZ; + break; + case NL80211_CHAN_WIDTH_80: + chan_width = IEEE80211_EHT_OPER_CHAN_WIDTH_80MHZ; + break; + case NL80211_CHAN_WIDTH_40: + chan_width = IEEE80211_EHT_OPER_CHAN_WIDTH_40MHZ; + break; + default: + chan_width = IEEE80211_EHT_OPER_CHAN_WIDTH_20MHZ; + break; + } + eht_oper_info->control = chan_width; + pos += eht_oper_info_len; + + /* TODO: eht_oper_info->optional */ + + return pos; +} + bool ieee80211_chandef_ht_oper(const struct ieee80211_ht_operation *ht_oper, struct cfg80211_chan_def *chandef) { From c7e39d70613c113b5ac667beeb3cacb242c6a4cb Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Sun, 19 Mar 2023 09:54:18 -0400 Subject: [PATCH 09/37] wifi: ipw2x00: remove unused _ipw_read16 function clang with W=1 reports drivers/net/wireless/intel/ipw2x00/ipw2200.c:381:19: error: unused function '_ipw_read16' [-Werror,-Wunused-function] static inline u16 _ipw_read16(struct ipw_priv *ipw, unsigned long ofs) ^ This function and its wrapping marco are not used, so remove them. Signed-off-by: Tom Rix Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230319135418.1703380-1-trix@redhat.com --- drivers/net/wireless/intel/ipw2x00/ipw2200.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2200.c b/drivers/net/wireless/intel/ipw2x00/ipw2200.c index b91b1a2d0be7..dfe0f74369e6 100644 --- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c @@ -377,19 +377,6 @@ static inline u8 _ipw_read8(struct ipw_priv *ipw, unsigned long ofs) _ipw_read8(ipw, ofs); \ }) -/* 16-bit direct read (low 4K) */ -static inline u16 _ipw_read16(struct ipw_priv *ipw, unsigned long ofs) -{ - return readw(ipw->hw_base + ofs); -} - -/* alias to 16-bit direct read (low 4K of SRAM/regs), with debug wrapper */ -#define ipw_read16(ipw, ofs) ({ \ - IPW_DEBUG_IO("%s %d: read_direct16(0x%08X)\n", __FILE__, __LINE__, \ - (u32)(ofs)); \ - _ipw_read16(ipw, ofs); \ -}) - /* 32-bit direct read (low 4K) */ static inline u32 _ipw_read32(struct ipw_priv *ipw, unsigned long ofs) { From 8de7838acfa3309fcc4c6160cb230ee79f582b18 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Mon, 20 Mar 2023 17:13:42 +0100 Subject: [PATCH 10/37] wifi: rsi: Slightly simplify rsi_set_channel() There is no point in allocating 'skb' and then freeing it if !channel. Make the sanity check first to slightly simplify the code. Signed-off-by: Christophe JAILLET Reviewed-by: Simon Horman Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/29bf0296bd939e3f6952272bfdcc73b22edbc374.1679328588.git.christophe.jaillet@wanadoo.fr --- drivers/net/wireless/rsi/rsi_91x_mgmt.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c b/drivers/net/wireless/rsi/rsi_91x_mgmt.c index 1b309e47a1f1..7f2c1608f2ce 100644 --- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c +++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c @@ -1127,6 +1127,9 @@ int rsi_set_channel(struct rsi_common *common, rsi_dbg(MGMT_TX_ZONE, "%s: Sending scan req frame\n", __func__); + if (!channel) + return 0; + skb = dev_alloc_skb(frame_len); if (!skb) { rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n", @@ -1134,10 +1137,6 @@ int rsi_set_channel(struct rsi_common *common, return -ENOMEM; } - if (!channel) { - dev_kfree_skb(skb); - return 0; - } memset(skb->data, 0, frame_len); chan_cfg = (struct rsi_chan_config *)skb->data; From c9b6111a6f94bd186d1f0f7a04a9b37030a27738 Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Mon, 20 Mar 2023 19:34:48 -0400 Subject: [PATCH 11/37] wifi: rtw88: remove unused rtw_pci_get_tx_desc function clang with W=1 reports drivers/net/wireless/realtek/rtw88/pci.c:92:21: error: unused function 'rtw_pci_get_tx_desc' [-Werror,-Wunused-function] static inline void *rtw_pci_get_tx_desc(struct rtw_pci_tx_ring *tx_ring, u8 idx) ^ This function is not used, so remove it. Signed-off-by: Tom Rix Reviewed-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230320233448.1729899-1-trix@redhat.com --- drivers/net/wireless/realtek/rtw88/pci.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/realtek/rtw88/pci.c index b4bd831c9845..6a8e6ee82069 100644 --- a/drivers/net/wireless/realtek/rtw88/pci.c +++ b/drivers/net/wireless/realtek/rtw88/pci.c @@ -89,13 +89,6 @@ static void rtw_pci_write32(struct rtw_dev *rtwdev, u32 addr, u32 val) writel(val, rtwpci->mmap + addr); } -static inline void *rtw_pci_get_tx_desc(struct rtw_pci_tx_ring *tx_ring, u8 idx) -{ - int offset = tx_ring->r.desc_size * idx; - - return tx_ring->r.head + offset; -} - static void rtw_pci_free_tx_ring_skbs(struct rtw_dev *rtwdev, struct rtw_pci_tx_ring *tx_ring) { From 703f15b6dce1e3d38b2455b10c660fafd22e5528 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 22 Mar 2023 12:07:31 +0300 Subject: [PATCH 12/37] wifi: rndis_wlan: clean up a type issue The rndis_bss_info_update() returns type bool. Change the NULL returns to false. Signed-off-by: Dan Carpenter Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/d1f250a3-653a-497d-9c92-12dd628b7927@kili.mountain --- drivers/net/wireless/legacy/rndis_wlan.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/legacy/rndis_wlan.c b/drivers/net/wireless/legacy/rndis_wlan.c index bf72e5fd39cf..cc361d35a90f 100644 --- a/drivers/net/wireless/legacy/rndis_wlan.c +++ b/drivers/net/wireless/legacy/rndis_wlan.c @@ -1972,7 +1972,7 @@ static bool rndis_bss_info_update(struct usbnet *usbdev, if (bssid_len < sizeof(struct ndis_80211_bssid_ex) + sizeof(struct ndis_80211_fixed_ies)) - return NULL; + return false; fixed = (struct ndis_80211_fixed_ies *)bssid->ies; @@ -1981,13 +1981,13 @@ static bool rndis_bss_info_update(struct usbnet *usbdev, (int)le32_to_cpu(bssid->ie_length)); ie_len -= sizeof(struct ndis_80211_fixed_ies); if (ie_len < 0) - return NULL; + return false; /* extract data for cfg80211_inform_bss */ channel = ieee80211_get_channel(priv->wdev.wiphy, KHZ_TO_MHZ(le32_to_cpu(bssid->config.ds_config))); if (!channel) - return NULL; + return false; signal = level_to_qual(le32_to_cpu(bssid->rssi)); timestamp = le64_to_cpu(*(__le64 *)fixed->timestamp); From 06dabcccc08b6323c56062c7fdbb9dba88168565 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Wed, 22 Mar 2023 12:26:53 -0600 Subject: [PATCH 13/37] wifi: rndis_wlan: Replace fake flex-array with flexible-array member MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Zero-length arrays as fake flexible arrays are deprecated and we are moving towards adopting C99 flexible-array members instead. Address the following warning found with GCC-13 and -fstrict-flex-array=3 enabled: drivers/net/wireless/rndis_wlan.c:2902:23: warning: array subscript 0 is outside array bounds of ‘struct ndis_80211_auth_request[0]’ [-Warray-bounds=] This helps with the ongoing efforts to tighten the FORTIFY_SOURCE routines on memcpy() and help us make progress towards globally enabling -fstrict-flex-arrays=3 [1]. Link: https://github.com/KSPP/linux/issues/21 Link: https://github.com/KSPP/linux/issues/274 Link: https://gcc.gnu.org/pipermail/gcc-patches/2022-October/602902.html [1] Signed-off-by: Gustavo A. R. Silva Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/ZBtIbU77L9eXqa4j@work --- drivers/net/wireless/legacy/rndis_wlan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/legacy/rndis_wlan.c b/drivers/net/wireless/legacy/rndis_wlan.c index cc361d35a90f..712038d46bdb 100644 --- a/drivers/net/wireless/legacy/rndis_wlan.c +++ b/drivers/net/wireless/legacy/rndis_wlan.c @@ -209,7 +209,7 @@ struct ndis_80211_status_indication { union { __le32 media_stream_mode; __le32 radio_status; - struct ndis_80211_auth_request auth_request[0]; + DECLARE_FLEX_ARRAY(struct ndis_80211_auth_request, auth_request); struct ndis_80211_pmkid_cand_list cand_list; } u; } __packed; From e665c6d67e541ac7520fa8c5175ad2c0213f247e Mon Sep 17 00:00:00 2001 From: Cai Huoqing Date: Thu, 23 Mar 2023 19:26:12 +0800 Subject: [PATCH 14/37] wifi: rtw88: Remove redundant pci_clear_master Remove pci_clear_master to simplify the code, the bus-mastering is also cleared in do_pci_disable_device, like this: ./drivers/pci/pci.c:2197 static void do_pci_disable_device(struct pci_dev *dev) { u16 pci_command; pci_read_config_word(dev, PCI_COMMAND, &pci_command); if (pci_command & PCI_COMMAND_MASTER) { pci_command &= ~PCI_COMMAND_MASTER; pci_write_config_word(dev, PCI_COMMAND, pci_command); } pcibios_disable_device(dev); }. And dev->is_busmaster is set to 0 in pci_disable_device. Signed-off-by: Cai Huoqing Reviewed-by: Simon Horman Reviewed-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230323112613.7550-4-cai.huoqing@linux.dev --- drivers/net/wireless/realtek/rtw88/pci.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/realtek/rtw88/pci.c index 6a8e6ee82069..672ddde80816 100644 --- a/drivers/net/wireless/realtek/rtw88/pci.c +++ b/drivers/net/wireless/realtek/rtw88/pci.c @@ -1545,7 +1545,6 @@ static int rtw_pci_claim(struct rtw_dev *rtwdev, struct pci_dev *pdev) static void rtw_pci_declaim(struct rtw_dev *rtwdev, struct pci_dev *pdev) { - pci_clear_master(pdev); pci_disable_device(pdev); } From 82d6077901c673546490daa0c1715d6662b06bcf Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Thu, 23 Mar 2023 19:11:35 -0600 Subject: [PATCH 15/37] wifi: rtlwifi: Replace fake flex-array with flex-array member MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Zero-length arrays as fake flexible arrays are deprecated and we are moving towards adopting C99 flexible-array members instead. Address the following warning found with GCC-13 and -fstrict-flex-arrays=3 enabled: In function ‘fortify_memset_chk’, inlined from ‘rtl_usb_probe’ at drivers/net/wireless/realtek/rtlwifi/usb.c:1044:2: ./include/linux/fortify-string.h:430:25: warning: call to ‘__write_overflow_field’ declared with attribute warning: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Wattribute-warning] 430 | __write_overflow_field(p_size_field, size); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This helps with the ongoing efforts to tighten the FORTIFY_SOURCE routines on memcpy() and help us make progress towards globally enabling -fstrict-flex-arrays=3 [1]. Link: https://github.com/KSPP/linux/issues/21 Link: https://github.com/KSPP/linux/issues/277 Link: https://gcc.gnu.org/pipermail/gcc-patches/2022-October/602902.html [1] Signed-off-by: Gustavo A. R. Silva Reviewed-by: Simon Horman Acked-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/ZBz4x+MWoI/f65o1@work --- drivers/net/wireless/realtek/rtlwifi/wifi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/wifi.h b/drivers/net/wireless/realtek/rtlwifi/wifi.h index 31f9e9e5c680..082af216760f 100644 --- a/drivers/net/wireless/realtek/rtlwifi/wifi.h +++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h @@ -2831,7 +2831,7 @@ struct rtl_priv { * beyond this structure like: * rtl_pci_priv or rtl_usb_priv */ - u8 priv[0] __aligned(sizeof(void *)); + u8 priv[] __aligned(sizeof(void *)); }; #define rtl_priv(hw) (((struct rtl_priv *)(hw)->priv)) From 4c7f8c237d322a98026a57f6ba846fc997f165df Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Fri, 24 Mar 2023 09:50:22 -0400 Subject: [PATCH 16/37] wifi: b43legacy: remove unused freq_r3A_value function clang with W=1 reports drivers/net/wireless/broadcom/b43legacy/radio.c:1713:5: error: unused function 'freq_r3A_value' [-Werror,-Wunused-function] u16 freq_r3A_value(u16 frequency) ^ This function is not used so remove it. Signed-off-by: Tom Rix Acked-by: Larry Finger Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230324135022.2649735-1-trix@redhat.com --- drivers/net/wireless/broadcom/b43legacy/radio.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/drivers/net/wireless/broadcom/b43legacy/radio.c b/drivers/net/wireless/broadcom/b43legacy/radio.c index fdf78c10a05c..8d7eb89c1628 100644 --- a/drivers/net/wireless/broadcom/b43legacy/radio.c +++ b/drivers/net/wireless/broadcom/b43legacy/radio.c @@ -1709,23 +1709,6 @@ u16 b43legacy_radio_init2050(struct b43legacy_wldev *dev) return ret; } -static inline -u16 freq_r3A_value(u16 frequency) -{ - u16 value; - - if (frequency < 5091) - value = 0x0040; - else if (frequency < 5321) - value = 0x0000; - else if (frequency < 5806) - value = 0x0080; - else - value = 0x0040; - - return value; -} - int b43legacy_radio_selectchannel(struct b43legacy_wldev *dev, u8 channel, int synthetic_pu_workaround) From 5aeb763a27c2b444928639d35cbe94520c405969 Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Sat, 25 Mar 2023 09:03:43 -0400 Subject: [PATCH 17/37] wifi: brcmsmac: remove unused has_5g variable clang with W=1 reports drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c:1051:6: error: variable 'has_5g' set but not used [-Werror,-Wunused-but-set-variable] int has_5g = 0; ^ This variable is not used so remove it. Signed-off-by: Tom Rix Reviewed-by: Simon Horman Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230325130343.1334209-1-trix@redhat.com --- drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c index a8333e6adbda..0bd4e679a359 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c @@ -1048,7 +1048,6 @@ static int ieee_hw_rate_init(struct ieee80211_hw *hw) struct brcms_info *wl = hw->priv; struct brcms_c_info *wlc = wl->wlc; struct ieee80211_supported_band *band; - int has_5g = 0; u16 phy_type; hw->wiphy->bands[NL80211_BAND_2GHZ] = NULL; @@ -1070,7 +1069,6 @@ static int ieee_hw_rate_init(struct ieee80211_hw *hw) /* Assume all bands use the same phy. True for 11n devices. */ if (wl->pub->_nbands > 1) { - has_5g++; if (phy_type == PHY_TYPE_N || phy_type == PHY_TYPE_LCN) { band = &wlc->bandstate[BAND_5G_INDEX]->band; *band = brcms_band_5GHz_nphy_template; From 905a9241e4e8c15d2c084fee916280514848fe35 Mon Sep 17 00:00:00 2001 From: Wei Chen Date: Sun, 26 Mar 2023 05:31:38 +0000 Subject: [PATCH 18/37] wifi: rtlwifi: fix incorrect error codes in rtl_debugfs_set_write_rfreg() If there is a failure during copy_from_user or user-provided data buffer is invalid, rtl_debugfs_set_write_rfreg should return negative error code instead of a positive value count. Fix this bug by returning correct error code. Moreover, the check of buffer against null is removed since it will be handled by copy_from_user. Fixes: 610247f46feb ("rtlwifi: Improve debugging by using debugfs") Signed-off-by: Wei Chen Reviewed-by: Simon Horman Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230326053138.91338-1-harperchen1110@gmail.com --- drivers/net/wireless/realtek/rtlwifi/debug.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/debug.c b/drivers/net/wireless/realtek/rtlwifi/debug.c index 0b1bc04cb6ad..602717928887 100644 --- a/drivers/net/wireless/realtek/rtlwifi/debug.c +++ b/drivers/net/wireless/realtek/rtlwifi/debug.c @@ -375,8 +375,8 @@ static ssize_t rtl_debugfs_set_write_rfreg(struct file *filp, tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count); - if (!buffer || copy_from_user(tmp, buffer, tmp_len)) - return count; + if (copy_from_user(tmp, buffer, tmp_len)) + return -EFAULT; tmp[tmp_len] = '\0'; @@ -386,7 +386,7 @@ static ssize_t rtl_debugfs_set_write_rfreg(struct file *filp, if (num != 4) { rtl_dbg(rtlpriv, COMP_ERR, DBG_DMESG, "Format is \n"); - return count; + return -EINVAL; } rtl_set_rfreg(hw, path, addr, bitmask, data); From 5dbe1f8eb8c5ac69394400a5b86fd81775e96c43 Mon Sep 17 00:00:00 2001 From: Wei Chen Date: Sun, 26 Mar 2023 05:42:17 +0000 Subject: [PATCH 19/37] wifi: rtlwifi: fix incorrect error codes in rtl_debugfs_set_write_reg() If there is a failure during copy_from_user or user-provided data buffer is invalid, rtl_debugfs_set_write_reg should return negative error code instead of a positive value count. Fix this bug by returning correct error code. Moreover, the check of buffer against null is removed since it will be handled by copy_from_user. Fixes: 610247f46feb ("rtlwifi: Improve debugging by using debugfs") Signed-off-by: Wei Chen Reviewed-by: Simon Horman Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230326054217.93492-1-harperchen1110@gmail.com --- drivers/net/wireless/realtek/rtlwifi/debug.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/debug.c b/drivers/net/wireless/realtek/rtlwifi/debug.c index 602717928887..9eb26dfe4ca9 100644 --- a/drivers/net/wireless/realtek/rtlwifi/debug.c +++ b/drivers/net/wireless/realtek/rtlwifi/debug.c @@ -278,8 +278,8 @@ static ssize_t rtl_debugfs_set_write_reg(struct file *filp, tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count); - if (!buffer || copy_from_user(tmp, buffer, tmp_len)) - return count; + if (copy_from_user(tmp, buffer, tmp_len)) + return -EFAULT; tmp[tmp_len] = '\0'; @@ -287,7 +287,7 @@ static ssize_t rtl_debugfs_set_write_reg(struct file *filp, num = sscanf(tmp, "%x %x %x", &addr, &val, &len); if (num != 3) - return count; + return -EINVAL; switch (len) { case 1: From 2f73f04b7f93f031c94a5c473dd9b7f1cdf91bc0 Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Mon, 27 Mar 2023 11:11:51 -0400 Subject: [PATCH 20/37] wifi: brcmsmac: ampdu: remove unused suc_mpdu variable clang with W=1 reports drivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c:848:5: error: variable 'suc_mpdu' set but not used [-Werror,-Wunused-but-set-variable] u8 suc_mpdu = 0, tot_mpdu = 0; ^ This variable is not used so remove it. Signed-off-by: Tom Rix Reviewed-by: Simon Horman Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230327151151.1771350-1-trix@redhat.com --- drivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c index 2631eb7569eb..e24228e60027 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c @@ -845,7 +845,7 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, u16 seq, start_seq = 0, bindex, index, mcl; u8 mcs = 0; bool ba_recd = false, ack_recd = false; - u8 suc_mpdu = 0, tot_mpdu = 0; + u8 tot_mpdu = 0; uint supr_status; bool retry = true; u16 mimoantsel = 0; @@ -975,7 +975,6 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p); ack_recd = true; - suc_mpdu++; } } /* either retransmit or send bar if ack not recd */ From 074d0a1ae1fefce3dfe73bdda855e62eb8eb2a78 Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Wed, 29 Mar 2023 09:14:44 -0400 Subject: [PATCH 21/37] wifi: mwifiex: remove unused evt_buf variable clang with W=1 reports drivers/net/wireless/marvell/mwifiex/11h.c:198:6: error: variable 'evt_buf' set but not used [-Werror,-Wunused-but-set-variable] u8 *evt_buf; ^ This variable is not used so remove it. Signed-off-by: Tom Rix Reviewed-by: Simon Horman Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230329131444.1809018-1-trix@redhat.com --- drivers/net/wireless/marvell/mwifiex/11h.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/net/wireless/marvell/mwifiex/11h.c b/drivers/net/wireless/marvell/mwifiex/11h.c index b0c40a776a2e..2ea03725f188 100644 --- a/drivers/net/wireless/marvell/mwifiex/11h.c +++ b/drivers/net/wireless/marvell/mwifiex/11h.c @@ -195,7 +195,6 @@ int mwifiex_11h_handle_chanrpt_ready(struct mwifiex_private *priv, { struct host_cmd_ds_chan_rpt_event *rpt_event; struct mwifiex_ie_types_chan_rpt_data *rpt; - u8 *evt_buf; u16 event_len, tlv_len; rpt_event = (void *)(skb->data + sizeof(u32)); @@ -208,8 +207,6 @@ int mwifiex_11h_handle_chanrpt_ready(struct mwifiex_private *priv, return -1; } - evt_buf = (void *)&rpt_event->tlvbuf; - while (event_len >= sizeof(struct mwifiex_ie_types_header)) { rpt = (void *)&rpt_event->tlvbuf; tlv_len = le16_to_cpu(rpt->header.len); @@ -231,7 +228,6 @@ int mwifiex_11h_handle_chanrpt_ready(struct mwifiex_private *priv, break; } - evt_buf += (tlv_len + sizeof(rpt->header)); event_len -= (tlv_len + sizeof(rpt->header)); } From 767d011dc39dc504b17a373ecba4966aef2b0205 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Sun, 19 Mar 2023 11:31:59 -0500 Subject: [PATCH 22/37] bcma: Use of_address_to_resource() Replace of_get_address() and of_translate_address() calls with single call to of_address_to_resource(). Signed-off-by: Rob Herring Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230319163159.225773-1-robh@kernel.org --- drivers/bcma/main.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index 7b39f010bbb3..5e438f74ee4c 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c @@ -140,17 +140,17 @@ static struct device_node *bcma_of_find_child_device(struct device *parent, struct bcma_device *core) { struct device_node *node; - u64 size; - const __be32 *reg; + int ret; if (!parent->of_node) return NULL; for_each_child_of_node(parent->of_node, node) { - reg = of_get_address(node, 0, &size, NULL); - if (!reg) + struct resource res; + ret = of_address_to_resource(node, 0, &res); + if (ret) continue; - if (of_translate_address(node, reg) == core->addr) + if (res.start == core->addr) return node; } return NULL; From 21898a40b2f84deb9438c2ef63f7a5072d6ab2af Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Fri, 24 Mar 2023 15:06:47 -0400 Subject: [PATCH 23/37] bcma: remove unused mips_read32 function clang with W=1 reports drivers/bcma/driver_mips.c:49:19: error: unused function 'mips_read32' [-Werror,-Wunused-function] static inline u32 mips_read32(struct bcma_drv_mips *mcore, ^ This function is not used so remove it. Signed-off-by: Tom Rix Reviewed-by: Simon Horman Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230324190647.2654293-1-trix@redhat.com --- drivers/bcma/driver_mips.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/bcma/driver_mips.c b/drivers/bcma/driver_mips.c index 4f01e6b17bb9..9be0806eb033 100644 --- a/drivers/bcma/driver_mips.c +++ b/drivers/bcma/driver_mips.c @@ -46,12 +46,6 @@ static inline bool bcma_core_mips_bcm5357b0_quirk(struct bcma_device *dev) dev->id.id == BCMA_CORE_USB20_HOST; } -static inline u32 mips_read32(struct bcma_drv_mips *mcore, - u16 offset) -{ - return bcma_read32(mcore->core, offset); -} - static u32 bcma_core_mips_irqflag(struct bcma_device *dev) { u32 flag; From 70a13e5f00e9ee5497b0c25c2787347c4431b5e4 Mon Sep 17 00:00:00 2001 From: Ching-Te Ku Date: Tue, 14 Mar 2023 10:06:13 +0800 Subject: [PATCH 24/37] wifi: rtw89: coex: Add LPS protocol radio state for RTL8852B This LPS state will not turn off RF, and it can still do some basic traffic, only RTL8852B has the state. Coexistence need let Bluetooth know WiFi is still alive to prevent some Bluetooth performance issue. Signed-off-by: Ching-Te Ku Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230314020617.28193-2-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/coex.c | 10 +++++++++- drivers/net/wireless/realtek/rtw89/coex.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c index 3dbd4ee14c70..bd06388ea211 100644 --- a/drivers/net/wireless/realtek/rtw89/coex.c +++ b/drivers/net/wireless/realtek/rtw89/coex.c @@ -5728,6 +5728,11 @@ void rtw89_btc_ntfy_radio_state(struct rtw89_dev *rtwdev, enum btc_rfctrl rf_sta wl->status.map.lps = BTC_LPS_RF_OFF; wl->status.map.busy = 0; break; + case BTC_RFCTRL_LPS_WL_ON: /* LPS-Protocol (RFon) */ + wl->status.map.rf_off = 0; + wl->status.map.lps = BTC_LPS_RF_ON; + wl->status.map.busy = 0; + break; case BTC_RFCTRL_WL_ON: default: wl->status.map.rf_off = 0; @@ -5745,6 +5750,9 @@ void rtw89_btc_ntfy_radio_state(struct rtw89_dev *rtwdev, enum btc_rfctrl rf_sta rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_ALL, false); if (rf_state == BTC_RFCTRL_WL_OFF) _write_scbd(rtwdev, BTC_WSCB_ALL, false); + else if (rf_state == BTC_RFCTRL_LPS_WL_ON && + wl->status.map.lps_pre != BTC_LPS_OFF) + _update_bt_scbd(rtwdev, true); } btc->dm.cnt_dm[BTC_DCNT_BTCNT_HANG] = 0; @@ -5755,7 +5763,7 @@ void rtw89_btc_ntfy_radio_state(struct rtw89_dev *rtwdev, enum btc_rfctrl rf_sta btc->dm.tdma_instant_excute = 0; _run_coex(rtwdev, BTC_RSN_NTFY_RADIO_STATE); - + btc->dm.tdma_instant_excute = 0; wl->status.map.rf_off_pre = wl->status.map.rf_off; wl->status.map.lps_pre = wl->status.map.lps; } diff --git a/drivers/net/wireless/realtek/rtw89/coex.h b/drivers/net/wireless/realtek/rtw89/coex.h index 38cc53a505c3..f16421cb30ef 100644 --- a/drivers/net/wireless/realtek/rtw89/coex.h +++ b/drivers/net/wireless/realtek/rtw89/coex.h @@ -131,6 +131,7 @@ enum btc_role_state { enum btc_rfctrl { BTC_RFCTRL_WL_OFF, BTC_RFCTRL_WL_ON, + BTC_RFCTRL_LPS_WL_ON, BTC_RFCTRL_FW_CTRL, BTC_RFCTRL_MAX }; From 829b3a8b212a71b55598b9bd5861a41906a611ae Mon Sep 17 00:00:00 2001 From: Ching-Te Ku Date: Tue, 14 Mar 2023 10:06:14 +0800 Subject: [PATCH 25/37] wifi: rtw89: coex: Not to enable firmware report when WiFi is power saving If driver enable firmware report during WiFi power saving, the firmware timer will lead to some power saving issue like, fail to enter LPS, can not leave LPS or some unexpected issue. Signed-off-by: Ching-Te Ku Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230314020617.28193-3-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/coex.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c index bd06388ea211..d4a2ed254213 100644 --- a/drivers/net/wireless/realtek/rtw89/coex.c +++ b/drivers/net/wireless/realtek/rtw89/coex.c @@ -1741,10 +1741,14 @@ static void rtw89_btc_fw_en_rpt(struct rtw89_dev *rtwdev, u32 rpt_map, bool rpt_state) { struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_wl_smap *wl_smap = &btc->cx.wl.status.map; struct rtw89_btc_btf_fwinfo *fwinfo = &btc->fwinfo; struct rtw89_btc_btf_set_report r = {0}; u32 val, bit_map; + if ((wl_smap->rf_off || wl_smap->lps != BTC_LPS_OFF) && rpt_state != 0) + return; + bit_map = rtw89_btc_fw_rpt_ver(rtwdev, rpt_map); rtw89_debug(rtwdev, RTW89_DBG_BTC, From 20595db3c0681cc034e50fbcba85a1e6cf3325b5 Mon Sep 17 00:00:00 2001 From: Ching-Te Ku Date: Tue, 14 Mar 2023 10:06:15 +0800 Subject: [PATCH 26/37] wifi: rtw89: coex: Update RTL8852B LNA2 hardware parameter The LNA gain didn't set before, it will lead some WiFi RX issue. And the setting can increase both of WiFi & BT performance while they are both RX. Signed-off-by: Ching-Te Ku Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230314020617.28193-4-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.h | 3 +- drivers/net/wireless/realtek/rtw89/rtw8852a.c | 11 ++-- drivers/net/wireless/realtek/rtw89/rtw8852b.c | 51 ++++++++++++++++++- drivers/net/wireless/realtek/rtw89/rtw8852c.c | 11 ++-- 4 files changed, 68 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index e447bfec508b..3b13f2a6b42d 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -2186,12 +2186,13 @@ struct rtw89_btc_dm { u32 wl_stb_chg: 1; u32 pta_owner: 1; u32 tdma_instant_excute: 1; - u32 rsvd: 1; u16 slot_dur[CXST_MAX]; u8 run_reason; u8 run_action; + + u8 wl_lna2: 1; }; struct rtw89_btc_ctrl { diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c index 9c42b6abd223..152f715d55d5 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c @@ -1947,20 +1947,25 @@ static void rtw8852a_set_wl_lna2(struct rtw89_dev *rtwdev, u8 level) static void rtw8852a_btc_set_wl_rx_gain(struct rtw89_dev *rtwdev, u32 level) { + struct rtw89_btc *btc = &rtwdev->btc; + switch (level) { case 0: /* original */ + default: rtw8852a_bb_ctrl_btc_preagc(rtwdev, false); - rtw8852a_set_wl_lna2(rtwdev, 0); + btc->dm.wl_lna2 = 0; break; case 1: /* for FDD free-run */ rtw8852a_bb_ctrl_btc_preagc(rtwdev, true); - rtw8852a_set_wl_lna2(rtwdev, 0); + btc->dm.wl_lna2 = 0; break; case 2: /* for BTG Co-Rx*/ rtw8852a_bb_ctrl_btc_preagc(rtwdev, false); - rtw8852a_set_wl_lna2(rtwdev, 1); + btc->dm.wl_lna2 = 1; break; } + + rtw8852a_set_wl_lna2(rtwdev, btc->dm.wl_lna2); } static void rtw8852a_fill_freq_with_ppdu(struct rtw89_dev *rtwdev, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c index 499ae0389c71..7bab6d2ab776 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c @@ -2284,15 +2284,64 @@ static void rtw8852b_btc_wl_s1_standby(struct rtw89_dev *rtwdev, bool state) /* set WL standby = Rx for GNT_BT_Tx = 1->0 settle issue */ if (state) - rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x579); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x179); else rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x20); rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x0); } +static void rtw8852b_btc_set_wl_lna2(struct rtw89_dev *rtwdev, u8 level) +{ + switch (level) { + case 0: /* default */ + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x1000); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x15); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x1); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x17); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x2); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x15); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x3); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x17); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x0); + break; + case 1: /* Fix LNA2=5 */ + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x1000); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x0); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x15); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x1); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x5); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x2); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x15); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWA, RFREG_MASK, 0x3); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWD0, RFREG_MASK, 0x5); + rtw89_write_rf(rtwdev, RF_PATH_B, RR_LUTWE, RFREG_MASK, 0x0); + break; + } +} + static void rtw8852b_btc_set_wl_rx_gain(struct rtw89_dev *rtwdev, u32 level) { + struct rtw89_btc *btc = &rtwdev->btc; + + switch (level) { + case 0: /* original */ + default: + rtw8852b_bb_ctrl_btc_preagc(rtwdev, false); + btc->dm.wl_lna2 = 0; + break; + case 1: /* for FDD free-run */ + rtw8852b_bb_ctrl_btc_preagc(rtwdev, true); + btc->dm.wl_lna2 = 0; + break; + case 2: /* for BTG Co-Rx*/ + rtw8852b_bb_ctrl_btc_preagc(rtwdev, false); + btc->dm.wl_lna2 = 1; + break; + } + + rtw8852b_btc_set_wl_lna2(rtwdev, btc->dm.wl_lna2); } static void rtw8852b_fill_freq_with_ppdu(struct rtw89_dev *rtwdev, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index 8af813132f71..758021287552 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -2633,20 +2633,25 @@ static void rtw8852c_set_wl_lna2(struct rtw89_dev *rtwdev, u8 level) static void rtw8852c_btc_set_wl_rx_gain(struct rtw89_dev *rtwdev, u32 level) { + struct rtw89_btc *btc = &rtwdev->btc; + switch (level) { case 0: /* original */ + default: rtw8852c_bb_ctrl_btc_preagc(rtwdev, false); - rtw8852c_set_wl_lna2(rtwdev, 0); + btc->dm.wl_lna2 = 0; break; case 1: /* for FDD free-run */ rtw8852c_bb_ctrl_btc_preagc(rtwdev, true); - rtw8852c_set_wl_lna2(rtwdev, 0); + btc->dm.wl_lna2 = 0; break; case 2: /* for BTG Co-Rx*/ rtw8852c_bb_ctrl_btc_preagc(rtwdev, false); - rtw8852c_set_wl_lna2(rtwdev, 1); + btc->dm.wl_lna2 = 1; break; } + + rtw8852c_set_wl_lna2(rtwdev, btc->dm.wl_lna2); } static void rtw8852c_fill_freq_with_ppdu(struct rtw89_dev *rtwdev, From d7904ca8a04062e1c926498966a9fab4abfab161 Mon Sep 17 00:00:00 2001 From: Ching-Te Ku Date: Tue, 14 Mar 2023 10:06:16 +0800 Subject: [PATCH 27/37] wifi: rtw89: coex: Add report control v5 variation In order to reduce firmware code size cost, remove some counter value from the structure. But firmware didn't update version code. To parse the correct report, add another variation version v105 to parse it. Signed-off-by: Ching-Te Ku Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230314020617.28193-5-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/coex.c | 148 ++++++++++++++++++++++ drivers/net/wireless/realtek/rtw89/core.h | 23 ++++ 2 files changed, 171 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c index d4a2ed254213..c0ca37473f03 100644 --- a/drivers/net/wireless/realtek/rtw89/coex.c +++ b/drivers/net/wireless/realtek/rtw89/coex.c @@ -1022,6 +1022,11 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, } else if (ver->fcxbtcrpt == 5) { pfinfo = &pfwinfo->rpt_ctrl.finfo.v5; pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v5); + } else if (ver->fcxbtcrpt == 105) { + pfinfo = &pfwinfo->rpt_ctrl.finfo.v105; + pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v105); + pcinfo->req_fver = 5; + break; } else { goto err; } @@ -1263,6 +1268,33 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev, _chk_btc_err(rtwdev, BTC_DCNT_RPT_HANG, pfwinfo->event[BTF_EVNT_RPT]); + dm->error.map.bt_rfk_timeout = bt->rfk_info.map.timeout; + } else if (ver->fcxbtcrpt == 105) { + prpt->v105 = pfwinfo->rpt_ctrl.finfo.v105; + pfwinfo->rpt_en_map = le32_to_cpu(prpt->v105.rpt_info.en); + wl->ver_info.fw_coex = le32_to_cpu(prpt->v105.rpt_info.cx_ver); + wl->ver_info.fw = le32_to_cpu(prpt->v105.rpt_info.fw_ver); + dm->wl_fw_cx_offload = 0; + + for (i = RTW89_PHY_0; i < RTW89_PHY_MAX; i++) + memcpy(&dm->gnt.band[i], &prpt->v105.gnt_val[i][0], + sizeof(dm->gnt.band[i])); + + btc->cx.cnt_bt[BTC_BCNT_HIPRI_TX] = + le16_to_cpu(prpt->v105.bt_cnt[BTC_BCNT_HI_TX_V105]); + btc->cx.cnt_bt[BTC_BCNT_HIPRI_RX] = + le16_to_cpu(prpt->v105.bt_cnt[BTC_BCNT_HI_RX_V105]); + btc->cx.cnt_bt[BTC_BCNT_LOPRI_TX] = + le16_to_cpu(prpt->v105.bt_cnt[BTC_BCNT_LO_TX_V105]); + btc->cx.cnt_bt[BTC_BCNT_LOPRI_RX] = + le16_to_cpu(prpt->v105.bt_cnt[BTC_BCNT_LO_RX_V105]); + btc->cx.cnt_bt[BTC_BCNT_POLUT] = + le16_to_cpu(prpt->v105.bt_cnt[BTC_BCNT_POLLUTED_V105]); + + _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_HANG, 0); + _chk_btc_err(rtwdev, BTC_DCNT_RPT_HANG, + pfwinfo->event[BTF_EVNT_RPT]); + dm->error.map.bt_rfk_timeout = bt->rfk_info.map.timeout; } else { goto err; @@ -8165,7 +8197,121 @@ static void _show_summary_v5(struct rtw89_dev *rtwdev, struct seq_file *m) le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_on), le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_off)); } else { + seq_printf(m, + " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d", + "[summary]", pfwinfo->cnt_h2c, + pfwinfo->cnt_h2c_fail, pfwinfo->cnt_c2h); + } + + if (!pcinfo->valid || pfwinfo->len_mismch || pfwinfo->fver_mismch || + pfwinfo->err[BTFRE_EXCEPTION]) { seq_puts(m, "\n"); + seq_printf(m, + " %-15s : WL FW rpt error!![rpt_ctrl_valid:%d/len:" + "0x%x/ver:0x%x/ex:%d/lps=%d/rf_off=%d]", + "[ERROR]", pcinfo->valid, pfwinfo->len_mismch, + pfwinfo->fver_mismch, pfwinfo->err[BTFRE_EXCEPTION], + wl->status.map.lps, wl->status.map.rf_off); + } + + for (i = 0; i < BTC_NCNT_NUM; i++) + cnt_sum += dm->cnt_notify[i]; + + seq_puts(m, "\n"); + seq_printf(m, + " %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ", + "[notify_cnt]", + cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO], + cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]); + + seq_printf(m, + "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d", + cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE], + cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK], + cnt[BTC_NCNT_WL_STA]); + + seq_puts(m, "\n"); + seq_printf(m, + " %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, special_pkt=%d, ", + "[notify_cnt]", + cnt[BTC_NCNT_SCAN_START], cnt[BTC_NCNT_SCAN_FINISH], + cnt[BTC_NCNT_SWITCH_BAND], cnt[BTC_NCNT_SPECIAL_PACKET]); + + seq_printf(m, + "timer=%d, control=%d, customerize=%d", + cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CONTROL], + cnt[BTC_NCNT_CUSTOMERIZE]); +} + +static void _show_summary_v105(struct rtw89_dev *rtwdev, struct seq_file *m) +{ + struct rtw89_btc *btc = &rtwdev->btc; + struct rtw89_btc_btf_fwinfo *pfwinfo = &btc->fwinfo; + struct rtw89_btc_fbtc_rpt_ctrl_v105 *prptctrl; + struct rtw89_btc_rpt_cmn_info *pcinfo; + struct rtw89_btc_cx *cx = &btc->cx; + struct rtw89_btc_dm *dm = &btc->dm; + struct rtw89_btc_wl_info *wl = &cx->wl; + u32 cnt_sum = 0, *cnt = btc->dm.cnt_notify; + u8 i; + + if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY)) + return; + + seq_puts(m, "========== [Statistics] ==========\n"); + + pcinfo = &pfwinfo->rpt_ctrl.cinfo; + if (pcinfo->valid && !wl->status.map.lps && !wl->status.map.rf_off) { + prptctrl = &pfwinfo->rpt_ctrl.finfo.v105; + + seq_printf(m, + " %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d, len:%d), ", + "[summary]", pfwinfo->cnt_h2c, pfwinfo->cnt_h2c_fail, + le16_to_cpu(prptctrl->rpt_info.cnt_h2c), + pfwinfo->cnt_c2h, + le16_to_cpu(prptctrl->rpt_info.cnt_c2h), + le16_to_cpu(prptctrl->rpt_info.len_c2h)); + + seq_printf(m, + "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x", + pfwinfo->event[BTF_EVNT_RPT], + le16_to_cpu(prptctrl->rpt_info.cnt), + le32_to_cpu(prptctrl->rpt_info.en)); + + if (dm->error.map.wl_fw_hang) + seq_puts(m, " (WL FW Hang!!)"); + seq_puts(m, "\n"); + seq_printf(m, + " %-15s : send_ok:%d, send_fail:%d, recv:%d, ", + "[mailbox]", + le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok), + le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail), + le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv)); + + seq_printf(m, + "A2DP_empty:%d(stop:%d, tx:%d, ack:%d, nack:%d)\n", + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack), + le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack)); + + seq_printf(m, + " %-15s : wl_rfk[req:%d/go:%d/reject:%d/tout:%d]", + "[RFK/LPS]", cx->cnt_wl[BTC_WCNT_RFK_REQ], + cx->cnt_wl[BTC_WCNT_RFK_GO], + cx->cnt_wl[BTC_WCNT_RFK_REJECT], + cx->cnt_wl[BTC_WCNT_RFK_TIMEOUT]); + + seq_printf(m, + ", bt_rfk[req:%d]", + le16_to_cpu(prptctrl->bt_cnt[BTC_BCNT_RFK_REQ])); + + seq_printf(m, + ", AOAC[RF_on:%d/RF_off:%d]", + le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_on), + le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_off)); + } else { seq_printf(m, " %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d", "[summary]", pfwinfo->cnt_h2c, @@ -8256,6 +8402,8 @@ void rtw89_btc_dump_info(struct rtw89_dev *rtwdev, struct seq_file *m) _show_summary_v4(rtwdev, m); else if (ver->fcxbtcrpt == 5) _show_summary_v5(rtwdev, m); + else if (ver->fcxbtcrpt == 105) + _show_summary_v105(rtwdev, m); } void rtw89_coex_recognize_ver(struct rtw89_dev *rtwdev) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 3b13f2a6b42d..ea2eb3ac1df0 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -1576,6 +1576,16 @@ enum rtw89_btc_bt_sta_counter { BTC_BCNT_STA_MAX }; +enum rtw89_btc_bt_sta_counter_v105 { + BTC_BCNT_RFK_REQ_V105 = 0, + BTC_BCNT_HI_TX_V105 = 1, + BTC_BCNT_HI_RX_V105 = 2, + BTC_BCNT_LO_TX_V105 = 3, + BTC_BCNT_LO_RX_V105 = 4, + BTC_BCNT_POLLUTED_V105 = 5, + BTC_BCNT_STA_MAX_V105 +}; + struct rtw89_btc_fbtc_rpt_ctrl_v1 { u16 fver; /* btc_ver::fcxbtcrpt */ u16 rpt_cnt; /* tmr counters */ @@ -1666,10 +1676,23 @@ struct rtw89_btc_fbtc_rpt_ctrl_v5 { struct rtw89_btc_fbtc_rpt_ctrl_bt_mailbox bt_mbx_info; } __packed; +struct rtw89_btc_fbtc_rpt_ctrl_v105 { + u8 fver; + u8 rsvd; + __le16 rsvd1; + + u8 gnt_val[RTW89_PHY_MAX][4]; + __le16 bt_cnt[BTC_BCNT_STA_MAX_V105]; + + struct rtw89_btc_fbtc_rpt_ctrl_info_v5 rpt_info; + struct rtw89_btc_fbtc_rpt_ctrl_bt_mailbox bt_mbx_info; +} __packed; + union rtw89_btc_fbtc_rpt_ctrl_ver_info { struct rtw89_btc_fbtc_rpt_ctrl_v1 v1; struct rtw89_btc_fbtc_rpt_ctrl_v4 v4; struct rtw89_btc_fbtc_rpt_ctrl_v5 v5; + struct rtw89_btc_fbtc_rpt_ctrl_v105 v105; }; enum rtw89_fbtc_ext_ctrl_type { From 7527251f77664dd19716f36f53b723845d537eec Mon Sep 17 00:00:00 2001 From: Ching-Te Ku Date: Tue, 14 Mar 2023 10:06:17 +0800 Subject: [PATCH 28/37] wifi: rtw89: coex: Update Wi-Fi Bluetooth coexistence version to 7.0.1 Update driver with the supported firmware version of the below item. Bluetooth firmware BT_Coex_Ver: 0x07 Wi-Fi firmware version: RTL8852C->v0.27.56.10 RTL8852A->v0.24.36 RTL8852B->v0.29.29 Signed-off-by: Ching-Te Ku Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230314020617.28193-6-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/coex.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c index c0ca37473f03..acb3fac0c96d 100644 --- a/drivers/net/wireless/realtek/rtw89/coex.c +++ b/drivers/net/wireless/realtek/rtw89/coex.c @@ -9,7 +9,7 @@ #include "ps.h" #include "reg.h" -#define RTW89_COEX_VERSION 0x07000013 +#define RTW89_COEX_VERSION 0x07000113 #define FCXDEF_STEP 50 /* MUST <= FCXMAX_STEP and match with wl fw*/ enum btc_fbtc_tdma_template { @@ -148,6 +148,13 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = { .fwlrole = 1, .frptmap = 2, .fcxctrl = 1, .info_buf = 1280, .max_role_num = 5, }, + {RTL8852B, RTW89_FW_VER_CODE(0, 29, 29, 0), + .fcxbtcrpt = 105, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 5, + .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 2, .fcxgpiodbg = 1, + .fcxbtver = 1, .fcxbtscan = 2, .fcxbtafh = 2, .fcxbtdevinfo = 1, + .fwlrole = 1, .frptmap = 3, .fcxctrl = 1, + .info_buf = 1800, .max_role_num = 6, + }, {RTL8852B, RTW89_FW_VER_CODE(0, 29, 14, 0), .fcxbtcrpt = 5, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 4, .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1, From e749ef968f14a92155b2c3138d7720cf39e65e00 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Thu, 16 Mar 2023 14:39:56 +0800 Subject: [PATCH 29/37] wifi: rtw89: add counters of register-based H2C/C2H The register-based H2C/C2H are used to exchange information between driver and firmware, but only apply to narrow area because its data size is smaller than regular packet-based H2C/C2H. This kind of H2C/C2H must be paired. To identify if any H2C/C2H is missing, update counters to help diagnose this kind of problems. Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230316063956.71687-1-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.h | 4 ++++ drivers/net/wireless/realtek/rtw89/fw.c | 11 +++++++++++ drivers/net/wireless/realtek/rtw89/mac.c | 2 ++ drivers/net/wireless/realtek/rtw89/reg.h | 5 +++++ drivers/net/wireless/realtek/rtw89/rtw8852a.c | 2 ++ drivers/net/wireless/realtek/rtw89/rtw8852b.c | 2 ++ drivers/net/wireless/realtek/rtw89/rtw8852c.c | 2 ++ 7 files changed, 28 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index ea2eb3ac1df0..62770d445713 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -3140,8 +3140,10 @@ struct rtw89_chip_info { u32 txwd_body_size; u32 h2c_ctrl_reg; const u32 *h2c_regs; + struct rtw89_reg_def h2c_counter_reg; u32 c2h_ctrl_reg; const u32 *c2h_regs; + struct rtw89_reg_def c2h_counter_reg; const struct rtw89_page_regs *page_regs; bool cfo_src_fd; const struct rtw89_reg_def *dcfo_comp; @@ -3268,6 +3270,8 @@ struct rtw89_fw_info { struct completion completion; u8 h2c_seq; u8 rec_seq; + u8 h2c_counter; + u8 c2h_counter; struct rtw89_fw_suit normal; struct rtw89_fw_suit wowlan; bool fw_log_enable; diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index 713aefd0cf8d..5fa6863d36b3 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -615,6 +615,8 @@ int rtw89_fw_download(struct rtw89_dev *rtwdev, enum rtw89_fw_type type) fw_info->h2c_seq = 0; fw_info->rec_seq = 0; + fw_info->h2c_counter = 0; + fw_info->c2h_counter = 0; rtwdev->mac.rpwm_seq_num = RPWM_SEQ_NUM_MAX; rtwdev->mac.cpwm_seq_num = CPWM_SEQ_NUM_MAX; @@ -2724,6 +2726,7 @@ static int rtw89_fw_write_h2c_reg(struct rtw89_dev *rtwdev, struct rtw89_mac_h2c_info *info) { const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_fw_info *fw_info = &rtwdev->fw; const u32 *h2c_reg = chip->h2c_regs; u8 i, val, len; int ret; @@ -2743,6 +2746,9 @@ static int rtw89_fw_write_h2c_reg(struct rtw89_dev *rtwdev, for (i = 0; i < RTW89_H2CREG_MAX; i++) rtw89_write32(rtwdev, h2c_reg[i], info->h2creg[i]); + fw_info->h2c_counter++; + rtw89_write8_mask(rtwdev, chip->h2c_counter_reg.addr, + chip->h2c_counter_reg.mask, fw_info->h2c_counter); rtw89_write8(rtwdev, chip->h2c_ctrl_reg, B_AX_H2CREG_TRIGGER); return 0; @@ -2752,6 +2758,7 @@ static int rtw89_fw_read_c2h_reg(struct rtw89_dev *rtwdev, struct rtw89_mac_c2h_info *info) { const struct rtw89_chip_info *chip = rtwdev->chip; + struct rtw89_fw_info *fw_info = &rtwdev->fw; const u32 *c2h_reg = chip->c2h_regs; u32 ret; u8 i, val; @@ -2775,6 +2782,10 @@ static int rtw89_fw_read_c2h_reg(struct rtw89_dev *rtwdev, info->content_len = (RTW89_GET_C2H_HDR_LEN(*info->c2hreg) << 2) - RTW89_C2HREG_HDR_LEN; + fw_info->c2h_counter++; + rtw89_write8_mask(rtwdev, chip->c2h_counter_reg.addr, + chip->c2h_counter_reg.mask, fw_info->c2h_counter); + return 0; } diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index 7866fe925d24..d0e138f8b880 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -3398,6 +3398,8 @@ int rtw89_mac_enable_cpu(struct rtw89_dev *rtwdev, u8 boot_reason, bool dlfw) if (rtw89_read32(rtwdev, R_AX_PLATFORM_ENABLE) & B_AX_WCPU_EN) return -EFAULT; + rtw89_write32(rtwdev, R_AX_UDM1, 0); + rtw89_write32(rtwdev, R_AX_UDM2, 0); rtw89_write32(rtwdev, R_AX_HALT_H2C_CTRL, 0); rtw89_write32(rtwdev, R_AX_HALT_C2H_CTRL, 0); rtw89_write32(rtwdev, R_AX_HALT_H2C, 0); diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index e5c0ab43ab7a..c75aee61f383 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -207,6 +207,11 @@ #define R_AX_UDM0 0x01F0 #define R_AX_UDM1 0x01F4 +#define B_AX_UDM1_MASK GENMASK(31, 16) +#define B_AX_UDM1_HALMAC_C2H_ENQ_CNT_MASK GENMASK(15, 12) +#define B_AX_UDM1_HALMAC_H2C_DEQ_CNT_MASK GENMASK(11, 8) +#define B_AX_UDM1_WCPU_C2H_ENQ_CNT_MASK GENMASK(7, 4) +#define B_AX_UDM1_WCPU_H2C_DEQ_CNT_MASK GENMASK(3, 0) #define R_AX_UDM2 0x01F8 #define R_AX_UDM3 0x01FC diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c index 152f715d55d5..e6f8df929a95 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c @@ -2136,9 +2136,11 @@ const struct rtw89_chip_info rtw8852a_chip_info = { .h2c_desc_size = sizeof(struct rtw89_txwd_body), .txwd_body_size = sizeof(struct rtw89_txwd_body), .h2c_ctrl_reg = R_AX_H2CREG_CTRL, + .h2c_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_H2C_DEQ_CNT_MASK >> 8}, .h2c_regs = rtw8852a_h2c_regs, .c2h_ctrl_reg = R_AX_C2HREG_CTRL, .c2h_regs = rtw8852a_c2h_regs, + .c2h_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_C2H_ENQ_CNT_MASK >> 8}, .page_regs = &rtw8852a_page_regs, .cfo_src_fd = false, .dcfo_comp = &rtw8852a_dcfo_comp, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c index 7bab6d2ab776..27733a3da6df 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c @@ -2557,8 +2557,10 @@ const struct rtw89_chip_info rtw8852b_chip_info = { .h2c_desc_size = sizeof(struct rtw89_txwd_body), .txwd_body_size = sizeof(struct rtw89_txwd_body), .h2c_ctrl_reg = R_AX_H2CREG_CTRL, + .h2c_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_H2C_DEQ_CNT_MASK >> 8}, .h2c_regs = rtw8852b_h2c_regs, .c2h_ctrl_reg = R_AX_C2HREG_CTRL, + .c2h_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_C2H_ENQ_CNT_MASK >> 8}, .c2h_regs = rtw8852b_c2h_regs, .page_regs = &rtw8852b_page_regs, .cfo_src_fd = true, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index 758021287552..a82bee5c8f0a 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -2872,8 +2872,10 @@ const struct rtw89_chip_info rtw8852c_chip_info = { .h2c_desc_size = sizeof(struct rtw89_rxdesc_short), .txwd_body_size = sizeof(struct rtw89_txwd_body_v1), .h2c_ctrl_reg = R_AX_H2CREG_CTRL_V1, + .h2c_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_H2C_DEQ_CNT_MASK >> 8}, .h2c_regs = rtw8852c_h2c_regs, .c2h_ctrl_reg = R_AX_C2HREG_CTRL_V1, + .c2h_counter_reg = {R_AX_UDM1 + 1, B_AX_UDM1_HALMAC_C2H_ENQ_CNT_MASK >> 8}, .c2h_regs = rtw8852c_c2h_regs, .page_regs = &rtw8852c_page_regs, .cfo_src_fd = false, From e5307c9cd7ee50accd4e5f28d6a6e09ec11849e3 Mon Sep 17 00:00:00 2001 From: Chih-Kang Chang Date: Mon, 20 Mar 2023 17:31:10 +0800 Subject: [PATCH 30/37] wifi: rtw89: set data lowest rate according to AP supported rate By default the driver uses the 1M and 6M rate (0x0) for data frames in 2 GHz and 5/6 GHz bands respectively. But the rate that might not AP supported. Therefore, We modify the data lowest rate according to the lowest of AP supported rate. Signed-off-by: Chih-Kang Chang Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230320093112.30466-1-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.c | 38 +++++++++++++++++------ 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index 489fa7a86160..208fd589ffa2 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -686,6 +686,33 @@ desc_bk: desc_info->bk = true; } +static u16 rtw89_core_get_data_rate(struct rtw89_dev *rtwdev, + struct rtw89_core_tx_request *tx_req) +{ + struct ieee80211_vif *vif = tx_req->vif; + struct ieee80211_sta *sta = tx_req->sta; + struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + struct rtw89_phy_rate_pattern *rate_pattern = &rtwvif->rate_pattern; + enum rtw89_sub_entity_idx idx = rtwvif->sub_entity_idx; + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx); + u16 lowest_rate; + + if (rate_pattern->enable) + return rate_pattern->rate; + + if (vif->p2p) + lowest_rate = RTW89_HW_RATE_OFDM6; + else if (chan->band_type == RTW89_BAND_2G) + lowest_rate = RTW89_HW_RATE_CCK1; + else + lowest_rate = RTW89_HW_RATE_OFDM6; + + if (!sta->deflink.supp_rates[chan->band_type]) + return lowest_rate; + + return __ffs(sta->deflink.supp_rates[chan->band_type]) + lowest_rate; +} + static void rtw89_core_tx_update_data_info(struct rtw89_dev *rtwdev, struct rtw89_core_tx_request *tx_req) @@ -694,8 +721,6 @@ rtw89_core_tx_update_data_info(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta = tx_req->sta; struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta); - struct rtw89_phy_rate_pattern *rate_pattern = &rtwvif->rate_pattern; - const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0); struct rtw89_tx_desc_info *desc_info = &tx_req->desc_info; struct sk_buff *skb = tx_req->skb; u8 tid, tid_indicate; @@ -719,14 +744,7 @@ rtw89_core_tx_update_data_info(struct rtw89_dev *rtwdev, if (IEEE80211_SKB_CB(skb)->control.hw_key) rtw89_core_tx_update_sec_key(rtwdev, tx_req); - if (vif->p2p) - desc_info->data_retry_lowest_rate = RTW89_HW_RATE_OFDM6; - else if (rate_pattern->enable) - desc_info->data_retry_lowest_rate = rate_pattern->rate; - else if (chan->band_type == RTW89_BAND_2G) - desc_info->data_retry_lowest_rate = RTW89_HW_RATE_CCK1; - else - desc_info->data_retry_lowest_rate = RTW89_HW_RATE_OFDM6; + desc_info->data_retry_lowest_rate = rtw89_core_get_data_rate(rtwdev, tx_req); } static enum btc_pkt_type From 41209362d700f868ae7f0f30dc7634d0e0026880 Mon Sep 17 00:00:00 2001 From: Chin-Yen Lee Date: Mon, 20 Mar 2023 17:31:11 +0800 Subject: [PATCH 31/37] wifi: rtw89: remove superfluous H2C of join_info We find that when starting WoWLAN, the second join_info H2C is unnecessary and leads WoWLAN not enter power save mode if using new firmware, so remove it. Signed-off-by: Chin-Yen Lee Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230320093112.30466-2-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/wow.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/wow.c b/drivers/net/wireless/realtek/rtw89/wow.c index c78ee2ab732c..7cff9c1d8d37 100644 --- a/drivers/net/wireless/realtek/rtw89/wow.c +++ b/drivers/net/wireless/realtek/rtw89/wow.c @@ -420,14 +420,11 @@ static int rtw89_wow_cfg_wake(struct rtw89_dev *rtwdev, bool wow) struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv; struct ieee80211_sta *wow_sta; struct rtw89_sta *rtwsta = NULL; - bool is_conn = true; int ret; wow_sta = ieee80211_find_sta(wow_vif, rtwvif->bssid); if (wow_sta) rtwsta = (struct rtw89_sta *)wow_sta->drv_priv; - else - is_conn = false; if (wow) { if (rtw_wow->pattern_cnt) @@ -454,12 +451,6 @@ static int rtw89_wow_cfg_wake(struct rtw89_dev *rtwdev, bool wow) } } - ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif, rtwsta, !is_conn); - if (ret) { - rtw89_warn(rtwdev, "failed to send h2c join info\n"); - return ret; - } - ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL); if (ret) { rtw89_warn(rtwdev, "failed to send h2c cam\n"); From 40711486c7ba91a35ba495564e45be0f2a1b3729 Mon Sep 17 00:00:00 2001 From: Chih-Kang Chang Date: Mon, 20 Mar 2023 17:31:12 +0800 Subject: [PATCH 32/37] wifi: rtw89: fix incorrect channel info during scan due to ppdu_sts filtering We use ppdu_sts to obtain channel information from hardware, to ensure that the scan results have correct channel information. However, some of ppdu_sts that is filtered by the to_self check is also needed for the scan results. Therefore, we modify the filter part in front of CFO count. Signed-off-by: Chih-Kang Chang Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230320093112.30466-3-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index 208fd589ffa2..448597835761 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -1220,6 +1220,10 @@ static void rtw89_core_parse_phy_status_ie01(struct rtw89_dev *rtwdev, u8 *addr, phy_ppdu->chan_idx = RTW89_GET_PHY_STS_IE01_CH_IDX(addr); if (phy_ppdu->rate < RTW89_HW_RATE_OFDM6) return; + + if (!phy_ppdu->to_self) + return; + /* sign conversion for S(12,2) */ if (rtwdev->chip->cfo_src_fd) cfo = sign_extend32(RTW89_GET_PHY_STS_IE01_FD_CFO(addr), 11); @@ -1284,9 +1288,6 @@ static int rtw89_core_rx_parse_phy_sts(struct rtw89_dev *rtwdev, if (phy_ppdu->ie < RTW89_CCK_PKT) return -EINVAL; - if (!phy_ppdu->to_self) - return 0; - pos = (u8 *)phy_ppdu->buf + PHY_STS_HDR_LEN; end = (u8 *)phy_ppdu->buf + phy_ppdu->len; while (pos < end) { From 280c444745aaf0ff7f2e54b000bd9fff9f1bbaf2 Mon Sep 17 00:00:00 2001 From: Chih-Kang Chang Date: Wed, 22 Mar 2023 14:02:38 +0800 Subject: [PATCH 33/37] wifi: rtw89: config EDCCA threshold during scan to prevent TX failed Need to configure EDCCA threshold to default value before scan, and recall original value after scan to prevent probe request can't be sent out. Signed-off-by: Chih-Kang Chang Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230322060238.43922-1-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.c | 2 ++ drivers/net/wireless/realtek/rtw89/core.h | 3 +++ drivers/net/wireless/realtek/rtw89/phy.c | 19 +++++++++++++++++++ drivers/net/wireless/realtek/rtw89/phy.h | 1 + drivers/net/wireless/realtek/rtw89/reg.h | 5 +++++ drivers/net/wireless/realtek/rtw89/rtw8852a.c | 1 + drivers/net/wireless/realtek/rtw89/rtw8852b.c | 1 + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 1 + 8 files changed, 33 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index 448597835761..0ec52a8b83b0 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -3264,6 +3264,7 @@ void rtw89_core_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, rtw89_btc_ntfy_scan_start(rtwdev, RTW89_PHY_0, chan->band_type); rtw89_chip_rfk_scan(rtwdev, true); rtw89_hci_recalc_int_mit(rtwdev); + rtw89_phy_config_edcca(rtwdev, true); rtw89_fw_h2c_cam(rtwdev, rtwvif, NULL, mac_addr); } @@ -3281,6 +3282,7 @@ void rtw89_core_scan_complete(struct rtw89_dev *rtwdev, rtw89_chip_rfk_scan(rtwdev, false); rtw89_btc_ntfy_scan_finish(rtwdev, RTW89_PHY_0); + rtw89_phy_config_edcca(rtwdev, false); rtwdev->scanning = false; rtwdev->dig.bypass_dig = true; diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 62770d445713..40fb18b613d9 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -3152,6 +3152,7 @@ struct rtw89_chip_info { const struct rtw89_rrsr_cfgs *rrsr_cfgs; u32 bss_clr_map_reg; u32 dma_ch_mask; + u32 edcca_lvl_reg; const struct wiphy_wowlan_support *wowlan_stub; }; @@ -3363,6 +3364,8 @@ struct rtw89_hal { bool entity_active; enum rtw89_entity_mode entity_mode; + + u32 edcca_bak; }; #define RTW89_MAX_MAC_ID_NUM 128 diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c index d8b035972dd4..cb0f6cc51d6b 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.c +++ b/drivers/net/wireless/realtek/rtw89/phy.c @@ -4366,3 +4366,22 @@ void rtw89_decode_chan_idx(struct rtw89_dev *rtwdev, u8 chan_idx, *ch = rtw89_ch_base_table[idx] + (offset << 1); } EXPORT_SYMBOL(rtw89_decode_chan_idx); + +#define EDCCA_DEFAULT 249 +void rtw89_phy_config_edcca(struct rtw89_dev *rtwdev, bool scan) +{ + u32 reg = rtwdev->chip->edcca_lvl_reg; + struct rtw89_hal *hal = &rtwdev->hal; + u32 val; + + if (scan) { + hal->edcca_bak = rtw89_phy_read32(rtwdev, reg); + val = hal->edcca_bak; + u32p_replace_bits(&val, EDCCA_DEFAULT, B_SEG0R_EDCCA_LVL_A_MSK); + u32p_replace_bits(&val, EDCCA_DEFAULT, B_SEG0R_EDCCA_LVL_P_MSK); + u32p_replace_bits(&val, EDCCA_DEFAULT, B_SEG0R_PPDU_LVL_MSK); + rtw89_phy_write32(rtwdev, reg, val); + } else { + rtw89_phy_write32(rtwdev, reg, hal->edcca_bak); + } +} diff --git a/drivers/net/wireless/realtek/rtw89/phy.h b/drivers/net/wireless/realtek/rtw89/phy.h index de0a9abf646e..7535867d0f48 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.h +++ b/drivers/net/wireless/realtek/rtw89/phy.h @@ -558,5 +558,6 @@ void rtw89_phy_ul_tb_ctrl_track(struct rtw89_dev *rtwdev); u8 rtw89_encode_chan_idx(struct rtw89_dev *rtwdev, u8 central_ch, u8 band); void rtw89_decode_chan_idx(struct rtw89_dev *rtwdev, u8 chan_idx, u8 *ch, enum nl80211_band *band); +void rtw89_phy_config_edcca(struct rtw89_dev *rtwdev, bool scan); #endif diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index c75aee61f383..37a1777a25a3 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -4280,6 +4280,11 @@ #define B_PKT_POP_EN BIT(8) #define R_SEG0R_PD 0x481C #define R_SEG0R_PD_V1 0x4860 +#define R_SEG0R_EDCCA_LVL 0x4840 +#define R_SEG0R_EDCCA_LVL_V1 0x4884 +#define B_SEG0R_PPDU_LVL_MSK GENMASK(31, 24) +#define B_SEG0R_EDCCA_LVL_P_MSK GENMASK(15, 8) +#define B_SEG0R_EDCCA_LVL_A_MSK GENMASK(7, 0) #define B_SEG0R_PD_SPATIAL_REUSE_EN_MSK_V1 BIT(30) #define B_SEG0R_PD_SPATIAL_REUSE_EN_MSK BIT(29) #define B_SEG0R_PD_LOWER_BOUND_MSK GENMASK(10, 6) diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c index e6f8df929a95..46907748778b 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c @@ -2149,6 +2149,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = { .rrsr_cfgs = &rtw8852a_rrsr_cfgs, .bss_clr_map_reg = R_BSS_CLR_MAP, .dma_ch_mask = 0, + .edcca_lvl_reg = R_SEG0R_EDCCA_LVL, #ifdef CONFIG_PM .wowlan_stub = &rtw_wowlan_stub_8852a, #endif diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c index 27733a3da6df..bae80984cfd5 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c @@ -2572,6 +2572,7 @@ const struct rtw89_chip_info rtw8852b_chip_info = { .dma_ch_mask = BIT(RTW89_DMA_ACH4) | BIT(RTW89_DMA_ACH5) | BIT(RTW89_DMA_ACH6) | BIT(RTW89_DMA_ACH7) | BIT(RTW89_DMA_B1MG) | BIT(RTW89_DMA_B1HI), + .edcca_lvl_reg = R_SEG0R_EDCCA_LVL_V1, }; EXPORT_SYMBOL(rtw8852b_chip_info); diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index a82bee5c8f0a..ba728fca9188 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -2885,6 +2885,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = { .rrsr_cfgs = &rtw8852c_rrsr_cfgs, .bss_clr_map_reg = R_BSS_CLR_MAP, .dma_ch_mask = 0, + .edcca_lvl_reg = R_SEG0R_EDCCA_LVL, #ifdef CONFIG_PM .wowlan_stub = &rtw_wowlan_stub_8852c, #endif From 47515664ecfbde11425dff121f298ae4499425c9 Mon Sep 17 00:00:00 2001 From: Ping-Ke Shih Date: Thu, 23 Mar 2023 16:28:39 +0800 Subject: [PATCH 34/37] wifi: rtw89: fix potential race condition between napi_init and napi_enable A race condition can happen if netdev is registered, but NAPI isn't initialized yet, and meanwhile user space starts the netdev that will enable NAPI. Then, it hits BUG_ON(): kernel BUG at net/core/dev.c:6423! invalid opcode: 0000 [#1] PREEMPT SMP NOPTI CPU: 0 PID: 417 Comm: iwd Not tainted 6.2.7-slab-dirty #3 eb0f5a8a9d91 Hardware name: LENOVO 21DL/LNVNB161216, BIOS JPCN20WW(V1.06) 09/20/2022 RIP: 0010:napi_enable+0x3f/0x50 Code: 48 89 c2 48 83 e2 f6 f6 81 89 08 00 00 02 74 0d 48 83 ... RSP: 0018:ffffada1414f3548 EFLAGS: 00010246 RAX: 0000000000000000 RBX: ffffa01425802080 RCX: 0000000000000000 RDX: 00000000000002ff RSI: ffffada14e50c614 RDI: ffffa01425808dc0 RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000001 R11: 0000000000000100 R12: ffffa01425808f58 R13: 0000000000000000 R14: ffffa01423498940 R15: 0000000000000001 FS: 00007f5577c0a740(0000) GS:ffffa0169fc00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f5577a19972 CR3: 0000000125a7a000 CR4: 0000000000750ef0 PKRU: 55555554 Call Trace: rtw89_pci_ops_start+0x1c/0x70 [rtw89_pci 6cbc75429515c181cbc386478d5cfb32ffc5a0f8] rtw89_core_start+0xbe/0x160 [rtw89_core fe07ecb874820b6d778370d4acb6ef8a37847f22] rtw89_ops_start+0x26/0x40 [rtw89_core fe07ecb874820b6d778370d4acb6ef8a37847f22] drv_start+0x42/0x100 [mac80211 c07fa22af8c3cf3f7d7ab3884ca990784d72e2d2] ieee80211_do_open+0x311/0x7d0 [mac80211 c07fa22af8c3cf3f7d7ab3884ca990784d72e2d2] ieee80211_open+0x6a/0x90 [mac80211 c07fa22af8c3cf3f7d7ab3884ca990784d72e2d2] __dev_open+0xe0/0x180 __dev_change_flags+0x1da/0x250 dev_change_flags+0x26/0x70 do_setlink+0x37c/0x12c0 ? ep_poll_callback+0x246/0x290 ? __nla_validate_parse+0x61/0xd00 ? __wake_up_common_lock+0x8f/0xd0 To fix this, follow Jonas' suggestion to switch the order of these functions and move register netdev to be the last step of PCI probe. Also, correct the error handling of rtw89_core_register_hw(). Fixes: e3ec7017f6a2 ("rtw89: add Realtek 802.11ax driver") Cc: stable@vger.kernel.org Reported-by: Hyeonggon Yoo <42.hyeyoo@gmail.com> Link: https://lore.kernel.org/linux-wireless/CAOiHx=n7EwK2B9CnBR07FVA=sEzFagb8TkS4XC_qBNq8OwcYUg@mail.gmail.com/T/#t Suggested-by: Jonas Gorski Tested-by: Larry Finger Reviewed-by: Larry Finger Signed-off-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230323082839.20474-1-pkshih@realtek.com --- drivers/net/wireless/realtek/rtw89/core.c | 10 +++++++--- drivers/net/wireless/realtek/rtw89/pci.c | 19 ++++++++++--------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index 0ec52a8b83b0..56a13be2e283 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -3455,18 +3455,22 @@ static int rtw89_core_register_hw(struct rtw89_dev *rtwdev) ret = ieee80211_register_hw(hw); if (ret) { rtw89_err(rtwdev, "failed to register hw\n"); - goto err; + goto err_free_supported_band; } ret = rtw89_regd_init(rtwdev, rtw89_regd_notifier); if (ret) { rtw89_err(rtwdev, "failed to init regd\n"); - goto err; + goto err_unregister_hw; } return 0; -err: +err_unregister_hw: + ieee80211_unregister_hw(hw); +err_free_supported_band: + rtw89_core_clr_supported_band(rtwdev); + return ret; } diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c index ec8bb5f10482..4025aabe0604 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.c +++ b/drivers/net/wireless/realtek/rtw89/pci.c @@ -3874,25 +3874,26 @@ int rtw89_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) rtw89_pci_link_cfg(rtwdev); rtw89_pci_l1ss_cfg(rtwdev); - ret = rtw89_core_register(rtwdev); - if (ret) { - rtw89_err(rtwdev, "failed to register core\n"); - goto err_clear_resource; - } - rtw89_core_napi_init(rtwdev); ret = rtw89_pci_request_irq(rtwdev, pdev); if (ret) { rtw89_err(rtwdev, "failed to request pci irq\n"); - goto err_unregister; + goto err_deinit_napi; + } + + ret = rtw89_core_register(rtwdev); + if (ret) { + rtw89_err(rtwdev, "failed to register core\n"); + goto err_free_irq; } return 0; -err_unregister: +err_free_irq: + rtw89_pci_free_irq(rtwdev, pdev); +err_deinit_napi: rtw89_core_napi_deinit(rtwdev); - rtw89_core_unregister(rtwdev); err_clear_resource: rtw89_pci_clear_resource(rtwdev, pdev); err_declaim_pci: From 5995f746310108b11c7e377b0ebac4c98e53f9dc Mon Sep 17 00:00:00 2001 From: Cai Huoqing Date: Thu, 23 Mar 2023 19:26:13 +0800 Subject: [PATCH 35/37] wifi: rtw89: Remove redundant pci_clear_master Remove pci_clear_master to simplify the code, the bus-mastering is also cleared in do_pci_disable_device, like this: ./drivers/pci/pci.c:2197 static void do_pci_disable_device(struct pci_dev *dev) { u16 pci_command; pci_read_config_word(dev, PCI_COMMAND, &pci_command); if (pci_command & PCI_COMMAND_MASTER) { pci_command &= ~PCI_COMMAND_MASTER; pci_write_config_word(dev, PCI_COMMAND, pci_command); } pcibios_disable_device(dev); }. And dev->is_busmaster is set to 0 in pci_disable_device. Signed-off-by: Cai Huoqing Reviewed-by: Simon Horman Acked-by: Ping-Ke Shih Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230323112613.7550-5-cai.huoqing@linux.dev --- drivers/net/wireless/realtek/rtw89/pci.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c index 4025aabe0604..68f0fed6d31e 100644 --- a/drivers/net/wireless/realtek/rtw89/pci.c +++ b/drivers/net/wireless/realtek/rtw89/pci.c @@ -2694,7 +2694,6 @@ static int rtw89_pci_claim_device(struct rtw89_dev *rtwdev, static void rtw89_pci_declaim_device(struct rtw89_dev *rtwdev, struct pci_dev *pdev) { - pci_clear_master(pdev); pci_disable_device(pdev); } From e83ce86aa7d914484038b181725718136387c7e1 Mon Sep 17 00:00:00 2001 From: Jiapeng Chong Date: Thu, 30 Mar 2023 10:18:41 +0800 Subject: [PATCH 36/37] wifi: b43legacy: Remove the unused function prev_slot() The function prev_slot is defined in the dma.c file, but not called elsewhere, so remove this unused function. drivers/net/wireless/broadcom/b43legacy/dma.c:130:19: warning: unused function 'prev_slot'. Reported-by: Abaci Robot Link: https://bugzilla.openanolis.cn/show_bug.cgi?id=4642 Signed-off-by: Jiapeng Chong Reviewed-by: Simon Horman Acked-by: Larry Finger Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230330021841.67724-1-jiapeng.chong@linux.alibaba.com --- drivers/net/wireless/broadcom/b43legacy/dma.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/net/wireless/broadcom/b43legacy/dma.c b/drivers/net/wireless/broadcom/b43legacy/dma.c index 6869f2bf1bae..60e41de72f29 100644 --- a/drivers/net/wireless/broadcom/b43legacy/dma.c +++ b/drivers/net/wireless/broadcom/b43legacy/dma.c @@ -127,14 +127,6 @@ static inline int next_slot(struct b43legacy_dmaring *ring, int slot) return slot + 1; } -static inline int prev_slot(struct b43legacy_dmaring *ring, int slot) -{ - B43legacy_WARN_ON(!(slot >= 0 && slot <= ring->nr_slots - 1)); - if (slot == 0) - return ring->nr_slots - 1; - return slot - 1; -} - #ifdef CONFIG_B43LEGACY_DEBUG static void update_max_used_slots(struct b43legacy_dmaring *ring, int current_used_slots) From cbef9a83c51dfcb07f77cfa6ac26f53a1ea86f49 Mon Sep 17 00:00:00 2001 From: Armin Wolf Date: Thu, 30 Mar 2023 23:56:37 +0200 Subject: [PATCH 37/37] wifi: rt2x00: Fix memory leak when handling surveys When removing a rt2x00 device, its associated channel surveys are not freed, causing a memory leak observable with kmemleak: unreferenced object 0xffff9620f0881a00 (size 512): comm "systemd-udevd", pid 2290, jiffies 4294906974 (age 33.768s) hex dump (first 32 bytes): 70 44 12 00 00 00 00 00 92 8a 00 00 00 00 00 00 pD.............. 00 00 00 00 00 00 00 00 ab 87 01 00 00 00 00 00 ................ backtrace: [] __kmalloc+0x4b/0x130 [] rt2800_probe_hw+0xc2b/0x1380 [rt2800lib] [] rt2800usb_probe_hw+0xe/0x60 [rt2800usb] [] rt2x00lib_probe_dev+0x21a/0x7d0 [rt2x00lib] [] rt2x00usb_probe+0x1be/0x980 [rt2x00usb] [] usb_probe_interface+0xe2/0x310 [usbcore] [] really_probe+0x1a5/0x410 [] __driver_probe_device+0x78/0x180 [] driver_probe_device+0x1e/0x90 [] __driver_attach+0xd2/0x1c0 [] bus_for_each_dev+0x77/0xd0 [] bus_add_driver+0x112/0x210 [] driver_register+0x5c/0x120 [] usb_register_driver+0x88/0x150 [usbcore] [] do_one_initcall+0x44/0x220 [] do_init_module+0x4c/0x220 Fix this by freeing the channel surveys on device removal. Tested with a RT3070 based USB wireless adapter. Fixes: 5447626910f5 ("rt2x00: save survey for every channel visited") Signed-off-by: Armin Wolf Reviewed-by: Simon Horman Acked-by: Stanislaw Gruszka Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230330215637.4332-1-W_Armin@gmx.de --- drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c index 3a035afcf7f9..9a9cfd0ce402 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c @@ -1091,6 +1091,7 @@ static void rt2x00lib_remove_hw(struct rt2x00_dev *rt2x00dev) } kfree(rt2x00dev->spec.channels_info); + kfree(rt2x00dev->chan_survey); } static const struct ieee80211_tpt_blink rt2x00_tpt_blink[] = {