From patchwork Mon Aug 28 13:09:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Berg X-Patchwork-Id: 719436 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 192AFC83F12 for ; Mon, 28 Aug 2023 13:10:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230334AbjH1NJk (ORCPT ); Mon, 28 Aug 2023 09:09:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48936 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230460AbjH1NJd (ORCPT ); Mon, 28 Aug 2023 09:09:33 -0400 Received: from sipsolutions.net (s3.sipsolutions.net [IPv6:2a01:4f8:242:246e::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6AB429D for ; Mon, 28 Aug 2023 06:09:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sipsolutions.net; s=mail; h=Content-Transfer-Encoding:MIME-Version: Message-ID:Date:Subject:Cc:To:From:Content-Type:Sender:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-To:Resent-Cc: Resent-Message-ID:In-Reply-To:References; bh=5yi49mfdGIOp96pkHby9afyXCFwBPcgol8l4fI6JCa8=; t=1693228170; x=1694437770; b=N8T4w3p941Nw5pTtED7JNO2IkkMag/H6mRe6KloRe8Lj7Wu5pnkxqge9zHPPLp3tISs09aDYfZw N4bSgUZYjFvZ77KVzj0UyGhxnPcniMRjrYzsHJJ9H/9276j3halz+fB55d5Qd5gXvCjv5Qw0r8x5t a7gFwt1rP3kCJ71twe3hYxiJHAthcDW+oNNPXddZ+DJ0ST9qWL9cWaLzLeb9JhfozNEilTgdDsAjv QSbiiRkgrWPqzlRtNU8KoWrVFR7NAWmXWU1cd5QNkwZ4RcBp/jPXOHCFI9kJSAZ9SH/mD/WJUCo9n 1g3kbGdTk66UXlcHOciU+fLSU7F7Fh/+NfGA==; Received: by sipsolutions.net with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.96) (envelope-from ) id 1qabzj-00Go8O-0x; Mon, 28 Aug 2023 15:09:27 +0200 From: Johannes Berg To: linux-wireless@vger.kernel.org Cc: Johannes Berg Subject: [PATCH v2 1/4] wifi: mac80211: tx: clarify conditions in if statement Date: Mon, 28 Aug 2023 15:09:23 +0200 Message-ID: <20230828150922.c5182ba79e0f.I5efd1399be8e6dedc1e48982b7f20c531ff37616@changeid> X-Mailer: git-send-email 2.41.0 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Johannes Berg This really just reformats the statement, but makes it more readable. Signed-off-by: Johannes Berg --- net/mac80211/tx.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 7fe7280e8437..3a5b41c2ee3d 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -2855,9 +2855,10 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata, goto free; } - if (unlikely(!multicast && ((skb->sk && - skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS) || - ctrl_flags & IEEE80211_TX_CTL_REQ_TX_STATUS))) + if (unlikely(!multicast && + ((skb->sk && + skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS) || + ctrl_flags & IEEE80211_TX_CTL_REQ_TX_STATUS))) info_id = ieee80211_store_ack_skb(local, skb, &info_flags, cookie); From patchwork Mon Aug 28 13:09:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Berg X-Patchwork-Id: 719435 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 52A43C83F16 for ; Mon, 28 Aug 2023 13:10:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230460AbjH1NJl (ORCPT ); Mon, 28 Aug 2023 09:09:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48938 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230453AbjH1NJd (ORCPT ); Mon, 28 Aug 2023 09:09:33 -0400 Received: from sipsolutions.net (s3.sipsolutions.net [IPv6:2a01:4f8:242:246e::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6AF58C9 for ; Mon, 28 Aug 2023 06:09:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sipsolutions.net; s=mail; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Content-Type:Sender :Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-To: Resent-Cc:Resent-Message-ID; bh=K3l1SoOeVInloWHUy2kLpcuc6jHWPWI+J78cuxI4C3c=; t=1693228170; x=1694437770; b=SHdE6ngmtPdv1mfbQBOrUUoVjl53BiS3dTa0W5/sc0VK4WT fSSVAzWa7YLQ3hUJz4nnCngKuX2N+mgj1eSlIBXvNNeaa0QES8/QX45UJUMCJyOLOnE4TtdYQOcDk eMudH6y4dN05bU7YwA0cqs71jAhNsoF86MxRXbeaCQZf141RH6vZYE52MtQzkWyPS+pcj1mlh3NmC bQBEcjFWpuwbxnS+kLdF0ZcBEbtDUqJGrK+XoMdQ/GXCrRUfp3gQsYXSnljEg6q4QOkKOjy7CKUGZ 9WLrzPiDJiPni+vMFkwUfKVfLcKOj4zrJYZp+Arq5Fl/o/wQqOjOw0+S6uRXwlOg==; Received: by sipsolutions.net with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.96) (envelope-from ) id 1qabzj-00Go8O-2z; Mon, 28 Aug 2023 15:09:28 +0200 From: Johannes Berg To: linux-wireless@vger.kernel.org Cc: Johannes Berg , Benjamin Berg , Ilan Peer Subject: [PATCH v2 2/4] wifi: mac80211: rework ack_frame_id handling a bit Date: Mon, 28 Aug 2023 15:09:24 +0200 Message-ID: <20230828150922.45c543acee45.If29e38f610e6c6ea667f77b6db7c4f0230d317f0@changeid> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230828150922.c5182ba79e0f.I5efd1399be8e6dedc1e48982b7f20c531ff37616@changeid> References: <20230828150922.c5182ba79e0f.I5efd1399be8e6dedc1e48982b7f20c531ff37616@changeid> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Johannes Berg Take one more free bit to indicate it's IDR vs. internal usage, to be able to carve out some bits here for other internal usage, other than IDR handling with a full ACK SKB, that is. Reviewed-by: Benjamin Berg Reviewed-by: Ilan Peer Signed-off-by: Johannes Berg --- include/net/mac80211.h | 9 ++++++--- net/mac80211/cfg.c | 3 ++- net/mac80211/ieee80211_i.h | 5 +++++ net/mac80211/status.c | 4 ++-- net/mac80211/tx.c | 14 ++++++++++---- 5 files changed, 25 insertions(+), 10 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 7c707358d15c..7f3b6f00f8a2 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1115,7 +1115,9 @@ ieee80211_rate_get_vht_nss(const struct ieee80211_tx_rate *rate) * not valid if the interface is an MLD since we won't know which * link the frame will be transmitted on * @hw_queue: HW queue to put the frame on, skb_get_queue_mapping() gives the AC - * @ack_frame_id: internal frame ID for TX status, used internally + * @status_data: internal data for TX status handling, assigned privately, + * see also &enum ieee80211_status_data for the internal documentation + * @status_data_idr: indicates status data is IDR allocated ID for ack frame * @tx_time_est: TX time estimate in units of 4us, used internally * @control: union part for control data * @control.rates: TX rates array to try @@ -1155,10 +1157,11 @@ struct ieee80211_tx_info { /* common information */ u32 flags; u32 band:3, - ack_frame_id:13, + status_data_idr:1, + status_data:13, hw_queue:4, tx_time_est:10; - /* 2 free bits */ + /* 1 free bit */ union { struct { diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 45e7a5d9c7d9..29a6da5ee77f 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -4034,7 +4034,8 @@ int ieee80211_attach_ack_skb(struct ieee80211_local *local, struct sk_buff *skb, return -ENOMEM; } - IEEE80211_SKB_CB(skb)->ack_frame_id = id; + IEEE80211_SKB_CB(skb)->status_data_idr = 1; + IEEE80211_SKB_CB(skb)->status_data = id; *cookie = ieee80211_mgmt_tx_cookie(local); IEEE80211_SKB_CB(ack_skb)->ack.cookie = *cookie; diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 06bd406846d2..7b74cf96ee0a 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -85,6 +85,11 @@ extern const u8 ieee80211_ac_to_qos_mask[IEEE80211_NUM_ACS]; #define IEEE80211_MAX_NAN_INSTANCE_ID 255 +enum ieee80211_status_data { + IEEE80211_STATUS_TYPE_MASK = 0x00f, + IEEE80211_STATUS_TYPE_INVALID = 0, + IEEE80211_STATUS_SUBDATA_MASK = 0xff0, +}; /* * Keep a station's queues on the active list for deficit accounting purposes diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 44d83da60aee..f24aceb59db0 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -633,7 +633,7 @@ static void ieee80211_report_ack_skb(struct ieee80211_local *local, unsigned long flags; spin_lock_irqsave(&local->ack_status_lock, flags); - skb = idr_remove(&local->ack_status_frames, info->ack_frame_id); + skb = idr_remove(&local->ack_status_frames, info->status_data); spin_unlock_irqrestore(&local->ack_status_lock, flags); if (!skb) @@ -759,7 +759,7 @@ static void ieee80211_report_used_skb(struct ieee80211_local *local, } rcu_read_unlock(); - } else if (info->ack_frame_id) { + } else if (info->status_data_idr) { ieee80211_report_ack_skb(local, skb, acked, dropped, ack_hwtstamp); } diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 3a5b41c2ee3d..ae33f727c6a8 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -2942,7 +2942,10 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata, memset(info, 0, sizeof(*info)); info->flags = info_flags; - info->ack_frame_id = info_id; + if (info_id) { + info->status_data = info_id; + info->status_data_idr = 1; + } info->band = band; if (likely(!cookie)) { @@ -4639,9 +4642,12 @@ static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata, } if (unlikely(skb->sk && - skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS)) - info->ack_frame_id = ieee80211_store_ack_skb(local, skb, - &info->flags, NULL); + skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS)) { + info->status_data = ieee80211_store_ack_skb(local, skb, + &info->flags, NULL); + if (info->status_data) + info->status_data_idr = 1; + } dev_sw_netstats_tx_add(dev, skbs, len); sta->deflink.tx_stats.packets[queue] += skbs; From patchwork Mon Aug 28 13:09:25 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Berg X-Patchwork-Id: 718182 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 32F94C83F11 for ; Mon, 28 Aug 2023 13:10:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231126AbjH1NJl (ORCPT ); Mon, 28 Aug 2023 09:09:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48954 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230474AbjH1NJd (ORCPT ); Mon, 28 Aug 2023 09:09:33 -0400 Received: from sipsolutions.net (s3.sipsolutions.net [IPv6:2a01:4f8:242:246e::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 03D37CC for ; Mon, 28 Aug 2023 06:09:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sipsolutions.net; s=mail; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Content-Type:Sender :Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-To: Resent-Cc:Resent-Message-ID; bh=yKvczykbCBbs1mw669eJ5ML0FkWfqshW9Tm/sR+WZF8=; t=1693228171; x=1694437771; b=UHRreAsZ/qJ8qMyXtCW2EZqWgW85t6yUKJVom6MMTZJeB68 yExoNjfHqosvdgCz+4ijNVep6yWSe3jEoKz1/Jbjt/bEjpjMIVsSVGCX3CItuuEaUBfnoowbxmsoQ GOTTJROvgiJiqmcowHxSSU+tPeXGHmMspomYbfEG8/0UJTAKOi8ssl5qArW3kqjkWZ72gJu9DQ0QO h74odw4AgcN36QW8K6+pSR5iIDnwNWOmjwAm9782jbGuhykFm2s1veMG1lkaiaBkI8aN7/ud9IpBL TnAJF0K4aXNbwiX4RYK3CzmRTVIF+kct9LKM7VqySf7fcpdocFea7yD9LlAxC1WA==; Received: by sipsolutions.net with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.96) (envelope-from ) id 1qabzk-00Go8O-1w; Mon, 28 Aug 2023 15:09:28 +0200 From: Johannes Berg To: linux-wireless@vger.kernel.org Cc: Ilan Peer Subject: [PATCH v2 3/4] wifi: mac80211: Fix SMPS handling in the context of MLO Date: Mon, 28 Aug 2023 15:09:25 +0200 Message-ID: <20230828150922.2cce9b20924e.Iaed8aaac30f599e030b9e9de5e868faaa2c1a0ab@changeid> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230828150922.c5182ba79e0f.I5efd1399be8e6dedc1e48982b7f20c531ff37616@changeid> References: <20230828150922.c5182ba79e0f.I5efd1399be8e6dedc1e48982b7f20c531ff37616@changeid> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Ilan Peer When the connection is a MLO connection, a SMPS request should be sent on a specific link, as SMPS is BSS specific, and the DA and BSSID used for the action frame transmission should be the AP MLD address, as the underlying driver is expected to perform the address translation (based on the link ID). Fix the SMPS request handling to use the AP MLD address and provide the link ID for the request processing during Tx. Signed-off-by: Ilan Peer Signed-off-by: Johannes Berg --- v2: fix the non-MLD case --- net/mac80211/cfg.c | 10 ++++++++-- net/mac80211/ht.c | 4 ++-- net/mac80211/ieee80211_i.h | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 29a6da5ee77f..fa20a260f9c8 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -3178,6 +3178,10 @@ int __ieee80211_request_smps_mgd(struct ieee80211_sub_if_data *sdata, if (WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION)) return -EINVAL; + if (ieee80211_vif_is_mld(&sdata->vif) && + !(sdata->vif.active_links & BIT(link->link_id))) + return 0; + old_req = link->u.mgd.req_smps; link->u.mgd.req_smps = smps_mode; @@ -3194,7 +3198,7 @@ int __ieee80211_request_smps_mgd(struct ieee80211_sub_if_data *sdata, link->conf->chandef.width == NL80211_CHAN_WIDTH_20_NOHT) return 0; - ap = link->u.mgd.bssid; + ap = sdata->vif.cfg.ap_addr; rcu_read_lock(); list_for_each_entry_rcu(sta, &sdata->local->sta_list, list) { @@ -3216,7 +3220,9 @@ int __ieee80211_request_smps_mgd(struct ieee80211_sub_if_data *sdata, /* send SM PS frame to AP */ err = ieee80211_send_smps_action(sdata, smps_mode, - ap, ap); + ap, ap, + ieee80211_vif_is_mld(&sdata->vif) ? + link->link_id : -1); if (err) link->u.mgd.req_smps = old_req; else if (smps_mode != IEEE80211_SMPS_OFF && tdls_peer_found) diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 33729870ad8a..802b0e738696 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c @@ -538,7 +538,7 @@ ieee80211_smps_mode_to_smps_mode(enum ieee80211_smps_mode smps) int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata, enum ieee80211_smps_mode smps, const u8 *da, - const u8 *bssid) + const u8 *bssid, int link_id) { struct ieee80211_local *local = sdata->local; struct sk_buff *skb; @@ -579,7 +579,7 @@ int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata, /* we'll do more on status of this frame */ IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; - ieee80211_tx_skb(sdata, skb); + ieee80211_tx_skb_tid(sdata, skb, 7, link_id); return 0; } diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 7b74cf96ee0a..1df2101d8eeb 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -2098,7 +2098,7 @@ void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata, u16 initiator, u16 reason_code); int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata, enum ieee80211_smps_mode smps, const u8 *da, - const u8 *bssid); + const u8 *bssid, int link_id); bool ieee80211_smps_is_restrictive(enum ieee80211_smps_mode smps_mode_old, enum ieee80211_smps_mode smps_mode_new); From patchwork Mon Aug 28 13:09:26 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Berg X-Patchwork-Id: 718181 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 61FADC83F15 for ; Mon, 28 Aug 2023 13:10:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231133AbjH1NJm (ORCPT ); Mon, 28 Aug 2023 09:09:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48958 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230195AbjH1NJe (ORCPT ); Mon, 28 Aug 2023 09:09:34 -0400 Received: from sipsolutions.net (s3.sipsolutions.net [IPv6:2a01:4f8:242:246e::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7209210C for ; Mon, 28 Aug 2023 06:09:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sipsolutions.net; s=mail; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Content-Type:Sender :Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-To: Resent-Cc:Resent-Message-ID; bh=AGij+/tdP1W0xDMsPVAbgLBhzGNQpIN2FNrFsUevKUc=; t=1693228171; x=1694437771; b=hhsjk3o56aHs27Do5NUyVchzX+yU8nCxOWwFpCjunUV1bOA ulTnmB5DelsNAHKiFieLmaFp4fnPl89jQ6HkCrBhxc/7MWhOM3rTCrDDRVmI5xH4zvtq7NehTvMuQ UCDV8vpZmoARSpv+Ag17eUqvqQyON85cEdpaxw2DSs7iwM41fXvGR9xYB+kmBWsKmnY39TyW/JIez rg59FJZA6krfd91Jik78e2qz/MUsYRSg2At+rEWAL2zdgspNhjW4j9JDWoc+StF8YEdC4xWNlUjiB iwzC9KodJtz7WM6TYFe08udAnFCiMdlEaTnCt1GUz/tEkkVZ9/GCQxG1bwVkYolw==; Received: by sipsolutions.net with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.96) (envelope-from ) id 1qabzl-00Go8O-0l; Mon, 28 Aug 2023 15:09:29 +0200 From: Johannes Berg To: linux-wireless@vger.kernel.org Cc: Johannes Berg Subject: [PATCH v2 4/4] wifi: mac80211: fix SMPS status handling Date: Mon, 28 Aug 2023 15:09:26 +0200 Message-ID: <20230828150922.86e74f4f47da.If8330b2c9441b5cb28f64d4814182207e89c5de2@changeid> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230828150922.c5182ba79e0f.I5efd1399be8e6dedc1e48982b7f20c531ff37616@changeid> References: <20230828150922.c5182ba79e0f.I5efd1399be8e6dedc1e48982b7f20c531ff37616@changeid> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Johannes Berg The current SMPS status handling isn't per link, so we only ever change the deflink, which is obviously wrong, it's not even used for multi-link connections, but the request API actually includes the link ID. Use the new status_data changes to move the handling to the right link, this also saves parsing the frame again on the status report, instead we can now check only if it was an SMPS frame. Of course, move the worker to be a wiphy work so that we're able to cancel it safely for the link. Signed-off-by: Johannes Berg --- net/mac80211/ht.c | 10 ++++- net/mac80211/ieee80211_i.h | 7 ++-- net/mac80211/iface.c | 11 ----- net/mac80211/mlme.c | 14 +++++++ net/mac80211/status.c | 86 ++++++++++++++++++++++---------------- 5 files changed, 78 insertions(+), 50 deletions(-) diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 802b0e738696..05f98f0a91a8 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c @@ -543,6 +543,8 @@ int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata, struct ieee80211_local *local = sdata->local; struct sk_buff *skb; struct ieee80211_mgmt *action_frame; + struct ieee80211_tx_info *info; + u8 status_link_id = link_id < 0 ? 0 : link_id; /* 27 = header + category + action + smps mode */ skb = dev_alloc_skb(27 + local->hw.extra_tx_headroom); @@ -562,6 +564,7 @@ int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata, case IEEE80211_SMPS_AUTOMATIC: case IEEE80211_SMPS_NUM_MODES: WARN_ON(1); + smps = IEEE80211_SMPS_OFF; fallthrough; case IEEE80211_SMPS_OFF: action_frame->u.action.u.ht_smps.smps_control = @@ -578,7 +581,12 @@ int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata, } /* we'll do more on status of this frame */ - IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; + info = IEEE80211_SKB_CB(skb); + info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; + /* we have 12 bits, and need 6: link_id 4, smps 2 */ + info->status_data = IEEE80211_STATUS_TYPE_SMPS | + u16_encode_bits(status_link_id << 2 | smps, + IEEE80211_STATUS_SUBDATA_MASK); ieee80211_tx_skb_tid(sdata, skb, 7, link_id); return 0; diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 1df2101d8eeb..338ab9e6e6b1 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -88,6 +88,7 @@ extern const u8 ieee80211_ac_to_qos_mask[IEEE80211_NUM_ACS]; enum ieee80211_status_data { IEEE80211_STATUS_TYPE_MASK = 0x00f, IEEE80211_STATUS_TYPE_INVALID = 0, + IEEE80211_STATUS_TYPE_SMPS = 1, IEEE80211_STATUS_SUBDATA_MASK = 0xff0, }; @@ -931,6 +932,9 @@ struct ieee80211_link_data_managed { struct wiphy_delayed_work chswitch_work; struct wiphy_work request_smps_work; + /* used to reconfigure hardware SM PS */ + struct wiphy_work recalc_smps; + bool beacon_crc_valid; u32 beacon_crc; struct ewma_beacon_signal ave_beacon_signal; @@ -1069,9 +1073,6 @@ struct ieee80211_sub_if_data { atomic_t num_tx_queued; struct mac80211_qos_map __rcu *qos_map; - /* used to reconfigure hardware SM PS */ - struct work_struct recalc_smps; - struct wiphy_work work; struct sk_buff_head skb_queue; struct sk_buff_head status_queue; diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index be586bc0b5b7..4beab027e0f9 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -518,8 +518,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do del_timer_sync(&local->dynamic_ps_timer); cancel_work_sync(&local->dynamic_ps_enable_work); - cancel_work_sync(&sdata->recalc_smps); - sdata_lock(sdata); WARN(ieee80211_vif_is_mld(&sdata->vif), "destroying interface with valid links 0x%04x\n", @@ -1692,14 +1690,6 @@ static void ieee80211_iface_work(struct wiphy *wiphy, struct wiphy_work *work) } } -static void ieee80211_recalc_smps_work(struct work_struct *work) -{ - struct ieee80211_sub_if_data *sdata = - container_of(work, struct ieee80211_sub_if_data, recalc_smps); - - ieee80211_recalc_smps(sdata, &sdata->deflink); -} - static void ieee80211_activate_links_work(struct work_struct *work) { struct ieee80211_sub_if_data *sdata = @@ -1745,7 +1735,6 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, skb_queue_head_init(&sdata->skb_queue); skb_queue_head_init(&sdata->status_queue); wiphy_work_init(&sdata->work, ieee80211_iface_work); - INIT_WORK(&sdata->recalc_smps, ieee80211_recalc_smps_work); INIT_WORK(&sdata->activate_links_work, ieee80211_activate_links_work); switch (type) { diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index f93eb38ae0b8..65d3e167132c 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -6847,6 +6847,16 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) ifmgd->orig_teardown_skb = NULL; } +static void ieee80211_recalc_smps_work(struct wiphy *wiphy, + struct wiphy_work *work) +{ + struct ieee80211_link_data *link = + container_of(work, struct ieee80211_link_data, + u.mgd.recalc_smps); + + ieee80211_recalc_smps(link->sdata, link); +} + void ieee80211_mgd_setup_link(struct ieee80211_link_data *link) { struct ieee80211_sub_if_data *sdata = link->sdata; @@ -6859,6 +6869,8 @@ void ieee80211_mgd_setup_link(struct ieee80211_link_data *link) wiphy_work_init(&link->u.mgd.request_smps_work, ieee80211_request_smps_mgd_work); + wiphy_work_init(&link->u.mgd.recalc_smps, + ieee80211_recalc_smps_work); if (local->hw.wiphy->features & NL80211_FEATURE_DYNAMIC_SMPS) link->u.mgd.req_smps = IEEE80211_SMPS_AUTOMATIC; else @@ -7824,6 +7836,8 @@ void ieee80211_mgd_stop_link(struct ieee80211_link_data *link) { wiphy_work_cancel(link->sdata->local->hw.wiphy, &link->u.mgd.request_smps_work); + wiphy_work_cancel(link->sdata->local->hw.wiphy, + &link->u.mgd.recalc_smps); wiphy_delayed_work_cancel(link->sdata->local->hw.wiphy, &link->u.mgd.chswitch_work); } diff --git a/net/mac80211/status.c b/net/mac80211/status.c index f24aceb59db0..3355e66d96d8 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -184,8 +184,6 @@ static void ieee80211_check_pending_bar(struct sta_info *sta, u8 *addr, u8 tid) static void ieee80211_frame_acked(struct sta_info *sta, struct sk_buff *skb) { struct ieee80211_mgmt *mgmt = (void *) skb->data; - struct ieee80211_local *local = sta->local; - struct ieee80211_sub_if_data *sdata = sta->sdata; if (ieee80211_is_data_qos(mgmt->frame_control)) { struct ieee80211_hdr *hdr = (void *) skb->data; @@ -194,39 +192,6 @@ static void ieee80211_frame_acked(struct sta_info *sta, struct sk_buff *skb) ieee80211_check_pending_bar(sta, hdr->addr1, tid); } - - if (ieee80211_is_action(mgmt->frame_control) && - !ieee80211_has_protected(mgmt->frame_control) && - mgmt->u.action.category == WLAN_CATEGORY_HT && - mgmt->u.action.u.ht_smps.action == WLAN_HT_ACTION_SMPS && - ieee80211_sdata_running(sdata)) { - enum ieee80211_smps_mode smps_mode; - - switch (mgmt->u.action.u.ht_smps.smps_control) { - case WLAN_HT_SMPS_CONTROL_DYNAMIC: - smps_mode = IEEE80211_SMPS_DYNAMIC; - break; - case WLAN_HT_SMPS_CONTROL_STATIC: - smps_mode = IEEE80211_SMPS_STATIC; - break; - case WLAN_HT_SMPS_CONTROL_DISABLED: - default: /* shouldn't happen since we don't send that */ - smps_mode = IEEE80211_SMPS_OFF; - break; - } - - if (sdata->vif.type == NL80211_IFTYPE_STATION) { - /* - * This update looks racy, but isn't -- if we come - * here we've definitely got a station that we're - * talking to, and on a managed interface that can - * only be the AP. And the only other place updating - * this variable in managed mode is before association. - */ - sdata->deflink.smps_mode = smps_mode; - ieee80211_queue_work(&local->hw, &sdata->recalc_smps); - } - } } static void ieee80211_set_bar_pending(struct sta_info *sta, u8 tid, u16 ssn) @@ -695,6 +660,42 @@ static void ieee80211_report_ack_skb(struct ieee80211_local *local, } } +static void ieee80211_handle_smps_status(struct ieee80211_sub_if_data *sdata, + bool acked, u16 status_data) +{ + u16 sub_data = u16_get_bits(status_data, IEEE80211_STATUS_SUBDATA_MASK); + enum ieee80211_smps_mode smps_mode = sub_data & 3; + int link_id = (sub_data >> 2); + struct ieee80211_link_data *link; + + if (!sdata || !ieee80211_sdata_running(sdata)) + return; + + if (!acked) + return; + + if (sdata->vif.type != NL80211_IFTYPE_STATION) + return; + + if (WARN(link_id >= ARRAY_SIZE(sdata->link), + "bad SMPS status link: %d\n", link_id)) + return; + + link = rcu_dereference(sdata->link[link_id]); + if (!link) + return; + + /* + * This update looks racy, but isn't, the only other place + * updating this variable is in managed mode before assoc, + * and we have to be associated to have a status from the + * action frame TX, since we cannot send it while we're not + * associated yet. + */ + link->smps_mode = smps_mode; + wiphy_work_queue(sdata->local->hw.wiphy, &link->u.mgd.recalc_smps); +} + static void ieee80211_report_used_skb(struct ieee80211_local *local, struct sk_buff *skb, bool dropped, ktime_t ack_hwtstamp) @@ -762,6 +763,21 @@ static void ieee80211_report_used_skb(struct ieee80211_local *local, } else if (info->status_data_idr) { ieee80211_report_ack_skb(local, skb, acked, dropped, ack_hwtstamp); + } else if (info->status_data) { + struct ieee80211_sub_if_data *sdata; + + rcu_read_lock(); + + sdata = ieee80211_sdata_from_skb(local, skb); + + switch (u16_get_bits(info->status_data, + IEEE80211_STATUS_TYPE_MASK)) { + case IEEE80211_STATUS_TYPE_SMPS: + ieee80211_handle_smps_status(sdata, acked, + info->status_data); + break; + } + rcu_read_unlock(); } if (!dropped && skb->destructor) {