From patchwork Fri Jan 10 04:24:43 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sarika Sharma X-Patchwork-Id: 13933572 X-Patchwork-Delegate: johannes@sipsolutions.net Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 515551A9B45 for ; Fri, 10 Jan 2025 04:26:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736483166; cv=none; b=X2NK4sjcGIJi6cDlkDhgVKvJWGRA4ddeQAIalrkSrYVdw++ilKHf70rS5fFWmrlnhCFED+9wIrUVZnt4AV2nb7lZbqhs2sufNRnxnoBqdjv0JYcPpWYymc6vaKD1Nfvck2kGVMOZ5wbNhazmPn6YCRWqGpXP8h96RGTJxvdh+hc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736483166; c=relaxed/simple; bh=GtJJFv2ylSC+Pd8toYf/1flIiSDr3CAuhuc+em+1KYA=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=dNn/RUim4ZvrB8Fg9Goxe3bzZGjW+6mLV8Ta9mMjqgsYs8YbYTcBKqLWnFy3w5b8FiUA1bYkG7Co96aM19caG6mSzeKcQ1zgC4tf/utEVvLpECPYr1xoUnURMN7IXs18h1bxqM4VfZbmQh9kzAZog9cVt3oajOiu6txb7ZYjT3w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=Dp+buXkG; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="Dp+buXkG" Received: from pps.filterd (m0279873.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 50A3bt6X002805; Fri, 10 Jan 2025 04:25:40 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= FScCncM5aHAye7plWUiuIdHgnyFBit14vPGmKG6sVcI=; b=Dp+buXkGECCsojcE MDGwBJwvn4YVOkI7/4qbPIB8m2d53p+Iarf1qC0mWhEtebDR2XBD3fE9bcQaYgPD MS0xhAJKeG87qKu+PLRxTAn+H0aVPK40mUXU/MHketorXT3u5DRU2QIIzOIQGcT9 KC6G0SVhqXgzg1aiy6QAM9GIZYfIT2hdLbRVK/AOgriT9ZbZDvDPVKPDB8S+vSdA Hlyw3Igx3FRc1K0THvgI9SesLyJVRW1A3BgdsSvjLThd3uF3TbazJ0cyt9KBiAo6 Bq/7fs/cTAaqeq5p7hXUpMWbnn1bf4+RGtrne4RJ+gyZyhej/C4fH9d7bOs5eXah gBEgQQ== Received: from nasanppmta03.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 442uteg2ku-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jan 2025 04:25:39 +0000 (GMT) Received: from nasanex01c.na.qualcomm.com (nasanex01c.na.qualcomm.com [10.45.79.139]) by NASANPPMTA03.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id 50A4Pc1a002027 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jan 2025 04:25:38 GMT Received: from hu-sarishar-blr.qualcomm.com (10.80.80.8) by nasanex01c.na.qualcomm.com (10.45.79.139) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.9; Thu, 9 Jan 2025 20:25:37 -0800 From: Sarika Sharma To: CC: , Sarika Sharma Subject: [PATCH RFC 1/7] wifi: cfg80211: reorg sinfo structure elements for mesh Date: Fri, 10 Jan 2025 09:54:43 +0530 Message-ID: <20250110042449.1158789-2-quic_sarishar@quicinc.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250110042449.1158789-1-quic_sarishar@quicinc.com> References: <20250110042449.1158789-1-quic_sarishar@quicinc.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nasanex01c.na.qualcomm.com (10.45.79.139) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: 7EGuG7fcQdMGkNBKWB7T9j8VgnCmxTq6 X-Proofpoint-ORIG-GUID: 7EGuG7fcQdMGkNBKWB7T9j8VgnCmxTq6 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.60.29 definitions=2024-09-06_09,2024-09-06_01,2024-09-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 spamscore=0 mlxlogscore=999 lowpriorityscore=0 adultscore=0 bulkscore=0 impostorscore=0 suspectscore=0 mlxscore=0 phishscore=0 malwarescore=0 priorityscore=1501 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2411120000 definitions=main-2501100034 Currently, as multi-link operation(MLO) is not supported for mesh, reorganize the sinfo structure for mesh-specific fields and introduce the sta_set_mesh_sinfo() API to populate these fields. This will allow for the simplified reorganization of sinfo structure for link level in a subsequent patch to add support for MLO station statistics. No functionality changes added. Pahole summary before the reorg of sinfo structure: - size: 256, cachelines: 4, members: 50 - sum members: 239, holes: 4, sum holes: 17 - paddings: 2, sum paddings: 2 - forced alignments: 1, forced holes: 1, sum forced holes: 1 Pahole summary after the reorg of sinfo structure: - size: 248, cachelines: 4, members: 50 - sum members: 239, holes: 4, sum holes: 9 - paddings: 2, sum paddings: 2 - forced alignments: 1, last cacheline: 56 bytes Signed-off-by: Sarika Sharma --- include/net/cfg80211.h | 43 ++++++++++++++------------- net/mac80211/sta_info.c | 64 ++++++++++++++++++++++------------------- net/wireless/nl80211.c | 11 +++---- 3 files changed, 62 insertions(+), 56 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 7790af534b7f..77f72a46ce42 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -2045,9 +2045,6 @@ struct cfg80211_tid_stats { * @assoc_at: bootime (ns) of the last association * @rx_bytes: bytes (size of MPDUs) received from this station * @tx_bytes: bytes (size of MPDUs) transmitted to this station - * @llid: mesh local link id - * @plid: mesh peer link id - * @plink_state: mesh peer link state * @signal: The signal strength, type depends on the wiphy's signal_type. * For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_. * @signal_avg: Average signal strength, type depends on the wiphy's signal_type. @@ -2067,14 +2064,20 @@ struct cfg80211_tid_stats { * This number should increase every time the list of stations * changes, i.e. when a station is added or removed, so that * userspace can tell whether it got a consistent snapshot. + * @beacon_loss_count: Number of times beacon loss event has triggered. * @assoc_req_ies: IEs from (Re)Association Request. * This is used only when in AP mode with drivers that do not use * user space MLME/SME implementation. The information is provided for * the cfg80211_new_sta() calls to notify user space of the IEs. * @assoc_req_ies_len: Length of assoc_req_ies buffer in octets. * @sta_flags: station flags mask & values - * @beacon_loss_count: Number of times beacon loss event has triggered. * @t_offset: Time offset of the station relative to this host. + * @llid: mesh local link id + * @plid: mesh peer link id + * @plink_state: mesh peer link state + * @connected_to_gate: true if mesh STA has a path to mesh gate + * @connected_to_as: true if mesh STA has a path to authentication server + * @airtime_link_metric: mesh airtime link metric. * @local_pm: local mesh STA power save mode * @peer_pm: peer mesh STA power save mode * @nonpeer_pm: non-peer mesh STA power save mode @@ -2083,7 +2086,6 @@ struct cfg80211_tid_stats { * @rx_beacon: number of beacons received from this peer * @rx_beacon_signal_avg: signal strength average (in dBm) for beacons received * from this peer - * @connected_to_gate: true if mesh STA has a path to mesh gate * @rx_duration: aggregate PPDU duration(usecs) for all the frames from a peer * @tx_duration: aggregate PPDU duration(usecs) for all the frames to a peer * @airtime_weight: current airtime scheduling weight @@ -2097,8 +2099,6 @@ struct cfg80211_tid_stats { * @fcs_err_count: number of packets (MPDUs) received from this station with * an FCS error. This counter should be incremented only when TA of the * received packet with an FCS error matches the peer MAC address. - * @airtime_link_metric: mesh airtime link metric. - * @connected_to_as: true if mesh STA has a path to authentication server * @mlo_params_valid: Indicates @assoc_link_id and @mld_addr fields are filled * by driver. Drivers use this only in cfg80211_new_sta() calls when AP * MLD's MLME/SME is offload to driver. Drivers won't fill this @@ -2125,9 +2125,6 @@ struct station_info { u64 assoc_at; u64 rx_bytes; u64 tx_bytes; - u16 llid; - u16 plid; - u8 plink_state; s8 signal; s8 signal_avg; @@ -2147,36 +2144,38 @@ struct station_info { int generation; + u32 beacon_loss_count; + const u8 *assoc_req_ies; size_t assoc_req_ies_len; - u32 beacon_loss_count; s64 t_offset; + u16 llid; + u16 plid; + u8 plink_state; + u8 connected_to_gate; + u8 connected_to_as; + u32 airtime_link_metric; enum nl80211_mesh_power_mode local_pm; enum nl80211_mesh_power_mode peer_pm; enum nl80211_mesh_power_mode nonpeer_pm; u32 expected_throughput; - u64 tx_duration; - u64 rx_duration; - u64 rx_beacon; - u8 rx_beacon_signal_avg; - u8 connected_to_gate; + u16 airtime_weight; - struct cfg80211_tid_stats *pertid; s8 ack_signal; s8 avg_ack_signal; + struct cfg80211_tid_stats *pertid; - u16 airtime_weight; + u64 tx_duration; + u64 rx_duration; + u64 rx_beacon; + u8 rx_beacon_signal_avg; u32 rx_mpdu_count; u32 fcs_err_count; - u32 airtime_link_metric; - - u8 connected_to_as; - bool mlo_params_valid; u8 assoc_link_id; u8 mld_addr[ETH_ALEN] __aligned(2); diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index aa22f09e6d14..53f8da74fb99 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -2563,6 +2563,39 @@ static inline u64 sta_get_stats_bytes(struct ieee80211_sta_rx_stats *rxstats) return value; } +#ifdef CONFIG_MAC80211_MESH +static void sta_set_mesh_sinfo(struct sta_info *sta, + struct station_info *sinfo) +{ + struct ieee80211_local *local = sta->sdata->local; + + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_LLID) | + BIT_ULL(NL80211_STA_INFO_PLID) | + BIT_ULL(NL80211_STA_INFO_PLINK_STATE) | + BIT_ULL(NL80211_STA_INFO_LOCAL_PM) | + BIT_ULL(NL80211_STA_INFO_PEER_PM) | + BIT_ULL(NL80211_STA_INFO_NONPEER_PM) | + BIT_ULL(NL80211_STA_INFO_CONNECTED_TO_GATE) | + BIT_ULL(NL80211_STA_INFO_CONNECTED_TO_AS); + + sinfo->llid = sta->mesh->llid; + sinfo->plid = sta->mesh->plid; + sinfo->plink_state = sta->mesh->plink_state; + if (test_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN)) { + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_T_OFFSET); + sinfo->t_offset = sta->mesh->t_offset; + } + sinfo->local_pm = sta->mesh->local_pm; + sinfo->peer_pm = sta->mesh->peer_pm; + sinfo->nonpeer_pm = sta->mesh->nonpeer_pm; + sinfo->connected_to_gate = sta->mesh->connected_to_gate; + sinfo->connected_to_as = sta->mesh->connected_to_as; + + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_AIRTIME_LINK_METRIC); + sinfo->airtime_link_metric = airtime_link_metric_get(local, sta); +} +#endif + void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo, bool tidstats) { @@ -2747,31 +2780,10 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo, sta_set_tidstats(sta, &sinfo->pertid[i], i); } - if (ieee80211_vif_is_mesh(&sdata->vif)) { #ifdef CONFIG_MAC80211_MESH - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_LLID) | - BIT_ULL(NL80211_STA_INFO_PLID) | - BIT_ULL(NL80211_STA_INFO_PLINK_STATE) | - BIT_ULL(NL80211_STA_INFO_LOCAL_PM) | - BIT_ULL(NL80211_STA_INFO_PEER_PM) | - BIT_ULL(NL80211_STA_INFO_NONPEER_PM) | - BIT_ULL(NL80211_STA_INFO_CONNECTED_TO_GATE) | - BIT_ULL(NL80211_STA_INFO_CONNECTED_TO_AS); - - sinfo->llid = sta->mesh->llid; - sinfo->plid = sta->mesh->plid; - sinfo->plink_state = sta->mesh->plink_state; - if (test_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN)) { - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_T_OFFSET); - sinfo->t_offset = sta->mesh->t_offset; - } - sinfo->local_pm = sta->mesh->local_pm; - sinfo->peer_pm = sta->mesh->peer_pm; - sinfo->nonpeer_pm = sta->mesh->nonpeer_pm; - sinfo->connected_to_gate = sta->mesh->connected_to_gate; - sinfo->connected_to_as = sta->mesh->connected_to_as; + if (ieee80211_vif_is_mesh(&sdata->vif)) + sta_set_mesh_sinfo(sta, sinfo); #endif - } sinfo->bss_param.flags = 0; if (sdata->vif.bss_conf.use_cts_prot) @@ -2827,12 +2839,6 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo, sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL_AVG); } - - if (ieee80211_vif_is_mesh(&sdata->vif)) { - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_AIRTIME_LINK_METRIC); - sinfo->airtime_link_metric = - airtime_link_metric_get(local, sta); - } } u32 sta_get_expected_throughput(struct sta_info *sta) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 8789d8b73f0f..d90033e03dd6 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -6726,9 +6726,6 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid, PUT_SINFO_U64(RX_BYTES64, rx_bytes); PUT_SINFO_U64(TX_BYTES64, tx_bytes); - PUT_SINFO(LLID, llid, u16); - PUT_SINFO(PLID, plid, u16); - PUT_SINFO(PLINK_STATE, plink_state, u8); PUT_SINFO_U64(RX_DURATION, rx_duration); PUT_SINFO_U64(TX_DURATION, tx_duration); @@ -6772,13 +6769,18 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid, PUT_SINFO(TX_RETRIES, tx_retries, u32); PUT_SINFO(TX_FAILED, tx_failed, u32); PUT_SINFO(EXPECTED_THROUGHPUT, expected_throughput, u32); - PUT_SINFO(AIRTIME_LINK_METRIC, airtime_link_metric, u32); PUT_SINFO(BEACON_LOSS, beacon_loss_count, u32); + + PUT_SINFO(LLID, llid, u16); + PUT_SINFO(PLID, plid, u16); + PUT_SINFO(PLINK_STATE, plink_state, u8); + PUT_SINFO(AIRTIME_LINK_METRIC, airtime_link_metric, u32); PUT_SINFO(LOCAL_PM, local_pm, u32); PUT_SINFO(PEER_PM, peer_pm, u32); PUT_SINFO(NONPEER_PM, nonpeer_pm, u32); PUT_SINFO(CONNECTED_TO_GATE, connected_to_gate, u8); PUT_SINFO(CONNECTED_TO_AS, connected_to_as, u8); + PUT_SINFO_U64(T_OFFSET, t_offset); if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_BSS_PARAM)) { bss_param = nla_nest_start_noflag(msg, @@ -6806,7 +6808,6 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid, &sinfo->sta_flags)) goto nla_put_failure; - PUT_SINFO_U64(T_OFFSET, t_offset); PUT_SINFO_U64(RX_DROP_MISC, rx_dropped_misc); PUT_SINFO_U64(BEACON_RX, rx_beacon); PUT_SINFO(BEACON_SIGNAL_AVG, rx_beacon_signal_avg, u8); From patchwork Fri Jan 10 04:24:44 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sarika Sharma X-Patchwork-Id: 13933570 X-Patchwork-Delegate: johannes@sipsolutions.net Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CBCF5126C10 for ; Fri, 10 Jan 2025 04:25:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736483163; cv=none; b=a3eRRvrW8/AGVJ6T2q8WUYVXqBz4KH+Qreuar/vHq45tSCW6IxMcC/vRhtcPr9mpRxWZDYwwH4H27lvXz27dSrzEPRjHYo48TNFU9Dtl/q16pHpCiYzr46Ij7sGDmzBs6LNHQhf36JVZho3CwNAhLUyC/Ih6fZrvuLCvGdnBxBg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736483163; c=relaxed/simple; bh=bRZK4yWiGqo5PzkqGihN/wSBRWYOfwsos9YSBhGd5QU=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=DjRE1rp99ufqO/H5WEV+/6/0kbr4gMIFIdyhqnSUEPH9vm2xbWDWTX3J4o4sD+UvA53Qf1GuS18YZAG6H7EFG01UA2rdfHfycr5NfwtcEaFC2CVwItQEo5RA4wMhUX6P5EVaiDBYS1fFdh//IdzNgE9uccjWllySXffkfhqhc6A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=UfpPjfa7; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="UfpPjfa7" Received: from pps.filterd (m0279871.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 509FrxZk007709; Fri, 10 Jan 2025 04:25:42 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= h7PTceYHEJ8FwagAljsHcvcMtUscLCt6Jw8RbJqWz3Q=; b=UfpPjfa76hdEGIYh dVARt4Hkuj4JF4wdbVvy1ytY2NyKrj5/ISVUKza+VQO9IZmLQ2qEQhuOx+7hVbGj H8K+lXGk8+1GCUKHdKqUei2AbNInTOWHitl5J/NZas2y4rVSwE0peVVPgQP0cCbk 3b5vN+w37SX+4sMLKDAZa6mMlbSdwklXmVhJ1CaLCJtDDYZISC6+nCYGdkIciDh+ C5xyOLyabX51covObqLzPn+yP47GIHeSDnWg3aEpZtOmYQRv6OEC/DmrKZcrWSKb XXf+YWimmw+KSyzspIWELusWLC6QAdJQY6lpKkFmlB0mKCd7u1qS8FTgZe8nF+Ns u5Bkcw== Received: from nasanppmta01.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 442hgg1gxy-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jan 2025 04:25:41 +0000 (GMT) Received: from nasanex01c.na.qualcomm.com (nasanex01c.na.qualcomm.com [10.45.79.139]) by NASANPPMTA01.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id 50A4Pex5028032 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jan 2025 04:25:40 GMT Received: from hu-sarishar-blr.qualcomm.com (10.80.80.8) by nasanex01c.na.qualcomm.com (10.45.79.139) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.9; Thu, 9 Jan 2025 20:25:38 -0800 From: Sarika Sharma To: CC: , Sarika Sharma Subject: [PATCH RFC 2/7] wifi: cfg80211: reorg sinfo structure elements for MLO Date: Fri, 10 Jan 2025 09:54:44 +0530 Message-ID: <20250110042449.1158789-3-quic_sarishar@quicinc.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250110042449.1158789-1-quic_sarishar@quicinc.com> References: <20250110042449.1158789-1-quic_sarishar@quicinc.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nasanex01c.na.qualcomm.com (10.45.79.139) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: bGSc6RjH0VI9pivgyhUHEea31KUbr8R6 X-Proofpoint-ORIG-GUID: bGSc6RjH0VI9pivgyhUHEea31KUbr8R6 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.60.29 definitions=2024-09-06_09,2024-09-06_01,2024-09-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 clxscore=1015 mlxscore=0 priorityscore=1501 suspectscore=0 malwarescore=0 spamscore=0 phishscore=0 mlxlogscore=999 adultscore=0 bulkscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2411120000 definitions=main-2501100034 Current implementation of NL80211_GET_STATION does not work for multi-link operation(MLO) since in case of MLO only deflink (or one of the links) is considered and not all links. Therefore to support for MLO, start reorganizing sinfo structure related data elements and add link_sinfo structure for link-level statistics and keep station related data at sinfo structure. Currently, changes are done at the deflink level. Actual link-level changes will be added in subsequent changes. Also currently, mac80211 ops .sta_statistics() is mapped to fill sinfo structure. But to add support for station statistics at link level, change the ops to .link_sta_statistics() to fill link_sinfo structure. NOTE: - Currently this patch is not-bisectable, once RFC patches are approved could add other required driver changes. - Have included ath12k driver changes as an example that could be used as reference for other drivers. Signed-off-by: Sarika Sharma --- drivers/net/wireless/ath/ath12k/mac.c | 42 ++-- include/net/cfg80211.h | 165 +++++++++------- include/net/mac80211.h | 18 +- net/mac80211/driver-ops.h | 14 +- net/mac80211/ethtool.c | 30 +-- net/mac80211/sta_info.c | 251 ++++++++++++----------- net/mac80211/trace.h | 2 +- net/wireless/nl80211.c | 273 +++++++++++++++----------- net/wireless/trace.h | 33 ++-- net/wireless/util.c | 10 +- net/wireless/wext-compat.c | 22 +-- 11 files changed, 469 insertions(+), 391 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index c4eab4c1c10e..ebde8a604eec 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -9896,10 +9896,10 @@ static int ath12k_mac_op_get_survey(struct ieee80211_hw *hw, int idx, return 0; } -static void ath12k_mac_op_sta_statistics(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - struct station_info *sinfo) +static void ath12k_mac_op_link_sta_statistics(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct link_station_info *link_sinfo) { struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(sta); struct ath12k_link_sta *arsta; @@ -9908,31 +9908,31 @@ static void ath12k_mac_op_sta_statistics(struct ieee80211_hw *hw, arsta = &ahsta->deflink; - sinfo->rx_duration = arsta->rx_duration; - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_DURATION); + link_sinfo->rx_duration = arsta->rx_duration; + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_DURATION); - sinfo->tx_duration = arsta->tx_duration; - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_DURATION); + link_sinfo->tx_duration = arsta->tx_duration; + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_DURATION); if (!arsta->txrate.legacy && !arsta->txrate.nss) return; if (arsta->txrate.legacy) { - sinfo->txrate.legacy = arsta->txrate.legacy; + link_sinfo->txrate.legacy = arsta->txrate.legacy; } else { - sinfo->txrate.mcs = arsta->txrate.mcs; - sinfo->txrate.nss = arsta->txrate.nss; - sinfo->txrate.bw = arsta->txrate.bw; - sinfo->txrate.he_gi = arsta->txrate.he_gi; - sinfo->txrate.he_dcm = arsta->txrate.he_dcm; - sinfo->txrate.he_ru_alloc = arsta->txrate.he_ru_alloc; + link_sinfo->txrate.mcs = arsta->txrate.mcs; + link_sinfo->txrate.nss = arsta->txrate.nss; + link_sinfo->txrate.bw = arsta->txrate.bw; + link_sinfo->txrate.he_gi = arsta->txrate.he_gi; + link_sinfo->txrate.he_dcm = arsta->txrate.he_dcm; + link_sinfo->txrate.he_ru_alloc = arsta->txrate.he_ru_alloc; } - sinfo->txrate.flags = arsta->txrate.flags; - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); + link_sinfo->txrate.flags = arsta->txrate.flags; + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); /* TODO: Use real NF instead of default one. */ - sinfo->signal = arsta->rssi_comb + ATH12K_DEFAULT_NOISE_FLOOR; - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL); + link_sinfo->signal = arsta->rssi_comb + ATH12K_DEFAULT_NOISE_FLOOR; + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL); } static int ath12k_mac_op_cancel_remain_on_channel(struct ieee80211_hw *hw, @@ -10177,7 +10177,7 @@ static const struct ieee80211_ops ath12k_ops = { .set_bitrate_mask = ath12k_mac_op_set_bitrate_mask, .get_survey = ath12k_mac_op_get_survey, .flush = ath12k_mac_op_flush, - .sta_statistics = ath12k_mac_op_sta_statistics, + .link_sta_statistics = ath12k_mac_op_link_sta_statistics, .remain_on_channel = ath12k_mac_op_remain_on_channel, .cancel_remain_on_channel = ath12k_mac_op_cancel_remain_on_channel, .change_sta_links = ath12k_mac_op_change_sta_links, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 77f72a46ce42..ba3e7e72ab5d 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -2034,17 +2034,18 @@ struct cfg80211_tid_stats { #define IEEE80211_MAX_CHAINS 4 /** - * struct station_info - station information + * struct link_station_info - link station information * - * Station information filled by driver for get_station() and dump_station. + * Link station information filled by driver for get_station() and dump_station. * + * @link_id: Link ID uniquely identifying the link STA. This is -1 for non-ML * @filled: bitflag of flags using the bits of &enum nl80211_sta_info to * indicate the relevant values in this struct for them - * @connected_time: time(in secs) since a station is last connected - * @inactive_time: time since last station activity (tx/rx) in milliseconds - * @assoc_at: bootime (ns) of the last association - * @rx_bytes: bytes (size of MPDUs) received from this station - * @tx_bytes: bytes (size of MPDUs) transmitted to this station + * @connected_time: time(in secs) since a link station is last connected + * @inactive_time: time since last link station activity (tx/rx) in milliseconds + * @assoc_at: bootime (ns) of the last link station association + * @rx_bytes: bytes (size of MPDUs) received from this link station + * @tx_bytes: bytes (size of MPDUs) transmitted to this link station * @signal: The signal strength, type depends on the wiphy's signal_type. * For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_. * @signal_avg: Average signal strength, type depends on the wiphy's signal_type. @@ -2052,19 +2053,95 @@ struct cfg80211_tid_stats { * @chains: bitmask for filled values in @chain_signal, @chain_signal_avg * @chain_signal: per-chain signal strength of last received packet in dBm * @chain_signal_avg: per-chain signal strength average in dBm - * @txrate: current unicast bitrate from this station - * @rxrate: current unicast bitrate to this station - * @rx_packets: packets (MSDUs & MMPDUs) received from this station - * @tx_packets: packets (MSDUs & MMPDUs) transmitted to this station + * @txrate: current unicast bitrate from this link station + * @rxrate: current unicast bitrate to this link station + * @rx_packets: packets (MSDUs & MMPDUs) received from this link station + * @tx_packets: packets (MSDUs & MMPDUs) transmitted to thislink station * @tx_retries: cumulative retry counts (MPDUs) * @tx_failed: number of failed transmissions (MPDUs) (retries exceeded, no ACK) * @rx_dropped_misc: Dropped for un-specified reason. * @bss_param: current BSS parameters + * @beacon_loss_count: Number of times beacon loss event has triggered. + * @expected_throughput: expected throughput in kbps (including 802.11 headers) + * towards this link station. + * @rx_beacon: number of beacons received from this peer + * @rx_beacon_signal_avg: signal strength average (in dBm) for beacons received + * from this peer + * @rx_duration: aggregate PPDU duration(usecs) for all the frames from a peer + * @tx_duration: aggregate PPDU duration(usecs) for all the frames to a peer + * @airtime_weight: current airtime scheduling weight + * @pertid: per-TID statistics, see &struct cfg80211_tid_stats, using the last + * (IEEE80211_NUM_TIDS) index for MSDUs not encapsulated in QoS-MPDUs. + * Note that this doesn't use the @filled bit, but is used if non-NULL. + * @ack_signal: signal strength (in dBm) of the last ACK frame. + * @avg_ack_signal: average rssi value of ack packet for the no of msdu's has + * been sent. + * @rx_mpdu_count: number of MPDUs received from this link station + * @fcs_err_count: number of packets (MPDUs) received from this link station with + * an FCS error. This counter should be incremented only when TA of the + * received packet with an FCS error matches the peer MAC address. + * @addr: For MLO STA connection, filled with address of the link station. + * For non-MLO STA connection, filled with all zeros. + */ +struct link_station_info { + int link_id; + u64 filled; + u32 connected_time; + u32 inactive_time; + u64 assoc_at; + u64 rx_bytes; + u64 tx_bytes; + s8 signal; + s8 signal_avg; + + u8 chains; + s8 chain_signal[IEEE80211_MAX_CHAINS]; + s8 chain_signal_avg[IEEE80211_MAX_CHAINS]; + + struct rate_info txrate; + struct rate_info rxrate; + u32 rx_packets; + u32 tx_packets; + u32 tx_retries; + u32 tx_failed; + u32 rx_dropped_misc; + struct sta_bss_parameters bss_param; + + u32 beacon_loss_count; + + u32 expected_throughput; + + u64 tx_duration; + u64 rx_duration; + u64 rx_beacon; + u8 rx_beacon_signal_avg; + + u16 airtime_weight; + + s8 ack_signal; + s8 avg_ack_signal; + struct cfg80211_tid_stats *pertid; + + u32 rx_mpdu_count; + u32 fcs_err_count; + + u8 addr[ETH_ALEN] __aligned(2); +}; + +/** + * struct station_info - station information + * + * Station information filled by driver for get_station() and dump_station. + * + * @filled: bitflag of flags using the bits of &enum nl80211_sta_info to + * indicate the relevant values in this struct for them + * @connected_time: time(in secs) since a station is last connected + * @assoc_at: bootime (ns) of the last association + * @sta_flags: station flags mask & values * @generation: generation number for nl80211 dumps. * This number should increase every time the list of stations * changes, i.e. when a station is added or removed, so that * userspace can tell whether it got a consistent snapshot. - * @beacon_loss_count: Number of times beacon loss event has triggered. * @assoc_req_ies: IEs from (Re)Association Request. * This is used only when in AP mode with drivers that do not use * user space MLME/SME implementation. The information is provided for @@ -2081,24 +2158,6 @@ struct cfg80211_tid_stats { * @local_pm: local mesh STA power save mode * @peer_pm: peer mesh STA power save mode * @nonpeer_pm: non-peer mesh STA power save mode - * @expected_throughput: expected throughput in kbps (including 802.11 headers) - * towards this station. - * @rx_beacon: number of beacons received from this peer - * @rx_beacon_signal_avg: signal strength average (in dBm) for beacons received - * from this peer - * @rx_duration: aggregate PPDU duration(usecs) for all the frames from a peer - * @tx_duration: aggregate PPDU duration(usecs) for all the frames to a peer - * @airtime_weight: current airtime scheduling weight - * @pertid: per-TID statistics, see &struct cfg80211_tid_stats, using the last - * (IEEE80211_NUM_TIDS) index for MSDUs not encapsulated in QoS-MPDUs. - * Note that this doesn't use the @filled bit, but is used if non-NULL. - * @ack_signal: signal strength (in dBm) of the last ACK frame. - * @avg_ack_signal: average rssi value of ack packet for the no of msdu's has - * been sent. - * @rx_mpdu_count: number of MPDUs received from this station - * @fcs_err_count: number of packets (MPDUs) received from this station with - * an FCS error. This counter should be incremented only when TA of the - * received packet with an FCS error matches the peer MAC address. * @mlo_params_valid: Indicates @assoc_link_id and @mld_addr fields are filled * by driver. Drivers use this only in cfg80211_new_sta() calls when AP * MLD's MLME/SME is offload to driver. Drivers won't fill this @@ -2117,35 +2176,17 @@ struct cfg80211_tid_stats { * dump_station() callbacks. User space needs this information to determine * the accepted and rejected affiliated links of the connected station. * @assoc_resp_ies_len: Length of @assoc_resp_ies buffer in octets. + * @deflink: This holds the default link STA information, for non MLO STA + * all link specific STA information is accessed through @deflink. */ struct station_info { u64 filled; u32 connected_time; - u32 inactive_time; u64 assoc_at; - u64 rx_bytes; - u64 tx_bytes; - s8 signal; - s8 signal_avg; - - u8 chains; - s8 chain_signal[IEEE80211_MAX_CHAINS]; - s8 chain_signal_avg[IEEE80211_MAX_CHAINS]; - - struct rate_info txrate; - struct rate_info rxrate; - u32 rx_packets; - u32 tx_packets; - u32 tx_retries; - u32 tx_failed; - u32 rx_dropped_misc; - struct sta_bss_parameters bss_param; struct nl80211_sta_flag_update sta_flags; int generation; - u32 beacon_loss_count; - const u8 *assoc_req_ies; size_t assoc_req_ies_len; @@ -2160,27 +2201,13 @@ struct station_info { enum nl80211_mesh_power_mode peer_pm; enum nl80211_mesh_power_mode nonpeer_pm; - u32 expected_throughput; - - u16 airtime_weight; - - s8 ack_signal; - s8 avg_ack_signal; - struct cfg80211_tid_stats *pertid; - - u64 tx_duration; - u64 rx_duration; - u64 rx_beacon; - u8 rx_beacon_signal_avg; - - u32 rx_mpdu_count; - u32 fcs_err_count; - bool mlo_params_valid; u8 assoc_link_id; u8 mld_addr[ETH_ALEN] __aligned(2); const u8 *assoc_resp_ies; size_t assoc_resp_ies_len; + + struct link_station_info deflink; }; /** @@ -8429,12 +8456,12 @@ void cfg80211_tx_mgmt_expired(struct wireless_dev *wdev, u64 cookie, /** * cfg80211_sinfo_alloc_tid_stats - allocate per-tid statistics. * - * @sinfo: the station information + * @link_sinfo: the station information * @gfp: allocation flags * * Return: 0 on success. Non-zero on error. */ -int cfg80211_sinfo_alloc_tid_stats(struct station_info *sinfo, gfp_t gfp); +int cfg80211_sinfo_alloc_tid_stats(struct link_station_info *link_sinfo, gfp_t gfp); /** * cfg80211_sinfo_release_content - release contents of station info @@ -8446,7 +8473,7 @@ int cfg80211_sinfo_alloc_tid_stats(struct station_info *sinfo, gfp_t gfp); */ static inline void cfg80211_sinfo_release_content(struct station_info *sinfo) { - kfree(sinfo->pertid); + kfree(sinfo->deflink.pertid); } /** diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 9320d4bc22ee..ea62d223a0e4 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -4106,11 +4106,11 @@ struct ieee80211_prep_tx_info { * is only used if the configured rate control algorithm actually uses * the new rate table API, and is therefore optional. Must be atomic. * - * @sta_statistics: Get statistics for this station. For example with beacon - * filtering, the statistics kept by mac80211 might not be accurate, so - * let the driver pre-fill the statistics. The driver can fill most of - * the values (indicating which by setting the filled bitmap), but not - * all of them make sense - see the source for which ones are possible. + * @link_sta_statistics: Get statistics for this link station. For example + * with beacon filtering, the statistics kept by mac80211 might not be + * accurate, so let the driver pre-fill the statistics. The driver can + * fill most of the values (indicating which by setting the filled bitmap), + * but not all of them make sense - see the source for which ones are possible. * Statistics that the driver doesn't fill will be filled by mac80211. * The callback can sleep. * @@ -4593,10 +4593,10 @@ struct ieee80211_ops { void (*sta_rate_tbl_update)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta); - void (*sta_statistics)(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - struct station_info *sinfo); + void (*link_sta_statistics)(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct link_station_info *link_sinfo); int (*conf_tx)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, unsigned int link_id, u16 ac, diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index c64531e0a60e..33365870ce86 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -613,10 +613,10 @@ static inline void drv_sta_rate_tbl_update(struct ieee80211_local *local, trace_drv_return_void(local); } -static inline void drv_sta_statistics(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata, - struct ieee80211_sta *sta, - struct station_info *sinfo) +static inline void drv_link_sta_statistics(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + struct ieee80211_sta *sta, + struct link_station_info *link_sinfo) { might_sleep(); lockdep_assert_wiphy(local->hw.wiphy); @@ -625,9 +625,9 @@ static inline void drv_sta_statistics(struct ieee80211_local *local, if (!check_sdata_in_driver(sdata)) return; - trace_drv_sta_statistics(local, sdata, sta); - if (local->ops->sta_statistics) - local->ops->sta_statistics(&local->hw, &sdata->vif, sta, sinfo); + trace_drv_link_sta_statistics(local, sdata, sta); + if (local->ops->link_sta_statistics) + local->ops->link_sta_statistics(&local->hw, &sdata->vif, sta, link_sinfo); trace_drv_return_void(local); } diff --git a/net/mac80211/ethtool.c b/net/mac80211/ethtool.c index 42f7ee142ce3..172e0c4659de 100644 --- a/net/mac80211/ethtool.c +++ b/net/mac80211/ethtool.c @@ -79,6 +79,7 @@ static void ieee80211_get_stats(struct net_device *dev, struct sta_info *sta; struct ieee80211_local *local = sdata->local; struct station_info sinfo; + struct link_station_info *link_sinfo; struct survey_info survey; int i, q; #define STA_STATS_SURVEY_LEN 7 @@ -87,17 +88,16 @@ static void ieee80211_get_stats(struct net_device *dev, #define ADD_STA_STATS(sta) \ do { \ - data[i++] += sinfo.rx_packets; \ - data[i++] += sinfo.rx_bytes; \ + data[i++] += link_sinfo->rx_packets; \ + data[i++] += link_sinfo->rx_bytes; \ data[i++] += (sta)->rx_stats.num_duplicates; \ data[i++] += (sta)->rx_stats.fragments; \ - data[i++] += sinfo.rx_dropped_misc; \ - \ - data[i++] += sinfo.tx_packets; \ - data[i++] += sinfo.tx_bytes; \ + data[i++] += link_sinfo->rx_dropped_misc; \ + data[i++] += link_sinfo->tx_packets; \ + data[i++] += link_sinfo->tx_bytes; \ data[i++] += (sta)->status_stats.filtered; \ - data[i++] += sinfo.tx_failed; \ - data[i++] += sinfo.tx_retries; \ + data[i++] += link_sinfo->tx_failed; \ + data[i++] += link_sinfo->tx_retries; \ } while (0) /* For Managed stations, find the single station based on BSSID @@ -117,23 +117,24 @@ static void ieee80211_get_stats(struct net_device *dev, memset(&sinfo, 0, sizeof(sinfo)); sta_set_sinfo(sta, &sinfo, false); + link_sinfo = &sinfo.deflink; i = 0; ADD_STA_STATS(&sta->deflink); data[i++] = sta->sta_state; - if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_TX_BITRATE)) + if (link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_BITRATE)) data[i] = 100000ULL * - cfg80211_calculate_bitrate(&sinfo.txrate); + cfg80211_calculate_bitrate(&link_sinfo->txrate); i++; - if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_RX_BITRATE)) + if (link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_BITRATE)) data[i] = 100000ULL * - cfg80211_calculate_bitrate(&sinfo.rxrate); + cfg80211_calculate_bitrate(&link_sinfo->rxrate); i++; - if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG)) - data[i] = (u8)sinfo.signal_avg; + if (link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG)) + data[i] = (u8)link_sinfo->signal_avg; i++; } else { list_for_each_entry(sta, &local->sta_list, list) { @@ -143,6 +144,7 @@ static void ieee80211_get_stats(struct net_device *dev, memset(&sinfo, 0, sizeof(sinfo)); sta_set_sinfo(sta, &sinfo, false); + link_sinfo = &sinfo.deflink; i = 0; ADD_STA_STATS(&sta->deflink); } diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 53f8da74fb99..985e53bf04bc 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -2596,204 +2596,231 @@ static void sta_set_mesh_sinfo(struct sta_info *sta, } #endif -void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo, - bool tidstats) +static void sta_set_link_sinfo(struct sta_info *sta, struct link_station_info *link_sinfo, + struct ieee80211_link_data *link_sdata, bool tidstats) { struct ieee80211_sub_if_data *sdata = sta->sdata; struct ieee80211_local *local = sdata->local; u32 thr = 0; int i, ac, cpu; struct ieee80211_sta_rx_stats *last_rxstats; + struct link_sta_info *link_sta_info = &sta->deflink; last_rxstats = sta_get_last_rx_stats(sta); - sinfo->generation = sdata->local->sta_generation; /* do before driver, so beacon filtering drivers have a * chance to e.g. just add the number of filtered beacons * (or just modify the value entirely, of course) */ if (sdata->vif.type == NL80211_IFTYPE_STATION) - sinfo->rx_beacon = sdata->deflink.u.mgd.count_beacon_signal; + link_sinfo->rx_beacon = link_sdata->u.mgd.count_beacon_signal; - drv_sta_statistics(local, sdata, &sta->sta, sinfo); - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_INACTIVE_TIME) | - BIT_ULL(NL80211_STA_INFO_STA_FLAGS) | + drv_link_sta_statistics(local, sdata, &sta->sta, link_sinfo); + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_INACTIVE_TIME) | BIT_ULL(NL80211_STA_INFO_BSS_PARAM) | - BIT_ULL(NL80211_STA_INFO_CONNECTED_TIME) | - BIT_ULL(NL80211_STA_INFO_ASSOC_AT_BOOTTIME) | BIT_ULL(NL80211_STA_INFO_RX_DROP_MISC); if (sdata->vif.type == NL80211_IFTYPE_STATION) { - sinfo->beacon_loss_count = - sdata->deflink.u.mgd.beacon_loss_count; - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_BEACON_LOSS); + link_sinfo->beacon_loss_count = + link_sdata->u.mgd.beacon_loss_count; + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_BEACON_LOSS); } - sinfo->connected_time = ktime_get_seconds() - sta->last_connected; - sinfo->assoc_at = sta->assoc_at; - sinfo->inactive_time = + link_sinfo->inactive_time = jiffies_to_msecs(jiffies - ieee80211_sta_last_active(sta)); - if (!(sinfo->filled & (BIT_ULL(NL80211_STA_INFO_TX_BYTES64) | + if (!(link_sinfo->filled & (BIT_ULL(NL80211_STA_INFO_TX_BYTES64) | BIT_ULL(NL80211_STA_INFO_TX_BYTES)))) { - sinfo->tx_bytes = 0; + link_sinfo->tx_bytes = 0; for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) - sinfo->tx_bytes += sta->deflink.tx_stats.bytes[ac]; - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES64); + link_sinfo->tx_bytes += link_sta_info->tx_stats.bytes[ac]; + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES64); } - if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_PACKETS))) { - sinfo->tx_packets = 0; + if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_PACKETS))) { + link_sinfo->tx_packets = 0; for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) - sinfo->tx_packets += sta->deflink.tx_stats.packets[ac]; - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS); + link_sinfo->tx_packets += link_sta_info->tx_stats.packets[ac]; + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS); } - if (!(sinfo->filled & (BIT_ULL(NL80211_STA_INFO_RX_BYTES64) | + if (!(link_sinfo->filled & (BIT_ULL(NL80211_STA_INFO_RX_BYTES64) | BIT_ULL(NL80211_STA_INFO_RX_BYTES)))) { - sinfo->rx_bytes += sta_get_stats_bytes(&sta->deflink.rx_stats); + link_sinfo->rx_bytes += sta_get_stats_bytes(&link_sta_info->rx_stats); - if (sta->deflink.pcpu_rx_stats) { + if (link_sta_info->pcpu_rx_stats) { for_each_possible_cpu(cpu) { struct ieee80211_sta_rx_stats *cpurxs; - cpurxs = per_cpu_ptr(sta->deflink.pcpu_rx_stats, + cpurxs = per_cpu_ptr(link_sta_info->pcpu_rx_stats, cpu); - sinfo->rx_bytes += sta_get_stats_bytes(cpurxs); + link_sinfo->rx_bytes += sta_get_stats_bytes(cpurxs); } } - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BYTES64); + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BYTES64); } - if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_PACKETS))) { - sinfo->rx_packets = sta->deflink.rx_stats.packets; - if (sta->deflink.pcpu_rx_stats) { + if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_PACKETS))) { + link_sinfo->rx_packets = link_sta_info->rx_stats.packets; + if (link_sta_info->pcpu_rx_stats) { for_each_possible_cpu(cpu) { struct ieee80211_sta_rx_stats *cpurxs; - cpurxs = per_cpu_ptr(sta->deflink.pcpu_rx_stats, + cpurxs = per_cpu_ptr(link_sta_info->pcpu_rx_stats, cpu); - sinfo->rx_packets += cpurxs->packets; + link_sinfo->rx_packets += cpurxs->packets; } } - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_PACKETS); + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_PACKETS); } - if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_RETRIES))) { - sinfo->tx_retries = sta->deflink.status_stats.retry_count; - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES); + if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_RETRIES))) { + link_sinfo->tx_retries = link_sta_info->status_stats.retry_count; + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES); } - if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_FAILED))) { - sinfo->tx_failed = sta->deflink.status_stats.retry_failed; - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); + if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_FAILED))) { + link_sinfo->tx_failed = link_sta_info->status_stats.retry_failed; + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); } - if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_DURATION))) { + if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_DURATION))) { for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) - sinfo->rx_duration += sta->airtime[ac].rx_airtime; - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_DURATION); + link_sinfo->rx_duration += sta->airtime[ac].rx_airtime; + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_DURATION); } - if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_DURATION))) { + if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_DURATION))) { for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) - sinfo->tx_duration += sta->airtime[ac].tx_airtime; - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_DURATION); + link_sinfo->tx_duration += sta->airtime[ac].tx_airtime; + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_DURATION); } - if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_AIRTIME_WEIGHT))) { - sinfo->airtime_weight = sta->airtime_weight; - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_AIRTIME_WEIGHT); + if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_AIRTIME_WEIGHT))) { + link_sinfo->airtime_weight = sta->airtime_weight; + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_AIRTIME_WEIGHT); } - sinfo->rx_dropped_misc = sta->deflink.rx_stats.dropped; - if (sta->deflink.pcpu_rx_stats) { + link_sinfo->rx_dropped_misc = link_sta_info->rx_stats.dropped; + if (link_sta_info->pcpu_rx_stats) { for_each_possible_cpu(cpu) { struct ieee80211_sta_rx_stats *cpurxs; - cpurxs = per_cpu_ptr(sta->deflink.pcpu_rx_stats, cpu); - sinfo->rx_dropped_misc += cpurxs->dropped; + cpurxs = per_cpu_ptr(link_sta_info->pcpu_rx_stats, cpu); + link_sinfo->rx_dropped_misc += cpurxs->dropped; } } if (sdata->vif.type == NL80211_IFTYPE_STATION && !(sdata->vif.driver_flags & IEEE80211_VIF_BEACON_FILTER)) { - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_BEACON_RX) | + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_BEACON_RX) | BIT_ULL(NL80211_STA_INFO_BEACON_SIGNAL_AVG); - sinfo->rx_beacon_signal_avg = ieee80211_ave_rssi(&sdata->vif); + link_sinfo->rx_beacon_signal_avg = ieee80211_ave_rssi(&sdata->vif); } if (ieee80211_hw_check(&sta->local->hw, SIGNAL_DBM) || ieee80211_hw_check(&sta->local->hw, SIGNAL_UNSPEC)) { - if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_SIGNAL))) { - sinfo->signal = (s8)last_rxstats->last_signal; - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL); + if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_SIGNAL))) { + link_sinfo->signal = (s8)last_rxstats->last_signal; + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL); } - if (!sta->deflink.pcpu_rx_stats && - !(sinfo->filled & BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG))) { - sinfo->signal_avg = - -ewma_signal_read(&sta->deflink.rx_stats_avg.signal); - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); + if (!link_sta_info->pcpu_rx_stats && + !(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG))) { + link_sinfo->signal_avg = + -ewma_signal_read(&link_sta_info->rx_stats_avg.signal); + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); } } /* for the average - if pcpu_rx_stats isn't set - rxstats must point to - * the sta->rx_stats struct, so the check here is fine with and without + * the link_sta_info->rx_stats struct, so the check here is fine with and without * pcpu statistics */ if (last_rxstats->chains && - !(sinfo->filled & (BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL) | + !(link_sinfo->filled & (BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL) | BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG)))) { - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL); - if (!sta->deflink.pcpu_rx_stats) - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG); + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL); + if (!link_sta_info->pcpu_rx_stats) + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG); + link_sinfo->chains = last_rxstats->chains; - sinfo->chains = last_rxstats->chains; - - for (i = 0; i < ARRAY_SIZE(sinfo->chain_signal); i++) { - sinfo->chain_signal[i] = + for (i = 0; i < ARRAY_SIZE(link_sinfo->chain_signal); i++) { + link_sinfo->chain_signal[i] = last_rxstats->chain_signal_last[i]; - sinfo->chain_signal_avg[i] = - -ewma_signal_read(&sta->deflink.rx_stats_avg.chain_signal[i]); + link_sinfo->chain_signal_avg[i] = + -ewma_signal_read(&link_sta_info->rx_stats_avg.chain_signal[i]); } } - if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_BITRATE)) && + if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_BITRATE)) && !sta->sta.valid_links && - ieee80211_rate_valid(&sta->deflink.tx_stats.last_rate)) { - sta_set_rate_info_tx(sta, &sta->deflink.tx_stats.last_rate, - &sinfo->txrate); - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); + ieee80211_rate_valid(&link_sta_info->tx_stats.last_rate)) { + sta_set_rate_info_tx(sta, &link_sta_info->tx_stats.last_rate, + &link_sinfo->txrate); + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); } - if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_BITRATE)) && - !sta->sta.valid_links) { - if (sta_set_rate_info_rx(sta, &sinfo->rxrate) == 0) - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BITRATE); + if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_BITRATE)) && + !sta->sta.valid_links){ + if (sta_set_rate_info_rx(sta, &link_sinfo->rxrate) == 0) + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BITRATE); } - if (tidstats && !cfg80211_sinfo_alloc_tid_stats(sinfo, GFP_KERNEL)) { + if (tidstats && !cfg80211_sinfo_alloc_tid_stats(link_sinfo, GFP_KERNEL)) { for (i = 0; i < IEEE80211_NUM_TIDS + 1; i++) - sta_set_tidstats(sta, &sinfo->pertid[i], i); + sta_set_tidstats(sta, &link_sinfo->pertid[i], i); } -#ifdef CONFIG_MAC80211_MESH - if (ieee80211_vif_is_mesh(&sdata->vif)) - sta_set_mesh_sinfo(sta, sinfo); -#endif + link_sinfo->bss_param.flags = 0; + if (link_sdata->conf->use_cts_prot) + link_sinfo->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT; + if (link_sdata->conf->use_short_preamble) + link_sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE; + if (link_sdata->conf->use_short_slot) + link_sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME; + link_sinfo->bss_param.dtim_period = link_sdata->conf->dtim_period; + link_sinfo->bss_param.beacon_interval = link_sdata->conf->beacon_int; + + thr = sta_get_expected_throughput(sta); + + if (thr != 0) { + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_EXPECTED_THROUGHPUT); + link_sinfo->expected_throughput = thr; + } + + if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL)) && + link_sta_info->status_stats.ack_signal_filled) { + link_sinfo->ack_signal = link_sta_info->status_stats.last_ack_signal; + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL); + } + + if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL_AVG)) && + link_sta_info->status_stats.ack_signal_filled) { + link_sinfo->avg_ack_signal = + -(s8)ewma_avg_signal_read(&link_sta_info->status_stats.avg_ack_signal); + link_sinfo->filled |= + BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL_AVG); + } +} - sinfo->bss_param.flags = 0; - if (sdata->vif.bss_conf.use_cts_prot) - sinfo->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT; - if (sdata->vif.bss_conf.use_short_preamble) - sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE; - if (sdata->vif.bss_conf.use_short_slot) - sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME; - sinfo->bss_param.dtim_period = sdata->vif.bss_conf.dtim_period; - sinfo->bss_param.beacon_interval = sdata->vif.bss_conf.beacon_int; +void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo, + bool tidstats) +{ + struct ieee80211_sub_if_data *sdata = sta->sdata; + struct link_station_info *link_sinfo = &sinfo->deflink; + struct ieee80211_link_data *link_sdata = &sdata->deflink; + + sinfo->generation = sdata->local->sta_generation; + + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_STA_FLAGS) | + BIT_ULL(NL80211_STA_INFO_CONNECTED_TIME) | + BIT_ULL(NL80211_STA_INFO_ASSOC_AT_BOOTTIME); + + sinfo->connected_time = ktime_get_seconds() - sta->last_connected; + sinfo->assoc_at = sta->assoc_at; sinfo->sta_flags.set = 0; sinfo->sta_flags.mask = BIT(NL80211_STA_FLAG_AUTHORIZED) | @@ -2803,6 +2830,7 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo, BIT(NL80211_STA_FLAG_AUTHENTICATED) | BIT(NL80211_STA_FLAG_ASSOCIATED) | BIT(NL80211_STA_FLAG_TDLS_PEER); + if (test_sta_flag(sta, WLAN_STA_AUTHORIZED)) sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHORIZED); if (test_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE)) @@ -2818,27 +2846,12 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo, if (test_sta_flag(sta, WLAN_STA_TDLS_PEER)) sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER); - thr = sta_get_expected_throughput(sta); - - if (thr != 0) { - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_EXPECTED_THROUGHPUT); - sinfo->expected_throughput = thr; - } - - if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL)) && - sta->deflink.status_stats.ack_signal_filled) { - sinfo->ack_signal = sta->deflink.status_stats.last_ack_signal; - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL); - } +#ifdef CONFIG_MAC80211_MESH + if (ieee80211_vif_is_mesh(&sdata->vif)) + sta_set_mesh_sinfo(sta, sinfo); +#endif - if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL_AVG)) && - sta->deflink.status_stats.ack_signal_filled) { - sinfo->avg_ack_signal = - -(s8)ewma_avg_signal_read( - &sta->deflink.status_stats.avg_ack_signal); - sinfo->filled |= - BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL_AVG); - } + sta_set_link_sinfo(sta, link_sinfo, link_sdata, tidstats); } u32 sta_get_expected_throughput(struct sta_info *sta) diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index dc35fed7e9b0..1477506c76d6 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h @@ -995,7 +995,7 @@ DECLARE_EVENT_CLASS(sta_event, ) ); -DEFINE_EVENT(sta_event, drv_sta_statistics, +DEFINE_EVENT(sta_event, drv_link_sta_statistics, TP_PROTO(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata, struct ieee80211_sta *sta), diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index d90033e03dd6..7740ab5c778d 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -6670,185 +6670,151 @@ static bool nl80211_put_signal(struct sk_buff *msg, u8 mask, s8 *signal, return true; } -static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid, - u32 seq, int flags, - struct cfg80211_registered_device *rdev, - struct net_device *dev, - const u8 *mac_addr, struct station_info *sinfo) +static int nl80211_fill_link_station(struct sk_buff *msg, + struct cfg80211_registered_device *rdev, + struct link_station_info *link_sinfo) { - void *hdr; - struct nlattr *sinfoattr, *bss_param; + struct nlattr *bss_param; - hdr = nl80211hdr_put(msg, portid, seq, flags, cmd); - if (!hdr) { - cfg80211_sinfo_release_content(sinfo); - return -1; - } - - if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || - nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) || - nla_put_u32(msg, NL80211_ATTR_GENERATION, sinfo->generation)) - goto nla_put_failure; - - sinfoattr = nla_nest_start_noflag(msg, NL80211_ATTR_STA_INFO); - if (!sinfoattr) - goto nla_put_failure; - -#define PUT_SINFO(attr, memb, type) do { \ +#define PUT_LINK_SINFO(attr, memb, type) do { \ BUILD_BUG_ON(sizeof(type) == sizeof(u64)); \ - if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_ ## attr) && \ + if (link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_ ## attr) && \ nla_put_ ## type(msg, NL80211_STA_INFO_ ## attr, \ - sinfo->memb)) \ - goto nla_put_failure; \ + link_sinfo->memb)) \ + return -EMSGSIZE; \ } while (0) -#define PUT_SINFO_U64(attr, memb) do { \ - if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_ ## attr) && \ +#define PUT_LINK_SINFO_U64(attr, memb) do { \ + if (link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_ ## attr) && \ nla_put_u64_64bit(msg, NL80211_STA_INFO_ ## attr, \ - sinfo->memb, NL80211_STA_INFO_PAD)) \ - goto nla_put_failure; \ + link_sinfo->memb, NL80211_STA_INFO_PAD)) \ + return -EMSGSIZE; \ } while (0) - PUT_SINFO(CONNECTED_TIME, connected_time, u32); - PUT_SINFO(INACTIVE_TIME, inactive_time, u32); - PUT_SINFO_U64(ASSOC_AT_BOOTTIME, assoc_at); + PUT_LINK_SINFO(CONNECTED_TIME, connected_time, u32); + PUT_LINK_SINFO(INACTIVE_TIME, inactive_time, u32); + PUT_LINK_SINFO_U64(ASSOC_AT_BOOTTIME, assoc_at); - if (sinfo->filled & (BIT_ULL(NL80211_STA_INFO_RX_BYTES) | - BIT_ULL(NL80211_STA_INFO_RX_BYTES64)) && + if (link_sinfo->filled & (BIT_ULL(NL80211_STA_INFO_RX_BYTES) | + BIT_ULL(NL80211_STA_INFO_RX_BYTES64)) && nla_put_u32(msg, NL80211_STA_INFO_RX_BYTES, - (u32)sinfo->rx_bytes)) - goto nla_put_failure; + (u32)link_sinfo->rx_bytes)) + return -EMSGSIZE; - if (sinfo->filled & (BIT_ULL(NL80211_STA_INFO_TX_BYTES) | - BIT_ULL(NL80211_STA_INFO_TX_BYTES64)) && + if (link_sinfo->filled & (BIT_ULL(NL80211_STA_INFO_TX_BYTES) | + BIT_ULL(NL80211_STA_INFO_TX_BYTES64)) && nla_put_u32(msg, NL80211_STA_INFO_TX_BYTES, - (u32)sinfo->tx_bytes)) - goto nla_put_failure; + (u32)link_sinfo->tx_bytes)) + return -EMSGSIZE; - PUT_SINFO_U64(RX_BYTES64, rx_bytes); - PUT_SINFO_U64(TX_BYTES64, tx_bytes); - PUT_SINFO_U64(RX_DURATION, rx_duration); - PUT_SINFO_U64(TX_DURATION, tx_duration); + PUT_LINK_SINFO_U64(RX_BYTES64, rx_bytes); + PUT_LINK_SINFO_U64(TX_BYTES64, tx_bytes); + PUT_LINK_SINFO_U64(RX_DURATION, rx_duration); + PUT_LINK_SINFO_U64(TX_DURATION, tx_duration); if (wiphy_ext_feature_isset(&rdev->wiphy, NL80211_EXT_FEATURE_AIRTIME_FAIRNESS)) - PUT_SINFO(AIRTIME_WEIGHT, airtime_weight, u16); + PUT_LINK_SINFO(AIRTIME_WEIGHT, airtime_weight, u16); switch (rdev->wiphy.signal_type) { case CFG80211_SIGNAL_TYPE_MBM: - PUT_SINFO(SIGNAL, signal, u8); - PUT_SINFO(SIGNAL_AVG, signal_avg, u8); + PUT_LINK_SINFO(SIGNAL, signal, u8); + PUT_LINK_SINFO(SIGNAL_AVG, signal_avg, u8); break; default: break; } - if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL)) { - if (!nl80211_put_signal(msg, sinfo->chains, - sinfo->chain_signal, + if (link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL)) { + if (!nl80211_put_signal(msg, link_sinfo->chains, + link_sinfo->chain_signal, NL80211_STA_INFO_CHAIN_SIGNAL)) - goto nla_put_failure; + return -EMSGSIZE; } - if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG)) { - if (!nl80211_put_signal(msg, sinfo->chains, - sinfo->chain_signal_avg, + if (link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG)) { + if (!nl80211_put_signal(msg, link_sinfo->chains, + link_sinfo->chain_signal_avg, NL80211_STA_INFO_CHAIN_SIGNAL_AVG)) - goto nla_put_failure; + return -EMSGSIZE; } - if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_BITRATE)) { - if (!nl80211_put_sta_rate(msg, &sinfo->txrate, + if (link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_BITRATE)) { + if (!nl80211_put_sta_rate(msg, &link_sinfo->txrate, NL80211_STA_INFO_TX_BITRATE)) - goto nla_put_failure; + return -EMSGSIZE; } - if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_BITRATE)) { - if (!nl80211_put_sta_rate(msg, &sinfo->rxrate, + if (link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_BITRATE)) { + if (!nl80211_put_sta_rate(msg, &link_sinfo->rxrate, NL80211_STA_INFO_RX_BITRATE)) - goto nla_put_failure; + return -EMSGSIZE; } - PUT_SINFO(RX_PACKETS, rx_packets, u32); - PUT_SINFO(TX_PACKETS, tx_packets, u32); - PUT_SINFO(TX_RETRIES, tx_retries, u32); - PUT_SINFO(TX_FAILED, tx_failed, u32); - PUT_SINFO(EXPECTED_THROUGHPUT, expected_throughput, u32); - PUT_SINFO(BEACON_LOSS, beacon_loss_count, u32); + PUT_LINK_SINFO(RX_PACKETS, rx_packets, u32); + PUT_LINK_SINFO(TX_PACKETS, tx_packets, u32); + PUT_LINK_SINFO(TX_RETRIES, tx_retries, u32); + PUT_LINK_SINFO(TX_FAILED, tx_failed, u32); + PUT_LINK_SINFO(EXPECTED_THROUGHPUT, expected_throughput, u32); + PUT_LINK_SINFO(BEACON_LOSS, beacon_loss_count, u32); - PUT_SINFO(LLID, llid, u16); - PUT_SINFO(PLID, plid, u16); - PUT_SINFO(PLINK_STATE, plink_state, u8); - PUT_SINFO(AIRTIME_LINK_METRIC, airtime_link_metric, u32); - PUT_SINFO(LOCAL_PM, local_pm, u32); - PUT_SINFO(PEER_PM, peer_pm, u32); - PUT_SINFO(NONPEER_PM, nonpeer_pm, u32); - PUT_SINFO(CONNECTED_TO_GATE, connected_to_gate, u8); - PUT_SINFO(CONNECTED_TO_AS, connected_to_as, u8); - PUT_SINFO_U64(T_OFFSET, t_offset); - - if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_BSS_PARAM)) { + if (link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_BSS_PARAM)) { bss_param = nla_nest_start_noflag(msg, NL80211_STA_INFO_BSS_PARAM); if (!bss_param) - goto nla_put_failure; + return -EMSGSIZE; - if (((sinfo->bss_param.flags & BSS_PARAM_FLAGS_CTS_PROT) && + if (((link_sinfo->bss_param.flags & BSS_PARAM_FLAGS_CTS_PROT) && nla_put_flag(msg, NL80211_STA_BSS_PARAM_CTS_PROT)) || - ((sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_PREAMBLE) && + ((link_sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_PREAMBLE) && nla_put_flag(msg, NL80211_STA_BSS_PARAM_SHORT_PREAMBLE)) || - ((sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_SLOT_TIME) && + ((link_sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_SLOT_TIME) && nla_put_flag(msg, NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME)) || nla_put_u8(msg, NL80211_STA_BSS_PARAM_DTIM_PERIOD, - sinfo->bss_param.dtim_period) || + link_sinfo->bss_param.dtim_period) || nla_put_u16(msg, NL80211_STA_BSS_PARAM_BEACON_INTERVAL, - sinfo->bss_param.beacon_interval)) - goto nla_put_failure; + link_sinfo->bss_param.beacon_interval)) + return -EMSGSIZE; nla_nest_end(msg, bss_param); } - if ((sinfo->filled & BIT_ULL(NL80211_STA_INFO_STA_FLAGS)) && - nla_put(msg, NL80211_STA_INFO_STA_FLAGS, - sizeof(struct nl80211_sta_flag_update), - &sinfo->sta_flags)) - goto nla_put_failure; - PUT_SINFO_U64(RX_DROP_MISC, rx_dropped_misc); - PUT_SINFO_U64(BEACON_RX, rx_beacon); - PUT_SINFO(BEACON_SIGNAL_AVG, rx_beacon_signal_avg, u8); - PUT_SINFO(RX_MPDUS, rx_mpdu_count, u32); - PUT_SINFO(FCS_ERROR_COUNT, fcs_err_count, u32); + PUT_LINK_SINFO_U64(RX_DROP_MISC, rx_dropped_misc); + PUT_LINK_SINFO_U64(BEACON_RX, rx_beacon); + PUT_LINK_SINFO(BEACON_SIGNAL_AVG, rx_beacon_signal_avg, u8); + PUT_LINK_SINFO(RX_MPDUS, rx_mpdu_count, u32); + PUT_LINK_SINFO(FCS_ERROR_COUNT, fcs_err_count, u32); if (wiphy_ext_feature_isset(&rdev->wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT)) { - PUT_SINFO(ACK_SIGNAL, ack_signal, u8); - PUT_SINFO(ACK_SIGNAL_AVG, avg_ack_signal, s8); + PUT_LINK_SINFO(ACK_SIGNAL, ack_signal, u8); + PUT_LINK_SINFO(ACK_SIGNAL_AVG, avg_ack_signal, s8); } -#undef PUT_SINFO -#undef PUT_SINFO_U64 +#undef PUT_LINK_SINFO +#undef PUT_LINK_SINFO_U64 - if (sinfo->pertid) { + if (link_sinfo->pertid) { struct nlattr *tidsattr; int tid; tidsattr = nla_nest_start_noflag(msg, NL80211_STA_INFO_TID_STATS); if (!tidsattr) - goto nla_put_failure; + return -EMSGSIZE; for (tid = 0; tid < IEEE80211_NUM_TIDS + 1; tid++) { struct cfg80211_tid_stats *tidstats; struct nlattr *tidattr; - tidstats = &sinfo->pertid[tid]; + tidstats = &link_sinfo->pertid[tid]; if (!tidstats->filled) continue; tidattr = nla_nest_start_noflag(msg, tid + 1); if (!tidattr) - goto nla_put_failure; + return -EMSGSIZE; #define PUT_TIDVAL_U64(attr, memb) do { \ if (tidstats->filled & BIT(NL80211_TID_STATS_ ## attr) && \ nla_put_u64_64bit(msg, NL80211_TID_STATS_ ## attr, \ tidstats->memb, NL80211_TID_STATS_PAD)) \ - goto nla_put_failure; \ + return -EMSGSIZE; \ } while (0) PUT_TIDVAL_U64(RX_MSDU, rx_msdu); @@ -6861,7 +6827,7 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid, BIT(NL80211_TID_STATS_TXQ_STATS)) && !nl80211_put_txq_stats(msg, &tidstats->txq_stats, NL80211_TID_STATS_TXQ_STATS)) - goto nla_put_failure; + return -EMSGSIZE; nla_nest_end(msg, tidattr); } @@ -6869,16 +6835,29 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid, nla_nest_end(msg, tidsattr); } - nla_nest_end(msg, sinfoattr); + return 0; +} - if (sinfo->assoc_req_ies_len && - nla_put(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len, - sinfo->assoc_req_ies)) - goto nla_put_failure; +static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid, + u32 seq, int flags, + struct cfg80211_registered_device *rdev, + struct net_device *dev, + const u8 *mac_addr, struct station_info *sinfo) +{ + struct nlattr *sinfoattr; + void *hdr; + struct link_station_info *link_sinfo = &sinfo->deflink; + int ret = -1; - if (sinfo->assoc_resp_ies_len && - nla_put(msg, NL80211_ATTR_RESP_IE, sinfo->assoc_resp_ies_len, - sinfo->assoc_resp_ies)) + hdr = nl80211hdr_put(msg, portid, seq, flags, cmd); + if (!hdr) { + cfg80211_sinfo_release_content(sinfo); + return ret; + } + + if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || + nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) || + nla_put_u32(msg, NL80211_ATTR_GENERATION, sinfo->generation)) goto nla_put_failure; if (sinfo->mlo_params_valid) { @@ -6892,11 +6871,68 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid, goto nla_put_failure; } + if (sinfo->assoc_req_ies_len && + nla_put(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len, + sinfo->assoc_req_ies)) + goto nla_put_failure; + + if (sinfo->assoc_resp_ies_len && + nla_put(msg, NL80211_ATTR_RESP_IE, sinfo->assoc_resp_ies_len, + sinfo->assoc_resp_ies)) + goto nla_put_failure; + + sinfoattr = nla_nest_start_noflag(msg, NL80211_ATTR_STA_INFO); + if (!sinfoattr) + goto nla_put_failure; + + if ((sinfo->filled & BIT_ULL(NL80211_STA_INFO_STA_FLAGS)) && + nla_put(msg, NL80211_STA_INFO_STA_FLAGS, + sizeof(struct nl80211_sta_flag_update), + &sinfo->sta_flags)) + goto nla_put_failure; + +#define PUT_SINFO(attr, memb, type) do { \ + BUILD_BUG_ON(sizeof(type) == sizeof(u64)); \ + if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_ ## attr) && \ + nla_put_ ## type(msg, NL80211_STA_INFO_ ## attr, \ + sinfo->memb)) \ + goto nla_put_failure; \ + } while (0) +#define PUT_SINFO_U64(attr, memb) do { \ + if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_ ## attr) && \ + nla_put_u64_64bit(msg, NL80211_STA_INFO_ ## attr, \ + sinfo->memb, NL80211_STA_INFO_PAD)) \ + goto nla_put_failure; \ + } while (0) + + PUT_SINFO(CONNECTED_TIME, connected_time, u32); + PUT_SINFO_U64(ASSOC_AT_BOOTTIME, assoc_at); + + PUT_SINFO(LLID, llid, u16); + PUT_SINFO(PLID, plid, u16); + PUT_SINFO(PLINK_STATE, plink_state, u8); + PUT_SINFO(AIRTIME_LINK_METRIC, airtime_link_metric, u32); + PUT_SINFO(LOCAL_PM, local_pm, u32); + PUT_SINFO(PEER_PM, peer_pm, u32); + PUT_SINFO(NONPEER_PM, nonpeer_pm, u32); + PUT_SINFO(CONNECTED_TO_GATE, connected_to_gate, u8); + PUT_SINFO(CONNECTED_TO_AS, connected_to_as, u8); + PUT_SINFO_U64(T_OFFSET, t_offset); + +#undef PUT_SINFO +#undef PUT_SINFO_U64 + + ret = nl80211_fill_link_station(msg, rdev, link_sinfo); + if (ret) + goto nla_put_failure; + + nla_nest_end(msg, sinfoattr); + cfg80211_sinfo_release_content(sinfo); genlmsg_end(msg, hdr); return 0; - nla_put_failure: +nla_put_failure: cfg80211_sinfo_release_content(sinfo); genlmsg_cancel(msg, hdr); return -EMSGSIZE; @@ -13005,11 +13041,10 @@ static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev, err = rdev_get_station(rdev, dev, mac_addr, &sinfo); if (err) return err; - cfg80211_sinfo_release_content(&sinfo); - if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_BEACON_SIGNAL_AVG)) + if (sinfo.deflink.filled & BIT_ULL(NL80211_STA_INFO_BEACON_SIGNAL_AVG)) cqm_config->last_rssi_event_value = - (s8) sinfo.rx_beacon_signal_avg; + (s8)sinfo.deflink.rx_beacon_signal_avg; } last = cqm_config->last_rssi_event_value; diff --git a/net/wireless/trace.h b/net/wireless/trace.h index a57210c8087c..69193fc3b040 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h @@ -200,22 +200,23 @@ __field(u16, llid) \ __field(u16, plid) \ __field(u8, plink_state) -#define SINFO_ASSIGN \ - do { \ - __entry->generation = sinfo->generation; \ - __entry->connected_time = sinfo->connected_time; \ - __entry->inactive_time = sinfo->inactive_time; \ - __entry->rx_bytes = sinfo->rx_bytes; \ - __entry->tx_bytes = sinfo->tx_bytes; \ - __entry->rx_packets = sinfo->rx_packets; \ - __entry->tx_packets = sinfo->tx_packets; \ - __entry->tx_retries = sinfo->tx_retries; \ - __entry->tx_failed = sinfo->tx_failed; \ - __entry->rx_dropped_misc = sinfo->rx_dropped_misc; \ - __entry->beacon_loss_count = sinfo->beacon_loss_count; \ - __entry->llid = sinfo->llid; \ - __entry->plid = sinfo->plid; \ - __entry->plink_state = sinfo->plink_state; \ +#define SINFO_ASSIGN \ + struct link_station_info *link_sinfo = &sinfo->deflink; \ + do { \ + __entry->generation = sinfo->generation; \ + __entry->connected_time = link_sinfo->connected_time; \ + __entry->inactive_time = link_sinfo->inactive_time; \ + __entry->rx_bytes = link_sinfo->rx_bytes; \ + __entry->tx_bytes = link_sinfo->tx_bytes; \ + __entry->rx_packets = link_sinfo->rx_packets; \ + __entry->tx_packets = link_sinfo->tx_packets; \ + __entry->tx_retries = link_sinfo->tx_retries; \ + __entry->tx_failed = link_sinfo->tx_failed; \ + __entry->rx_dropped_misc = link_sinfo->rx_dropped_misc; \ + __entry->beacon_loss_count = link_sinfo->beacon_loss_count; \ + __entry->llid = sinfo->llid; \ + __entry->plid = sinfo->plid; \ + __entry->plink_state = sinfo->plink_state; \ } while (0) #define BOOL_TO_STR(bo) (bo) ? "true" : "false" diff --git a/net/wireless/util.c b/net/wireless/util.c index 60157943d351..dbb2313b6982 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -2626,12 +2626,12 @@ bool cfg80211_does_bw_fit_range(const struct ieee80211_freq_range *freq_range, return false; } -int cfg80211_sinfo_alloc_tid_stats(struct station_info *sinfo, gfp_t gfp) +int cfg80211_sinfo_alloc_tid_stats(struct link_station_info *link_sinfo, gfp_t gfp) { - sinfo->pertid = kcalloc(IEEE80211_NUM_TIDS + 1, - sizeof(*(sinfo->pertid)), - gfp); - if (!sinfo->pertid) + link_sinfo->pertid = kcalloc(IEEE80211_NUM_TIDS + 1, + sizeof(*(link_sinfo->pertid)), + gfp); + if (!link_sinfo->pertid) return -ENOMEM; return 0; diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index a74b1afc594e..a59510deffae 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c @@ -1267,12 +1267,12 @@ static int cfg80211_wext_giwrate(struct net_device *dev, if (err) return err; - if (!(sinfo.filled & BIT_ULL(NL80211_STA_INFO_TX_BITRATE))) { + if (!(sinfo.deflink.filled & BIT_ULL(NL80211_STA_INFO_TX_BITRATE))) { err = -EOPNOTSUPP; goto free; } - rate->value = 100000 * cfg80211_calculate_bitrate(&sinfo.txrate); + rate->value = 100000 * cfg80211_calculate_bitrate(&sinfo.deflink.txrate); free: cfg80211_sinfo_release_content(&sinfo); @@ -1316,8 +1316,8 @@ static struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev) switch (rdev->wiphy.signal_type) { case CFG80211_SIGNAL_TYPE_MBM: - if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_SIGNAL)) { - int sig = sinfo.signal; + if (sinfo.deflink.filled & BIT_ULL(NL80211_STA_INFO_SIGNAL)) { + int sig = sinfo.deflink.signal; wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED; wstats.qual.updated |= IW_QUAL_QUAL_UPDATED; wstats.qual.updated |= IW_QUAL_DBM; @@ -1331,11 +1331,11 @@ static struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev) } fallthrough; case CFG80211_SIGNAL_TYPE_UNSPEC: - if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_SIGNAL)) { + if (sinfo.deflink.filled & BIT_ULL(NL80211_STA_INFO_SIGNAL)) { wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED; wstats.qual.updated |= IW_QUAL_QUAL_UPDATED; - wstats.qual.level = sinfo.signal; - wstats.qual.qual = sinfo.signal; + wstats.qual.level = sinfo.deflink.signal; + wstats.qual.qual = sinfo.deflink.signal; break; } fallthrough; @@ -1345,10 +1345,10 @@ static struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev) } wstats.qual.updated |= IW_QUAL_NOISE_INVALID; - if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_RX_DROP_MISC)) - wstats.discard.misc = sinfo.rx_dropped_misc; - if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_TX_FAILED)) - wstats.discard.retries = sinfo.tx_failed; + if (sinfo.deflink.filled & BIT_ULL(NL80211_STA_INFO_RX_DROP_MISC)) + wstats.discard.misc = sinfo.deflink.rx_dropped_misc; + if (sinfo.deflink.filled & BIT_ULL(NL80211_STA_INFO_TX_FAILED)) + wstats.discard.retries = sinfo.deflink.tx_failed; cfg80211_sinfo_release_content(&sinfo); From patchwork Fri Jan 10 04:24:45 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sarika Sharma X-Patchwork-Id: 13933576 X-Patchwork-Delegate: johannes@sipsolutions.net Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EF40C2046A5 for ; Fri, 10 Jan 2025 04:26:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736483173; cv=none; b=tXcaAFgqlNoXiOrNrNNOCXGelE1I2eNGds8jvSIPVJr8z5LDOOkdGfU00PordboMdAAc6rSLcXYAr2wAfBdSnNummJGh68p4WUq+XFKyU8y6evlxq3Be2ygJvBa8tfTVOpm8SDiskx86XAdrYcjeO73husj5KOt7/NI6NV4eGNM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736483173; c=relaxed/simple; bh=eECMbhHO/tZtTtgd9wWhiV1Jsmr1ysOK9ZGzKnz52KQ=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=cSaxwMi/Lv/wZ2uoUagBYFo7b/Eu3jFiwdob2teGXHRn10IqmTMFwqAOAfV4UfbFzVeMKvydMcmtqr93pJWxvwu2ELSaxaZATCnqI4n0gtc/6/fiWyhQ+cJnG8y/3n9maOJM8pSn8PsZeJvbih8vPPmdWyD8J4tBhGYTYraMAOo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=BkXjPXNM; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="BkXjPXNM" Received: from pps.filterd (m0279863.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 50A1W32H023421; Fri, 10 Jan 2025 04:25:43 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= nVtkMhadTyinaJhpt2IRpczkOn3ERE/pOh4gnqQFWhU=; b=BkXjPXNMNnfxRhzk pjqYiLydi0B1qaXqq7zhgW3kRNNJTg/l3BeiNtB8olX0OAZ7E/xsmJ0ueAgDYVUg Yd7LwlV50XYl33DJsFYVaps1kRu+Tb4fvBx0lxezjCfFbWcoyQk4qJlsypwz24Om dO+Rw6nlaRRUdNKr8dDq/JyJAZH1oN73a7feebUjVvZSvrfqrbSgCJxkGZcWA4nn zgGN1PSorr9B2TvHw5iQZKwx0tVAZsFePlTP2vUPxs/T6cPCIvuxu6tXhX7sQzv4 QcbRuxkg66F3ff8j5HG2O9DUwKHG7xpCxP/OoJzNvftmgYjmJ3EhxD1/j7FcA/fl b0ITTA== Received: from nasanppmta04.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 442syc0bba-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jan 2025 04:25:43 +0000 (GMT) Received: from nasanex01c.na.qualcomm.com (nasanex01c.na.qualcomm.com [10.45.79.139]) by NASANPPMTA04.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id 50A4Pgev004621 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jan 2025 04:25:42 GMT Received: from hu-sarishar-blr.qualcomm.com (10.80.80.8) by nasanex01c.na.qualcomm.com (10.45.79.139) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.9; Thu, 9 Jan 2025 20:25:40 -0800 From: Sarika Sharma To: CC: , Sarika Sharma Subject: [PATCH RFC 3/7] wifi: cfg80211: extend statistics for link level in sinfo Date: Fri, 10 Jan 2025 09:54:45 +0530 Message-ID: <20250110042449.1158789-4-quic_sarishar@quicinc.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250110042449.1158789-1-quic_sarishar@quicinc.com> References: <20250110042449.1158789-1-quic_sarishar@quicinc.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nasanex01c.na.qualcomm.com (10.45.79.139) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: i1sQBMCCmRkmQ9DAXgQ6Hm8IQuQI9OOF X-Proofpoint-ORIG-GUID: i1sQBMCCmRkmQ9DAXgQ6Hm8IQuQI9OOF X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.60.29 definitions=2024-09-06_09,2024-09-06_01,2024-09-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 mlxlogscore=999 malwarescore=0 phishscore=0 lowpriorityscore=0 impostorscore=0 bulkscore=0 clxscore=1015 mlxscore=0 suspectscore=0 priorityscore=1501 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2411120000 definitions=main-2501100034 Currently, statistics is supported at deflink level for station. This has problems when applied to multi-link(ML) connections. Hence, add changes to support link level statistics in sinfo structure. Additionally, remove mlo_params_valid from the sinfo structure and add valid_links to indicate bitmap of valid links for MLO. This will be helpful to check the link related statistics during MLO. The statistics could be embedded into NL message as below: For MLO: cmd -> NL80211_ATTR_IFINDEX NL80211_ATTR_MAC NL80211_ATTR_GENERATION .......etc NL80211_ATTR_STA_INFO | nest flag NL80211_STA_INFO_CONNECTED_TIME, NL80211_STA_INFO_STA_FLAGS, ........etc NL80211_ATTR_MLO_LINK_ID, NL80211_ATTR_MLD_ADDR, NL80211_ATTR_MLO_LINKS | nested link_id-1 | nested NL80211_ATTR_MLO_LINK_ID, NL80211_ATTR_MLD_ADDR, NL80211_ATTR_STA_INFO | nest flag NL80211_STA_INFO_RX_BYTES, NL80211_STA_INFO_TX_BYTES, ..........etc. link_id-2 | nested NL80211_ATTR_MLO_LINK_ID, NL80211_ATTR_MLD_ADDR, NL80211_ATTR_STA_INFO | nest flag NL80211_STA_INFO_RX_BYTES, NL80211_STA_INFO_TX_BYTES, .........etc For non-ML: cmd-> NL80211_ATTR_IFINDEX NL80211_ATTR_MAC NL80211_ATTR_GENERATION .... NL80211_ATTR_STA_INFO | nest flag NL80211_STA_INFO_CONNECTED_TIME, NL80211_STA_INFO_STA_FLAGS, NL80211_STA_INFO_RX_BYTES, NL80211_STA_INFO_TX_BYTES, .........etc The output of iw dev wlan0 station dump for MLO could look like below: Station 00:03:7f:04:31:78 (on wlan0) authorized: yes authenticated: yes associated: yes preamble: long WMM/WME: yes MFP: yes TDLS peer: no connected time: 383 seconds associated at [boottime]: 93.740s associated at: 93685 ms current time: 340046 ms MLD address: 00:03:7f:04:31:78 Link 0: Address: 00:03:7f:04:31:78 inactive time: 330120 ms rx bytes: 116 rx packets: 3 tx bytes: 0 tx packets: 0 tx retries: 0 tx failed: 0 rx drop misc: 0 signal: -95 dBm tx bitrate: 6.0 MBit/s tx duration: 2669 us rx duration: 0 us DTIM period: 2 beacon interval:100 Link 1: Address: 00:03:7f:04:31:79 inactive time: 81268 ms rx bytes: 1323 rx packets: 12 tx bytes: 1538 tx packets: 8 tx retries: 0 tx failed: 0 rx drop misc: 0 signal: -95 dBm tx bitrate: 6.0 MBit/s tx duration: 2669 us rx bitrate: 6.0 MBit/s rx duration: 0 us DTIM period: 2 beacon interval:100 Signed-off-by: Sarika Sharma --- include/net/cfg80211.h | 24 +++++--- include/net/mac80211.h | 3 +- net/mac80211/ibss.c | 4 +- net/mac80211/sta_info.c | 132 ++++++++++++++++++++++++++++++---------- net/mac80211/sta_info.h | 2 +- net/mac80211/util.c | 18 +++++- net/wireless/nl80211.c | 78 ++++++++++++++++++------ 7 files changed, 198 insertions(+), 63 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index ba3e7e72ab5d..5b0ec0394715 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -2158,11 +2158,6 @@ struct link_station_info { * @local_pm: local mesh STA power save mode * @peer_pm: peer mesh STA power save mode * @nonpeer_pm: non-peer mesh STA power save mode - * @mlo_params_valid: Indicates @assoc_link_id and @mld_addr fields are filled - * by driver. Drivers use this only in cfg80211_new_sta() calls when AP - * MLD's MLME/SME is offload to driver. Drivers won't fill this - * information in cfg80211_del_sta_sinfo(), get_station() and - * dump_station() callbacks. * @assoc_link_id: Indicates MLO link ID of the AP, with which the station * completed (re)association. This information filled for both MLO * and non-MLO STA connections when the AP affiliated with an MLD. @@ -2176,8 +2171,12 @@ struct link_station_info { * dump_station() callbacks. User space needs this information to determine * the accepted and rejected affiliated links of the connected station. * @assoc_resp_ies_len: Length of @assoc_resp_ies buffer in octets. + * @valid_links: bitmap of valid links, or 0 for non-MLO. Drivers fill this + * information in cfg80211_new_sta(), cfg80211_del_sta_sinfo(), + * get_station() and dump_station() callbacks. * @deflink: This holds the default link STA information, for non MLO STA * all link specific STA information is accessed through @deflink. + * @links: reference to Link sta entries for MLO. */ struct station_info { u64 filled; @@ -2201,13 +2200,15 @@ struct station_info { enum nl80211_mesh_power_mode peer_pm; enum nl80211_mesh_power_mode nonpeer_pm; - bool mlo_params_valid; u8 assoc_link_id; u8 mld_addr[ETH_ALEN] __aligned(2); const u8 *assoc_resp_ies; size_t assoc_resp_ies_len; + u16 valid_links; struct link_station_info deflink; + /* TODO: Need to check and add protection access to links memory */ + struct link_station_info *links[IEEE80211_MLD_MAX_NUM_LINKS]; }; /** @@ -8473,7 +8474,16 @@ int cfg80211_sinfo_alloc_tid_stats(struct link_station_info *link_sinfo, gfp_t g */ static inline void cfg80211_sinfo_release_content(struct station_info *sinfo) { - kfree(sinfo->deflink.pertid); + int link_id; + + if (sinfo->valid_links) { + for_each_valid_link(sinfo, link_id) { + kfree(sinfo->links[link_id]->pertid); + kfree(sinfo->links[link_id]); + } + } else { + kfree(sinfo->deflink.pertid); + } } /** diff --git a/include/net/mac80211.h b/include/net/mac80211.h index ea62d223a0e4..c1e88761b5e8 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -7214,13 +7214,14 @@ void ieee80211_disable_rssi_reports(struct ieee80211_vif *vif); * ieee80211_ave_rssi - report the average RSSI for the specified interface * * @vif: the specified virtual interface + * @link_id: the link ID for MLO, or -1 for non-MLO * * Note: This function assumes that the given vif is valid. * * Return: The average RSSI value for the requested interface, or 0 if not * applicable. */ -int ieee80211_ave_rssi(struct ieee80211_vif *vif); +int ieee80211_ave_rssi(struct ieee80211_vif *vif, int link_id); /** * ieee80211_report_wowlan_wakeup - report WoWLAN wakeup diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index a1b4178deccf..0848fbda65f9 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -642,7 +642,7 @@ static int ieee80211_sta_active_ibss(struct ieee80211_sub_if_data *sdata) rcu_read_lock(); list_for_each_entry_rcu(sta, &local->sta_list, list) { - unsigned long last_active = ieee80211_sta_last_active(sta); + unsigned long last_active = ieee80211_sta_last_active(sta, -1); if (sta->sdata == sdata && time_is_after_jiffies(last_active + @@ -1235,7 +1235,7 @@ static void ieee80211_ibss_sta_expire(struct ieee80211_sub_if_data *sdata) lockdep_assert_wiphy(local->hw.wiphy); list_for_each_entry_safe(sta, tmp, &local->sta_list, list) { - unsigned long last_active = ieee80211_sta_last_active(sta); + unsigned long last_active = ieee80211_sta_last_active(sta, -1); if (sdata != sta->sdata) continue; diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 985e53bf04bc..6be5c05b686a 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -1622,7 +1622,7 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, lockdep_assert_wiphy(local->hw.wiphy); list_for_each_entry_safe(sta, tmp, &local->sta_list, list) { - unsigned long last_active = ieee80211_sta_last_active(sta); + unsigned long last_active = ieee80211_sta_last_active(sta, -1); if (sdata != sta->sdata) continue; @@ -2391,18 +2391,28 @@ void ieee80211_sta_update_pending_airtime(struct ieee80211_local *local, } static struct ieee80211_sta_rx_stats * -sta_get_last_rx_stats(struct sta_info *sta) +sta_get_last_rx_stats(struct sta_info *sta, int link_id) { - struct ieee80211_sta_rx_stats *stats = &sta->deflink.rx_stats; + struct ieee80211_sta_rx_stats *stats; + struct link_sta_info *link_sta_info; int cpu; - if (!sta->deflink.pcpu_rx_stats) + if (link_id < 0) + link_sta_info = &sta->deflink; + else + link_sta_info = + rcu_dereference_protected(sta->link[link_id], + lockdep_is_held(&sta->local->hw.wiphy->mtx)); + + stats = &link_sta_info->rx_stats; + + if (!link_sta_info->pcpu_rx_stats) return stats; for_each_possible_cpu(cpu) { struct ieee80211_sta_rx_stats *cpustats; - cpustats = per_cpu_ptr(sta->deflink.pcpu_rx_stats, cpu); + cpustats = per_cpu_ptr(link_sta_info->pcpu_rx_stats, cpu); if (time_after(cpustats->last_rx, stats->last_rx)) stats = cpustats; @@ -2470,9 +2480,10 @@ static void sta_stats_decode_rate(struct ieee80211_local *local, u32 rate, } } -static int sta_set_rate_info_rx(struct sta_info *sta, struct rate_info *rinfo) +static int sta_set_rate_info_rx(struct sta_info *sta, struct rate_info *rinfo, + int link_id) { - u32 rate = READ_ONCE(sta_get_last_rx_stats(sta)->last_rate); + u32 rate = READ_ONCE(sta_get_last_rx_stats(sta, link_id)->last_rate); if (rate == STA_STATS_RATE_INVALID) return -EINVAL; @@ -2497,20 +2508,28 @@ static inline u64 sta_get_tidstats_msdu(struct ieee80211_sta_rx_stats *rxstats, static void sta_set_tidstats(struct sta_info *sta, struct cfg80211_tid_stats *tidstats, - int tid) + int link_id, int tid) { struct ieee80211_local *local = sta->local; + struct link_sta_info *link_sta_info; int cpu; + if (link_id < 0) + link_sta_info = &sta->deflink; + else + link_sta_info = + rcu_dereference_protected(sta->link[link_id], + lockdep_is_held(&local->hw.wiphy->mtx)); + if (!(tidstats->filled & BIT(NL80211_TID_STATS_RX_MSDU))) { - tidstats->rx_msdu += sta_get_tidstats_msdu(&sta->deflink.rx_stats, + tidstats->rx_msdu += sta_get_tidstats_msdu(&link_sta_info->rx_stats, tid); - if (sta->deflink.pcpu_rx_stats) { + if (link_sta_info->pcpu_rx_stats) { for_each_possible_cpu(cpu) { struct ieee80211_sta_rx_stats *cpurxs; - cpurxs = per_cpu_ptr(sta->deflink.pcpu_rx_stats, + cpurxs = per_cpu_ptr(link_sta_info->pcpu_rx_stats, cpu); tidstats->rx_msdu += sta_get_tidstats_msdu(cpurxs, tid); @@ -2522,19 +2541,19 @@ static void sta_set_tidstats(struct sta_info *sta, if (!(tidstats->filled & BIT(NL80211_TID_STATS_TX_MSDU))) { tidstats->filled |= BIT(NL80211_TID_STATS_TX_MSDU); - tidstats->tx_msdu = sta->deflink.tx_stats.msdu[tid]; + tidstats->tx_msdu = link_sta_info->tx_stats.msdu[tid]; } if (!(tidstats->filled & BIT(NL80211_TID_STATS_TX_MSDU_RETRIES)) && ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) { tidstats->filled |= BIT(NL80211_TID_STATS_TX_MSDU_RETRIES); - tidstats->tx_msdu_retries = sta->deflink.status_stats.msdu_retries[tid]; + tidstats->tx_msdu_retries = link_sta_info->status_stats.msdu_retries[tid]; } if (!(tidstats->filled & BIT(NL80211_TID_STATS_TX_MSDU_FAILED)) && ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) { tidstats->filled |= BIT(NL80211_TID_STATS_TX_MSDU_FAILED); - tidstats->tx_msdu_failed = sta->deflink.status_stats.msdu_failed[tid]; + tidstats->tx_msdu_failed = link_sta_info->status_stats.msdu_failed[tid]; } if (tid < IEEE80211_NUM_TIDS) { @@ -2602,11 +2621,20 @@ static void sta_set_link_sinfo(struct sta_info *sta, struct link_station_info *l struct ieee80211_sub_if_data *sdata = sta->sdata; struct ieee80211_local *local = sdata->local; u32 thr = 0; - int i, ac, cpu; + int i, ac, cpu, link_id; struct ieee80211_sta_rx_stats *last_rxstats; - struct link_sta_info *link_sta_info = &sta->deflink; + struct link_sta_info *link_sta_info; - last_rxstats = sta_get_last_rx_stats(sta); + link_id = link_sinfo->link_id; + + if (link_id < 0) + link_sta_info = &sta->deflink; + else + link_sta_info = + rcu_dereference_protected(sta->link[link_id], + lockdep_is_held(&local->hw.wiphy->mtx)); + + last_rxstats = sta_get_last_rx_stats(sta, link_id); /* do before driver, so beacon filtering drivers have a @@ -2617,6 +2645,9 @@ static void sta_set_link_sinfo(struct sta_info *sta, struct link_station_info *l link_sinfo->rx_beacon = link_sdata->u.mgd.count_beacon_signal; drv_link_sta_statistics(local, sdata, &sta->sta, link_sinfo); + + memcpy(link_sinfo->addr, link_sta_info->addr, ETH_ALEN); + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_INACTIVE_TIME) | BIT_ULL(NL80211_STA_INFO_BSS_PARAM) | BIT_ULL(NL80211_STA_INFO_RX_DROP_MISC); @@ -2628,7 +2659,7 @@ static void sta_set_link_sinfo(struct sta_info *sta, struct link_station_info *l } link_sinfo->inactive_time = - jiffies_to_msecs(jiffies - ieee80211_sta_last_active(sta)); + jiffies_to_msecs(jiffies - ieee80211_sta_last_active(sta, link_id)); if (!(link_sinfo->filled & (BIT_ULL(NL80211_STA_INFO_TX_BYTES64) | BIT_ULL(NL80211_STA_INFO_TX_BYTES)))) { @@ -2717,7 +2748,8 @@ static void sta_set_link_sinfo(struct sta_info *sta, struct link_station_info *l !(sdata->vif.driver_flags & IEEE80211_VIF_BEACON_FILTER)) { link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_BEACON_RX) | BIT_ULL(NL80211_STA_INFO_BEACON_SIGNAL_AVG); - link_sinfo->rx_beacon_signal_avg = ieee80211_ave_rssi(&sdata->vif); + link_sinfo->rx_beacon_signal_avg = + ieee80211_ave_rssi(&sdata->vif, link_id); } if (ieee80211_hw_check(&sta->local->hw, SIGNAL_DBM) || @@ -2756,22 +2788,20 @@ static void sta_set_link_sinfo(struct sta_info *sta, struct link_station_info *l } if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_BITRATE)) && - !sta->sta.valid_links && ieee80211_rate_valid(&link_sta_info->tx_stats.last_rate)) { sta_set_rate_info_tx(sta, &link_sta_info->tx_stats.last_rate, &link_sinfo->txrate); link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); } - if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_BITRATE)) && - !sta->sta.valid_links){ - if (sta_set_rate_info_rx(sta, &link_sinfo->rxrate) == 0) + if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_BITRATE))) { + if (sta_set_rate_info_rx(sta, &link_sinfo->rxrate, link_id) == 0) link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BITRATE); } if (tidstats && !cfg80211_sinfo_alloc_tid_stats(link_sinfo, GFP_KERNEL)) { for (i = 0; i < IEEE80211_NUM_TIDS + 1; i++) - sta_set_tidstats(sta, &link_sinfo->pertid[i], i); + sta_set_tidstats(sta, &link_sinfo->pertid[i], link_id, i); } link_sinfo->bss_param.flags = 0; @@ -2810,10 +2840,13 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo, bool tidstats) { struct ieee80211_sub_if_data *sdata = sta->sdata; - struct link_station_info *link_sinfo = &sinfo->deflink; - struct ieee80211_link_data *link_sdata = &sdata->deflink; + struct ieee80211_link_data *link_sdata; + struct link_station_info *link_sinfo; + struct link_sta_info *link_sta; + int link_id; sinfo->generation = sdata->local->sta_generation; + sinfo->valid_links = sta->sta.valid_links; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_STA_FLAGS) | BIT_ULL(NL80211_STA_INFO_CONNECTED_TIME) | @@ -2851,7 +2884,33 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo, sta_set_mesh_sinfo(sta, sinfo); #endif - sta_set_link_sinfo(sta, link_sinfo, link_sdata, tidstats); + if (sinfo->valid_links) { + memcpy(sinfo->mld_addr, sta->addr, ETH_ALEN); + + for_each_valid_link(sinfo, link_id) { + link_sta = + rcu_dereference_protected(sta->link[link_id], + lockdep_is_held(&sta->local->hw.wiphy->mtx)); + if (!link_sta) + continue; + + link_sinfo = kzalloc(sizeof(*link_sinfo), GFP_KERNEL); + if (!link_sinfo) + return; + + link_sinfo->link_id = link_id; + link_sdata = + rcu_dereference_protected(sdata->link[link_id], + lockdep_is_held(&sdata->local->hw.wiphy->mtx)); + sta_set_link_sinfo(sta, link_sinfo, link_sdata, tidstats); + sinfo->links[link_id] = link_sinfo; + } + } else { + link_sinfo = &sinfo->deflink; + link_sinfo->link_id = -1; + link_sdata = &sdata->deflink; + sta_set_link_sinfo(sta, link_sinfo, link_sdata, tidstats); + } } u32 sta_get_expected_throughput(struct sta_info *sta) @@ -2873,14 +2932,23 @@ u32 sta_get_expected_throughput(struct sta_info *sta) return thr; } -unsigned long ieee80211_sta_last_active(struct sta_info *sta) +unsigned long ieee80211_sta_last_active(struct sta_info *sta, int link_id) { - struct ieee80211_sta_rx_stats *stats = sta_get_last_rx_stats(sta); + struct ieee80211_sta_rx_stats *stats = sta_get_last_rx_stats(sta, link_id); + struct link_sta_info *link_sta_info; - if (!sta->deflink.status_stats.last_ack || - time_after(stats->last_rx, sta->deflink.status_stats.last_ack)) + if (link_id < 0) + link_sta_info = &sta->deflink; + else + link_sta_info = + rcu_dereference_protected(sta->link[link_id], + lockdep_is_held(&sta->local->hw.wiphy->mtx)); + + if (!link_sta_info->status_stats.last_ack || + time_after(stats->last_rx, link_sta_info->status_stats.last_ack)) return stats->last_rx; - return sta->deflink.status_stats.last_ack; + + return link_sta_info->status_stats.last_ack; } static void sta_update_codel_params(struct sta_info *sta, u32 thr) diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 9f89fb5bee37..1d82519319fe 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -939,7 +939,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta); void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta); void ieee80211_sta_ps_deliver_uapsd(struct sta_info *sta); -unsigned long ieee80211_sta_last_active(struct sta_info *sta); +unsigned long ieee80211_sta_last_active(struct sta_info *sta, int link_id); void ieee80211_sta_set_max_amsdu_subframes(struct sta_info *sta, const u8 *ext_capab, diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 7b656326e68a..f8ae7726eede 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -3274,14 +3274,28 @@ int ieee80211_put_srates_elem(struct sk_buff *skb, return 0; } -int ieee80211_ave_rssi(struct ieee80211_vif *vif) +int ieee80211_ave_rssi(struct ieee80211_vif *vif, int link_id) { struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); + struct ieee80211_link_data *link_data; + int rssi; if (WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION)) return 0; - return -ewma_beacon_signal_read(&sdata->deflink.u.mgd.ave_beacon_signal); + if (link_id < 0) + link_data = &sdata->deflink; + else + link_data = + rcu_dereference_protected(sdata->link[link_id], + lockdep_is_held(&sdata->local->hw.wiphy->mtx)); + + if (WARN_ON(!link_data)) + return -99; + + rssi = -ewma_beacon_signal_read(&link_data->u.mgd.ave_beacon_signal); + + return rssi; } EXPORT_SYMBOL_GPL(ieee80211_ave_rssi); diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 7740ab5c778d..37a8cbb1022a 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -6844,10 +6844,10 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid, struct net_device *dev, const u8 *mac_addr, struct station_info *sinfo) { - struct nlattr *sinfoattr; + struct nlattr *sinfoattr, *link_sinfoattr, *links, *link; void *hdr; - struct link_station_info *link_sinfo = &sinfo->deflink; - int ret = -1; + struct link_station_info *link_sinfo; + int ret = -1, link_id; hdr = nl80211hdr_put(msg, portid, seq, flags, cmd); if (!hdr) { @@ -6860,17 +6860,6 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid, nla_put_u32(msg, NL80211_ATTR_GENERATION, sinfo->generation)) goto nla_put_failure; - if (sinfo->mlo_params_valid) { - if (nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID, - sinfo->assoc_link_id)) - goto nla_put_failure; - - if (!is_zero_ether_addr(sinfo->mld_addr) && - nla_put(msg, NL80211_ATTR_MLD_ADDR, ETH_ALEN, - sinfo->mld_addr)) - goto nla_put_failure; - } - if (sinfo->assoc_req_ies_len && nla_put(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len, sinfo->assoc_req_ies)) @@ -6922,11 +6911,64 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid, #undef PUT_SINFO #undef PUT_SINFO_U64 - ret = nl80211_fill_link_station(msg, rdev, link_sinfo); - if (ret) - goto nla_put_failure; + if (sinfo->valid_links) { + /* TODO: Add accumulated stats for packets, bytes for + * better representation at MLO level. + */ + + /* Closing nested STA_INFO as MLO links ATTR should not + * be in nested STA_INFO + */ + nla_nest_end(msg, sinfoattr); + + if (nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID, + sinfo->assoc_link_id)) + goto nla_put_failure; + + if (!is_zero_ether_addr(sinfo->mld_addr) && + nla_put(msg, NL80211_ATTR_MLD_ADDR, ETH_ALEN, + sinfo->mld_addr)) + goto nla_put_failure; + + links = nla_nest_start(msg, NL80211_ATTR_MLO_LINKS); + if (!links) + goto nla_put_failure; + + for_each_valid_link(sinfo, link_id) { + link_sinfo = sinfo->links[link_id]; + link = nla_nest_start(msg, link_id + 1); + if (!link) + goto nla_put_failure; + + if (nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID, + link_id)) + goto nla_put_failure; - nla_nest_end(msg, sinfoattr); + if (!is_zero_ether_addr(link_sinfo->addr) && + nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, + link_sinfo->addr)) + goto nla_put_failure; + + link_sinfoattr = nla_nest_start_noflag(msg, NL80211_ATTR_STA_INFO); + if (!link_sinfoattr) + goto nla_put_failure; + + ret = nl80211_fill_link_station(msg, rdev, link_sinfo); + if (ret) + goto nla_put_failure; + + nla_nest_end(msg, link_sinfoattr); + nla_nest_end(msg, link); + } + nla_nest_end(msg, links); + } else { + link_sinfo = &sinfo->deflink; + ret = nl80211_fill_link_station(msg, rdev, link_sinfo); + if (ret) + goto nla_put_failure; + + nla_nest_end(msg, sinfoattr); + } cfg80211_sinfo_release_content(sinfo); genlmsg_end(msg, hdr); From patchwork Fri Jan 10 04:24:46 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sarika Sharma X-Patchwork-Id: 13933573 X-Patchwork-Delegate: johannes@sipsolutions.net Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 02D9E126C10 for ; Fri, 10 Jan 2025 04:26:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736483166; cv=none; b=fuXYZpyC2DduutyN4ZYfAp0JS4pGpFXGp7JAPzkyDyIm9TH5fexjLKAephKHecmVmWLk47wL/0e+jLG4UOEyb2oqDpdWh74Du1KriGn1+9edsuzvpMIO4Gkd1rt+NoPwa0INmSgh+GMPBNko7JDHkE5bFaicGwN2aM568a5CUKM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736483166; c=relaxed/simple; bh=VWp46MBrIaZYonBOBR9LrQrncnpbz3OCTeOZ/e8RcXY=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=lQ9aBKfHdB+BS5gWhQO+hvzAU8xTiZTJ2ce7yw860CEA9+rMFFnvCXN9hKSVfbZamHLoHwN/GaynDQs8w5GYXhGr63pal1o92/cHMMiA9jHMebJLAA1oML6ZVYeGYcrB9OW98NkxpWwRW/qEudwztheXgFi9GWDFFOUlv7fkI8Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=pDgylDKI; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="pDgylDKI" Received: from pps.filterd (m0279866.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 50A3vWSq016225; Fri, 10 Jan 2025 04:25:45 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= pukuwWpLrCdyIy3wbKkUTDSjEz89WUi7SrjL9OffzMQ=; b=pDgylDKI9+QuTmoJ HJOPGWgchpBXCyjvOmKD6BpkyPp2j4vvjaxWyTugbrOd32usSKd9IqLULQ0Px3/h 2E8yG4+hyb7lcofGSkg1nrOecrPYCaChrN/2WhdiQHt9xSpyufCBDm/pifulTTm2 9/Hw+29wl6fE9d2CtJyi6xMTjE+J2MjG5vhIztF6VqETrqWJm01lKNBUVQ+NvcNz c2DWYN0TmdlEyNzDel6cY9iH3gMSWZJDB3ummAg/DeuPc7TKa0q4nwsFMzCRwoE7 KMNpHNkE7Eys8QTtanPG/Iv+1+Z8tM9Oum8gUE3J80YZPdgnrVPItu8SmivgY1tT ZRWtPw== Received: from nasanppmta05.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 442v3rg1ng-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jan 2025 04:25:44 +0000 (GMT) Received: from nasanex01c.na.qualcomm.com (nasanex01c.na.qualcomm.com [10.45.79.139]) by NASANPPMTA05.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id 50A4Pi9t010989 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jan 2025 04:25:44 GMT Received: from hu-sarishar-blr.qualcomm.com (10.80.80.8) by nasanex01c.na.qualcomm.com (10.45.79.139) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.9; Thu, 9 Jan 2025 20:25:42 -0800 From: Sarika Sharma To: CC: , Sarika Sharma Subject: [PATCH RFC 4/7] wifi: cfg80211: add accumulated statistics for MLO links Date: Fri, 10 Jan 2025 09:54:46 +0530 Message-ID: <20250110042449.1158789-5-quic_sarishar@quicinc.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250110042449.1158789-1-quic_sarishar@quicinc.com> References: <20250110042449.1158789-1-quic_sarishar@quicinc.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nasanex01c.na.qualcomm.com (10.45.79.139) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: IaTqILDyDCx0AzyBWxAxNIwpcnkix2WK X-Proofpoint-ORIG-GUID: IaTqILDyDCx0AzyBWxAxNIwpcnkix2WK X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.60.29 definitions=2024-09-06_09,2024-09-06_01,2024-09-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxlogscore=999 spamscore=0 clxscore=1015 mlxscore=0 bulkscore=0 malwarescore=0 lowpriorityscore=0 adultscore=0 suspectscore=0 phishscore=0 priorityscore=1501 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2411120000 definitions=main-2501100034 Currently statistics are handled at link level for multi-link operation(MLO). There is no provision to check accumulated statistics for a multi-link(ML) station. Accumulated statistics are useful to provide comprehensive overview for the ML stations. Statistics such as packets and bytes are useful for observing the total packets sent and received at the station level. However, MLO statistics for rates and signal can not be accumulated since it won't make much sense. Hence, a subsequent change will handle signal and rates bit differently at MLO level. Hence, add accumulated statistics for MLO station. Also, for non-ML station accumulated statistics make no sense. The statistics could be embedded into NL message as below: For MLO: cmd -> NL80211_ATTR_IFINDEX NL80211_ATTR_MAC NL80211_ATTR_GENERATION ......etc NL80211_ATTR_STA_INFO | nest flag NL80211_STA_INFO_CONNECTED_TIME, NL80211_STA_INFO_STA_FLAGS, NL80211_STA_INFO_RX_BYTES, //accumulated data NL80211_STA_INFO_TX_BYTES, ......etc NL80211_ATTR_MLO_LINK_ID, NL80211_ATTR_MLD_ADDR, NL80211_ATTR_MLO_LINKS | nested link_id-1 | nested NL80211_ATTR_MLO_LINK_ID, NL80211_ATTR_MLD_ADDR, NL80211_ATTR_STA_INFO | nest flag NL80211_STA_INFO_RX_BYTES, NL80211_STA_INFO_TX_BYTES, ..........etc. link_id-2 | nested NL80211_ATTR_MLO_LINK_ID, NL80211_ATTR_MLD_ADDR, NL80211_ATTR_STA_INFO | nest flag NL80211_STA_INFO_RX_BYTES, NL80211_STA_INFO_TX_BYTES, .........etc The output of iw dev wlan0 station dump for MLO could look like below: Station 00:03:7f:04:31:78 (on wlan0) authorized: yes authenticated: yes associated: yes preamble: long WMM/WME: yes MFP: yes TDLS peer: no connected time: 383 seconds associated at [boottime]: 93.740s associated at: 93685 ms rx bytes: 1439 rx packets: 15 tx bytes: 1538 tx packets: 8 tx retries: 0 tx failed: 0 current time: 474340 ms MLD address: 00:03:7f:04:31:78 Link 0: Address: 00:03:7f:04:31:78 inactive time: 330120 ms rx bytes: 116 rx packets: 3 tx bytes: 0 tx packets: 0 tx retries: 0 tx failed: 0 rx drop misc: 0 signal: -95 dBm tx bitrate: 6.0 MBit/s tx duration: 2669 us rx duration: 0 us DTIM period: 2 beacon interval:100 Link 1: Address: 00:03:7f:04:31:79 inactive time: 81268 ms rx bytes: 1323 rx packets: 12 tx bytes: 1538 tx packets: 8 tx retries: 0 tx failed: 0 rx drop misc: 0 signal: -95 dBm tx bitrate: 6.0 MBit/s tx duration: 2669 us rx bitrate: 6.0 MBit/s rx duration: 0 us DTIM period: 2 beacon interval:100 Signed-off-by: Sarika Sharma --- include/net/cfg80211.h | 13 +++++++++++ net/mac80211/sta_info.c | 50 +++++++++++++++++++++++++++++++++++++++++ net/wireless/nl80211.c | 36 ++++++++++++++++++++++++++--- 3 files changed, 96 insertions(+), 3 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 5b0ec0394715..ac038903d53e 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -2174,6 +2174,12 @@ struct link_station_info { * @valid_links: bitmap of valid links, or 0 for non-MLO. Drivers fill this * information in cfg80211_new_sta(), cfg80211_del_sta_sinfo(), * get_station() and dump_station() callbacks. + * @rx_packets: packets (MSDUs & MMPDUs) received from this station + * @tx_packets: packets (MSDUs & MMPDUs) transmitted to this station + * @rx_bytes: bytes (size of MPDUs) received from this station + * @tx_bytes: bytes (size of MPDUs) transmitted to this station + * @tx_retries: cumulative retry counts (MPDUs) + * @tx_failed: number of failed transmissions (MPDUs) (retries exceeded, no ACK) * @deflink: This holds the default link STA information, for non MLO STA * all link specific STA information is accessed through @deflink. * @links: reference to Link sta entries for MLO. @@ -2206,6 +2212,13 @@ struct station_info { size_t assoc_resp_ies_len; u16 valid_links; + u32 rx_packets; + u32 tx_packets; + u64 rx_bytes; + u64 tx_bytes; + u32 tx_retries; + u32 tx_failed; + struct link_station_info deflink; /* TODO: Need to check and add protection access to links memory */ struct link_station_info *links[IEEE80211_MLD_MAX_NUM_LINKS]; diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 6be5c05b686a..f4492174d2c4 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -2836,6 +2836,55 @@ static void sta_set_link_sinfo(struct sta_info *sta, struct link_station_info *l } } +static void sta_set_mld_sinfo(struct station_info *sinfo, struct sta_info *sta) +{ + struct link_station_info *link_sinfo; + struct link_sta_info *link_sta; + int link_id; + + for_each_valid_link(sinfo, link_id) { + link_sta = + rcu_dereference_protected(sta->link[link_id], + lockdep_is_held(&sta->local->hw.wiphy->mtx)); + if (!link_sta) + continue; + + link_sinfo = sinfo->links[link_id]; + + if ((link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_PACKETS))) { + sinfo->tx_packets += link_sinfo->tx_packets; + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS); + } + + if ((link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_PACKETS))) { + sinfo->rx_packets += link_sinfo->rx_packets; + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_PACKETS); + } + + if (link_sinfo->filled & (BIT_ULL(NL80211_STA_INFO_TX_BYTES) | + BIT_ULL(NL80211_STA_INFO_TX_BYTES64))) { + sinfo->tx_bytes += link_sinfo->tx_bytes; + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES); + } + + if (link_sinfo->filled & (BIT_ULL(NL80211_STA_INFO_RX_BYTES) | + BIT_ULL(NL80211_STA_INFO_TX_BYTES64))) { + sinfo->rx_bytes += link_sinfo->rx_bytes; + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BYTES); + } + + if (link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_RETRIES)) { + sinfo->tx_retries += link_sinfo->tx_retries; + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES); + } + + if (link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_FAILED)) { + sinfo->tx_failed += link_sinfo->tx_failed; + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); + } + } +} + void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo, bool tidstats) { @@ -2905,6 +2954,7 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo, sta_set_link_sinfo(sta, link_sinfo, link_sdata, tidstats); sinfo->links[link_id] = link_sinfo; } + sta_set_mld_sinfo(sinfo, sta); } else { link_sinfo = &sinfo->deflink; link_sinfo->link_id = -1; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 37a8cbb1022a..06688aa1780f 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -6838,6 +6838,36 @@ static int nl80211_fill_link_station(struct sk_buff *msg, return 0; } +static int nl80211_fill_mld_station(struct sk_buff *msg, + struct station_info *sinfo) +{ +#define PUT_SINFO(attr, memb, type) do { \ + BUILD_BUG_ON(sizeof(type) == sizeof(u64)); \ + if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_ ## attr) && \ + nla_put_ ## type(msg, NL80211_STA_INFO_ ## attr, \ + sinfo->memb)) \ + return -EMSGSIZE; \ + } while (0) +#define PUT_SINFO_U64(attr, memb) do { \ + if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_ ## attr) && \ + nla_put_u64_64bit(msg, NL80211_STA_INFO_ ## attr, \ + sinfo->memb, NL80211_STA_INFO_PAD)) \ + return -EMSGSIZE; \ + } while (0) + + PUT_SINFO(RX_PACKETS, rx_packets, u32); + PUT_SINFO(TX_PACKETS, tx_packets, u32); + PUT_SINFO_U64(RX_BYTES, rx_bytes); + PUT_SINFO_U64(TX_BYTES, tx_bytes); + PUT_SINFO(TX_RETRIES, tx_retries, u32); + PUT_SINFO(TX_FAILED, tx_failed, u32); + +#undef PUT_SINFO +#undef PUT_SINFO_U64 + + return 0; +} + static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid, u32 seq, int flags, struct cfg80211_registered_device *rdev, @@ -6912,9 +6942,9 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid, #undef PUT_SINFO_U64 if (sinfo->valid_links) { - /* TODO: Add accumulated stats for packets, bytes for - * better representation at MLO level. - */ + ret = nl80211_fill_mld_station(msg, sinfo); + if (ret) + goto nla_put_failure; /* Closing nested STA_INFO as MLO links ATTR should not * be in nested STA_INFO From patchwork Fri Jan 10 04:24:47 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sarika Sharma X-Patchwork-Id: 13933575 X-Patchwork-Delegate: johannes@sipsolutions.net Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BD6671E3762 for ; Fri, 10 Jan 2025 04:26:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736483172; cv=none; b=Wkpg62coE0pp46t6twer+V3JmVTz5QJ/hvj7oBfTGKVnbluB3g+j8I0qtoNkDLTnCdLrE029pT/MA/glirSYDlD4Y5sXtHcgebGPxzB1bw1ftDSQEXJJ/DiH/xW7ryOvhQIJwjfjiwslx22A0GvG5TJ96T66jkLK6gqQDUpVb0s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736483172; c=relaxed/simple; bh=qSKiMQa1Uoiu+JIfRZexkqTUsDRAEt8KTZVJ+yfJE5M=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=p+VgVDl3MFJs6z2+DG1V5vfqIYo7QWNSH7N0TQWpGs/KadZvzkMxPCGOKXX1ve/uX5zGG0G9Vl9vYhv3KaqU+7TQfZSyeDnUQ9WdAea+gdlZlrLQAbFuyUJTco5R9cA9AInKqhtS7vcJal656garizzl/OprrB3HVRuF0rmQnMw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=PyQNkCEf; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="PyQNkCEf" Received: from pps.filterd (m0279873.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 50A3bXlF002584; Fri, 10 Jan 2025 04:25:47 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= zUxTMGrvGjMqDRFhH9O3tWFiOsTfUpOsT55imAWxmno=; b=PyQNkCEfyLnB1D29 SVuIEgYDefEkDuzVNHc5cESjpWzOdLo9egji8WvERmK8JAwMuejND/DlH9rtp1v9 uRQT8FTGQYEjiTD0bnqvA9WbnY4kSgtLJ75SN/KAQ0cS63zf+NoV9a8jYdATSGNr +Pa1RVig14dWF7CXsQbSX+7srizkVl6HYDr9adkTseo6fGrZ9SDuxEXBYPjHRIwr ocMOvvz/KQH/ZJeTdmX6b7/VqSjDV9VvKee7EQPJbMIMHENmj/zcVTw4uo+AiuXi fApYjIpil7TowhyvVnnNWrSNn7QjXbX84Yi/uVDtGUkvEVCNy3vO1GvBMPzvnNrC ufboOQ== Received: from nasanppmta03.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 442uteg2ky-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jan 2025 04:25:47 +0000 (GMT) Received: from nasanex01c.na.qualcomm.com (nasanex01c.na.qualcomm.com [10.45.79.139]) by NASANPPMTA03.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id 50A4Pkwd002288 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jan 2025 04:25:46 GMT Received: from hu-sarishar-blr.qualcomm.com (10.80.80.8) by nasanex01c.na.qualcomm.com (10.45.79.139) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.9; Thu, 9 Jan 2025 20:25:44 -0800 From: Sarika Sharma To: CC: , Sarika Sharma Subject: [PATCH RFC 5/7] wifi: mac80211: add support to accumulate removed link statistics Date: Fri, 10 Jan 2025 09:54:47 +0530 Message-ID: <20250110042449.1158789-6-quic_sarishar@quicinc.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250110042449.1158789-1-quic_sarishar@quicinc.com> References: <20250110042449.1158789-1-quic_sarishar@quicinc.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nasanex01c.na.qualcomm.com (10.45.79.139) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: wHLh0P_hRF37bjTNsGORHSkxPevZ-hRZ X-Proofpoint-ORIG-GUID: wHLh0P_hRF37bjTNsGORHSkxPevZ-hRZ X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.60.29 definitions=2024-09-06_09,2024-09-06_01,2024-09-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 spamscore=0 mlxlogscore=993 lowpriorityscore=0 adultscore=0 bulkscore=0 impostorscore=0 suspectscore=0 mlxscore=0 phishscore=0 malwarescore=0 priorityscore=1501 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2411120000 definitions=main-2501100034 Currently, if a link gets removed in between for a station then directly accumulated data will fall down to sum of other active links. This will bring inconsistency in station dump statistics. For instance, let's take Tx packets - at t=0-> link-0:2 link-1:3 Tx packets => accumulated = 5 - at t=1-> link-0:4 link-1:6 Tx packets => accumulated = 10 let say at t=2, link-0 went down => link-0:0 link-1:7 => accumulated = 7 Here, suddenly accumulated Tx packets will come down to 7 from 10. This is showing inconsistency. Therefore, store link-0 data when it went down and add to accumulated Tx packet = 11. Hence, store the removed link statistics data in sta structure and add it in accumulated statistics for consistency. Signed-off-by: Sarika Sharma --- net/mac80211/sta_info.c | 30 ++++++++++++++++++++++++++++++ net/mac80211/sta_info.h | 28 ++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index f4492174d2c4..4b78b03b1047 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -356,6 +356,24 @@ static void sta_info_free_link(struct link_sta_info *link_sta) free_percpu(link_sta->pcpu_rx_stats); } +static void sta_accumulate_removed_link_stats(struct sta_info *sta, int link_id) +{ + struct link_sta_info *link_sta = + rcu_dereference_protected(sta->link[link_id], + lockdep_is_held(&sta->local->hw.wiphy->mtx)); + int ac; + + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { + sta->rem_link_stats.tx_packets += link_sta->tx_stats.packets[ac]; + sta->rem_link_stats.tx_bytes += link_sta->tx_stats.bytes[ac]; + } + + sta->rem_link_stats.rx_packets += link_sta->rx_stats.packets; + sta->rem_link_stats.rx_bytes += link_sta->rx_stats.bytes; + sta->rem_link_stats.tx_retries += link_sta->status_stats.retry_count; + sta->rem_link_stats.tx_failed += link_sta->status_stats.retry_failed; +} + static void sta_remove_link(struct sta_info *sta, unsigned int link_id, bool unhash) { @@ -378,6 +396,10 @@ static void sta_remove_link(struct sta_info *sta, unsigned int link_id, alloc = container_of(link_sta, typeof(*alloc), info); sta->sta.valid_links &= ~BIT(link_id); + + /* store removed link info for accumulated stats consistency */ + sta_accumulate_removed_link_stats(sta, link_id); + RCU_INIT_POINTER(sta->link[link_id], NULL); RCU_INIT_POINTER(sta->sta.link[link_id], NULL); if (alloc) { @@ -2883,6 +2905,14 @@ static void sta_set_mld_sinfo(struct station_info *sinfo, struct sta_info *sta) sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); } } + + /* Add accumulated removed link data to sinfo data for consistency */ + sinfo->tx_packets += sta->rem_link_stats.tx_packets; + sinfo->rx_packets += sta->rem_link_stats.rx_packets; + sinfo->tx_bytes += sta->rem_link_stats.tx_bytes; + sinfo->rx_bytes += sta->rem_link_stats.rx_bytes; + sinfo->tx_retries += sta->rem_link_stats.tx_retries; + sinfo->tx_failed += sta->rem_link_stats.tx_failed; } void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo, diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 1d82519319fe..2ddea966d500 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -569,6 +569,32 @@ struct link_sta_info { struct ieee80211_link_sta *pub; }; +/** + * struct ieee80211_sta_removed_link_stats - Removed link sta data + * + * keep required accumulated removed link data for stats + * + * @rx_packets: accumulated packets (MSDUs & MMPDUs) received from + * this station for removed links + * @tx_packets: accumulated packets (MSDUs & MMPDUs) transmitted to + * this station for removed links + * @rx_bytes: accumulated bytes (size of MPDUs) received from this + * station for removed links + * @tx_bytes: accumulated bytes (size of MPDUs) transmitted to this + * station for removed links + * @tx_retries: cumulative retry counts (MPDUs) for removed links + * @tx_failed: accumulated number of failed transmissions (MPDUs) + * (retries exceeded, no ACK) for removed links + */ +struct ieee80211_sta_removed_link_stats { + u32 rx_packets; + u32 tx_packets; + u64 rx_bytes; + u64 tx_bytes; + u32 tx_retries; + u32 tx_failed; +}; + /** * struct sta_info - STA information * @@ -646,6 +672,7 @@ struct link_sta_info { * @deflink address and remaining would be allocated and the address * would be assigned to link[link_id] where link_id is the id assigned * by the AP. + * @rem_link_stats: accumulated removed link stats */ struct sta_info { /* General information, mostly static */ @@ -722,6 +749,7 @@ struct sta_info { struct ieee80211_sta_aggregates cur; struct link_sta_info deflink; struct link_sta_info __rcu *link[IEEE80211_MLD_MAX_NUM_LINKS]; + struct ieee80211_sta_removed_link_stats rem_link_stats; /* keep last! */ struct ieee80211_sta sta; From patchwork Fri Jan 10 04:24:48 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sarika Sharma X-Patchwork-Id: 13933574 X-Patchwork-Delegate: johannes@sipsolutions.net Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 035F3126C10 for ; Fri, 10 Jan 2025 04:26:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736483171; cv=none; b=KmgkDo2fwufc3BKbuqJzUtGKGMo5xYAHA+R/2Qolw1hl9xREv7XSbXJqSn4SCQfwG3PhptNK+SC1xnqUlzNTbdhX0DjGaMnvi+QUT5cVT41QfFx69213h5ASwpatihkXv3jqFeHoCCZrMcfFVETcBREDv5COxApCom/vbkW8kOQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736483171; c=relaxed/simple; bh=PRAywbvg2qtPecU+jGpfi6FcxK3jK8whm8R25J6dxjU=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Ub7++RrIenuMLDHTgKVT2MtVpM3PLHChkWMyhcD5NpXoXSNd2R9/VhwoHg4r//fiLKPzh8BonkDVzU39B4LbLN11DUOYUvoKfIoosemwh+n7n0O/CI6rY2W0u2gbumyhwjtzsIfYnl0zyuEe0kQdc8uKdl05cIlquVL9u8SZ30E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=gTyTms4q; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="gTyTms4q" Received: from pps.filterd (m0279872.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 509K1ioQ030498; Fri, 10 Jan 2025 04:25:49 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= L216Zcny7vXCBxEvO3/iRLrPZ1CrDlWfrZTI5JxqV38=; b=gTyTms4qGKs86NNV gH6lMpHtGU1BIrd9y0VQEu7dRCINs3Nhg2q+xudrWdJcyZfcoiCrQ30lW5yzqZ1Z osnGDvjbRvSxZo7ORS2wc9iR8lV8tnTNINg7RZFjRT+Nj4CCFYcZfVo25pyWPyvQ nJmFH2kNhSG0JkyRbJ809cLUboLaGl7LbNEhr1mFUb2Lyv+f8UGk7eebPzXGXe17 QR2vkPQon31Wj5w97rMZ/68NUXdpvx6zrT6+q/gtJilDF2jCS8ej3mET3WXpKe2h 7KBinQ/l3+fMMDYTXK3qZw7qfJUMoxX+js42c6jfmt60zq/LQpd/dcWGM98ABd8m LGE2CQ== Received: from nasanppmta03.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 442n4r0x8t-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jan 2025 04:25:48 +0000 (GMT) Received: from nasanex01c.na.qualcomm.com (nasanex01c.na.qualcomm.com [10.45.79.139]) by NASANPPMTA03.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id 50A4PmbC002301 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jan 2025 04:25:48 GMT Received: from hu-sarishar-blr.qualcomm.com (10.80.80.8) by nasanex01c.na.qualcomm.com (10.45.79.139) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.9; Thu, 9 Jan 2025 20:25:46 -0800 From: Sarika Sharma To: CC: , Sarika Sharma Subject: [PATCH RFC 6/7] wifi: cfg80211: add additional MLO statistics Date: Fri, 10 Jan 2025 09:54:48 +0530 Message-ID: <20250110042449.1158789-7-quic_sarishar@quicinc.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250110042449.1158789-1-quic_sarishar@quicinc.com> References: <20250110042449.1158789-1-quic_sarishar@quicinc.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nasanex01c.na.qualcomm.com (10.45.79.139) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: HF-EP4WfADhuEmhJ0maGKbPdkx7P04lq X-Proofpoint-ORIG-GUID: HF-EP4WfADhuEmhJ0maGKbPdkx7P04lq X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.60.29 definitions=2024-09-06_09,2024-09-06_01,2024-09-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 phishscore=0 spamscore=0 impostorscore=0 clxscore=1015 malwarescore=0 adultscore=0 bulkscore=0 lowpriorityscore=0 mlxlogscore=977 mlxscore=0 priorityscore=1501 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2411120000 definitions=main-2501100034 Currently, the accumulable statistics for multi-link operation(MLO) are handled. Other statistics, such as signal and rates, are managed at the link level. Therefore, add signal and rates at the MLO level to provide an comprehensive overview of the station. The signal could be the best of all links- e.g. if Link 1 has a signal strength of -70 dBm and Link 2 has -65 dBm, the signal for MLO will be -65 dBm. The rate could be determined based on the most recently updated link- e.g. if link 1 has a rate of 300 Mbps and link 2 has a rate of 450 Mbps, the MLO rate can be calculated based on the inactivity of each link. If the inactive time for link 1 is 20 seconds and for link 2 is 10 seconds, the MLO rate will be the most recently updated rate, which is link 2's rate of 450 Mbps. NOTE: - Currently using one of the link to fill rate and signal. Could add the last updated for rate and best of signal for MLO with actual patches. Signed-off-by: Sarika Sharma --- include/net/cfg80211.h | 7 +++++++ net/mac80211/sta_info.c | 44 +++++++++++++++++++++++++++++++++++++++++ net/wireless/nl80211.c | 25 +++++++++++++++++++++-- 3 files changed, 74 insertions(+), 2 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index ac038903d53e..30231855be1f 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -2180,6 +2180,10 @@ struct link_station_info { * @tx_bytes: bytes (size of MPDUs) transmitted to this station * @tx_retries: cumulative retry counts (MPDUs) * @tx_failed: number of failed transmissions (MPDUs) (retries exceeded, no ACK) + * @signal: The signal strength, type depends on the wiphy's signal_type. + * For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_. + * @txrate: last updated unicast bitrate from this station + * @rxrate: last updated unicast bitrate to this station * @deflink: This holds the default link STA information, for non MLO STA * all link specific STA information is accessed through @deflink. * @links: reference to Link sta entries for MLO. @@ -2218,6 +2222,9 @@ struct station_info { u64 tx_bytes; u32 tx_retries; u32 tx_failed; + s8 signal; + struct rate_info txrate; + struct rate_info rxrate; struct link_station_info deflink; /* TODO: Need to check and add protection access to links memory */ diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 4b78b03b1047..2cad17cb64d7 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -2858,6 +2858,33 @@ static void sta_set_link_sinfo(struct sta_info *sta, struct link_station_info *l } } +static void sta_set_mld_rate_info(struct rate_info *sinfo_rate, + struct rate_info *link_sinfo_rate) +{ + if (link_sinfo_rate->flags) + sinfo_rate->flags = link_sinfo_rate->flags; + if (link_sinfo_rate->legacy) + sinfo_rate->legacy = link_sinfo_rate->legacy; + if (link_sinfo_rate->mcs) + sinfo_rate->mcs = link_sinfo_rate->mcs; + if (link_sinfo_rate->nss) + sinfo_rate->nss = link_sinfo_rate->nss; + if (link_sinfo_rate->bw) + sinfo_rate->bw = link_sinfo_rate->bw; + if (link_sinfo_rate->he_gi) + sinfo_rate->he_gi = link_sinfo_rate->he_gi; + if (link_sinfo_rate->he_dcm) + sinfo_rate->he_dcm = link_sinfo_rate->he_dcm; + if (link_sinfo_rate->he_ru_alloc) + sinfo_rate->he_ru_alloc = link_sinfo_rate->he_ru_alloc; + if (link_sinfo_rate->n_bonded_ch) + sinfo_rate->n_bonded_ch = link_sinfo_rate->n_bonded_ch; + if (link_sinfo_rate->eht_gi) + sinfo_rate->eht_gi = link_sinfo_rate->eht_gi; + if (link_sinfo_rate->eht_ru_alloc) + sinfo_rate->eht_ru_alloc = link_sinfo_rate->eht_ru_alloc; +} + static void sta_set_mld_sinfo(struct station_info *sinfo, struct sta_info *sta) { struct link_station_info *link_sinfo; @@ -2913,6 +2940,23 @@ static void sta_set_mld_sinfo(struct station_info *sinfo, struct sta_info *sta) sinfo->rx_bytes += sta->rem_link_stats.rx_bytes; sinfo->tx_retries += sta->rem_link_stats.tx_retries; sinfo->tx_failed += sta->rem_link_stats.tx_failed; + + /*TODO: set mld stats for signal based on best values and signal + * for last updated, currently using one of the link to fill stats + */ + if (link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_SIGNAL)) { + sinfo->signal = link_sinfo->signal; + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL); + } + if (link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_BITRATE)) { + sta_set_mld_rate_info(&sinfo->txrate, &link_sinfo->txrate); + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); + } + + if (link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_BITRATE)) { + sta_set_mld_rate_info(&sinfo->rxrate, &link_sinfo->rxrate); + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BITRATE); + } } void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo, diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 06688aa1780f..99d74f67b1a2 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -6839,7 +6839,8 @@ static int nl80211_fill_link_station(struct sk_buff *msg, } static int nl80211_fill_mld_station(struct sk_buff *msg, - struct station_info *sinfo) + struct station_info *sinfo, + struct cfg80211_registered_device *rdev) { #define PUT_SINFO(attr, memb, type) do { \ BUILD_BUG_ON(sizeof(type) == sizeof(u64)); \ @@ -6862,9 +6863,29 @@ static int nl80211_fill_mld_station(struct sk_buff *msg, PUT_SINFO(TX_RETRIES, tx_retries, u32); PUT_SINFO(TX_FAILED, tx_failed, u32); + switch (rdev->wiphy.signal_type) { + case CFG80211_SIGNAL_TYPE_MBM: + PUT_SINFO(SIGNAL, signal, u8); + break; + default: + break; + } + #undef PUT_SINFO #undef PUT_SINFO_U64 + if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_BITRATE)) { + if (!nl80211_put_sta_rate(msg, &sinfo->txrate, + NL80211_STA_INFO_TX_BITRATE)) + return -EMSGSIZE; + } + + if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_BITRATE)) { + if (!nl80211_put_sta_rate(msg, &sinfo->rxrate, + NL80211_STA_INFO_RX_BITRATE)) + return -EMSGSIZE; + } + return 0; } @@ -6942,7 +6963,7 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid, #undef PUT_SINFO_U64 if (sinfo->valid_links) { - ret = nl80211_fill_mld_station(msg, sinfo); + ret = nl80211_fill_mld_station(msg, sinfo, rdev); if (ret) goto nla_put_failure; From patchwork Fri Jan 10 04:24:49 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sarika Sharma X-Patchwork-Id: 13933571 X-Patchwork-Delegate: kvalo@adurom.com Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 18C1B1E32C5 for ; Fri, 10 Jan 2025 04:26:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736483165; cv=none; b=V6EPIWmk64fY1IPpmDmidaYovpssZP60a7u3W34D2PPtbq930A2AlMBnzj4RdsN7qhcgjdqMMLlGYl/l487woYVW4QbDd/3gpssAhnZsmiXbsmHklqFyROY5rFC+JqPNfchTPhqcwTugaGGBa6ymocwGZKo1eVWn1M+hpRS6ICU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736483165; c=relaxed/simple; bh=HfPcIyw/R8RqLH53BqGALZn9JN+wvIdSTchRnyyjvuY=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=X3dnYaQNx4wsB+4ezO7nBbpRJV2WgF2yXhIvnVRDCRvUMFMHrxV1lm5OhSsxdHVwjAbHI9URU7xd2DWbRajx+aWquGu2kpsrFPZfHK3ufVzDIp82ozeOJuTcvVeiSuFUGSbcYhM6NkUF3hvHUG7Ija/PvALVmbFCP+NqQmR/H9I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=GU+a4U9C; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="GU+a4U9C" Received: from pps.filterd (m0279864.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 509HItus012233; Fri, 10 Jan 2025 04:25:50 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= fADG9n2TNBBTpZ+OMHAaVomwc1MUgWg3dEIiNgaCLZc=; b=GU+a4U9CRjx/OD+n ETo41PI7lN0HYdTHApNO74cnRlaUzT8oiSMemYigyQBDerXkYkE4tuQj/VxDAB6C yofEz2hHGwQkkz0OEB9e5RDKQlHtHOFxO/Yh1bzXGcuFH3hHUa0I4Rd9+dep9rvW uKdUD6aKAbeTtKVEdMsBgyqgHjB/kZUPEzZlqgJCIaveEeRA+n3mL5UqEiolmLyS nR+f0LGxmzmf7D67mCS+nAYT5Xwl/GW5QoTjcYIrOWxDohQRofppifob3e3rlcCy TIlVSRLNs5YknYkqAn6cEcSjpNQsveIw0dl7agGhAeUIbMQR4IsdUQ3CRmo3FSKT 0wArgg== Received: from nasanppmta04.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 442jra98ws-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jan 2025 04:25:50 +0000 (GMT) Received: from nasanex01c.na.qualcomm.com (nasanex01c.na.qualcomm.com [10.45.79.139]) by NASANPPMTA04.qualcomm.com (8.18.1.2/8.18.1.2) with ESMTPS id 50A4PnTv004748 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jan 2025 04:25:49 GMT Received: from hu-sarishar-blr.qualcomm.com (10.80.80.8) by nasanex01c.na.qualcomm.com (10.45.79.139) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.9; Thu, 9 Jan 2025 20:25:48 -0800 From: Sarika Sharma To: CC: , Sarika Sharma Subject: [PATCH RFC 7/7] wifi: ath12k: correctly fetch arsta for MLO Date: Fri, 10 Jan 2025 09:54:49 +0530 Message-ID: <20250110042449.1158789-8-quic_sarishar@quicinc.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250110042449.1158789-1-quic_sarishar@quicinc.com> References: <20250110042449.1158789-1-quic_sarishar@quicinc.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nasanex01c.na.qualcomm.com (10.45.79.139) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: zyYeKhJXLMXQFN1X6HdO77yoUK_zbLje X-Proofpoint-ORIG-GUID: zyYeKhJXLMXQFN1X6HdO77yoUK_zbLje X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.60.29 definitions=2024-09-06_09,2024-09-06_01,2024-09-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 adultscore=0 priorityscore=1501 malwarescore=0 lowpriorityscore=0 impostorscore=0 phishscore=0 mlxscore=0 bulkscore=0 spamscore=0 clxscore=1015 mlxlogscore=515 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2411120000 definitions=main-2501100034 Currently in ath12k_mac_op_link_sta_statistics(), link sinfo structure is filled from arsta structure and arsta is fetched from ahsta->deflink. For both non-ML and multi-link operation (MLO), deflink is used. While this is correct for non-ML, but the corresponding link_id should be used for MLO. Therefore, add support for MLO by taking the link_id from the link_sinfo structure, fetching arsta from ahsta->link[link_id], and filling the link_sinfo structure if valid_links. NOTE: - Currently ath12k changes are only included as an reference to other drivers. Signed-off-by: Sarika Sharma --- drivers/net/wireless/ath/ath12k/mac.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index ebde8a604eec..1bafda3c83aa 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -9902,11 +9902,18 @@ static void ath12k_mac_op_link_sta_statistics(struct ieee80211_hw *hw, struct link_station_info *link_sinfo) { struct ath12k_sta *ahsta = ath12k_sta_to_ahsta(sta); + int link_id = link_sinfo->link_id; struct ath12k_link_sta *arsta; lockdep_assert_wiphy(hw->wiphy); - arsta = &ahsta->deflink; + if (link_id < 0) + arsta = &ahsta->deflink; + else + arsta = wiphy_dereference(hw->wiphy, ahsta->link[link_id]); + + if (!arsta) + return; link_sinfo->rx_duration = arsta->rx_duration; link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_DURATION);