From patchwork Fri Feb 25 23:28:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Greear X-Patchwork-Id: 546408 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2818BC433F5 for ; Fri, 25 Feb 2022 23:28:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239258AbiBYX3W (ORCPT ); Fri, 25 Feb 2022 18:29:22 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58028 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230190AbiBYX3V (ORCPT ); Fri, 25 Feb 2022 18:29:21 -0500 Received: from dispatch1-us1.ppe-hosted.com (dispatch1-us1.ppe-hosted.com [67.231.154.183]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E08F912341F for ; Fri, 25 Feb 2022 15:28:47 -0800 (PST) X-Virus-Scanned: Proofpoint Essentials engine Received: from mx1-us1.ppe-hosted.com (unknown [10.110.51.164]) by mx1-us1.ppe-hosted.com (PPE Hosted ESMTP Server) with ESMTPS id 6C023A0074 for ; Fri, 25 Feb 2022 23:28:46 +0000 (UTC) Received: from mail3.candelatech.com (mail2.candelatech.com [208.74.158.173]) by mx1-us1.ppe-hosted.com (PPE Hosted ESMTP Server) with ESMTP id 3F9B7B00072 for ; Fri, 25 Feb 2022 23:28:46 +0000 (UTC) Received: from ben-dt4.candelatech.com (50-251-239-81-static.hfc.comcastbusiness.net [50.251.239.81]) by mail3.candelatech.com (Postfix) with ESMTP id A8D8113C2B0; Fri, 25 Feb 2022 15:28:45 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 mail3.candelatech.com A8D8113C2B0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=candelatech.com; s=default; t=1645831725; bh=0KnkVM0jE2CErxS79Sa2/Q5kulSfZbpWM9FmwF87zAg=; h=From:To:Cc:Subject:Date:From; b=fDScoqeJMKumnjj60tfORh/pWEzPcqBrUNKQym7yGzl6fHy7onVkfDuoimqAQEtQs JAnFfmgosJmi94cL4x0XAatb3nJYnJEpETryMT52rr2aGPgsR+nVFB+hWngkeBGuDJ 3qtecPYb6k1Lc+r5VD0CDSZJmvTADCUG29zAaImM= From: greearb@candelatech.com To: linux-wireless@vger.kernel.org Cc: Ben Greear Subject: [PATCH 1/2] mac80211: Allow drivers to report avg chain signal. Date: Fri, 25 Feb 2022 15:28:41 -0800 Message-Id: <20220225232842.32028-1-greearb@candelatech.com> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 X-MDID: 1645831726-m_09h8JzGjcz Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Ben Greear Drivers that use RSS cannot get the avg signal from mac80211. So allow drivers to report the avg chain signal while letting mac80211 take care of the last chain signal. Signed-off-by: Ben Greear --- net/mac80211/sta_info.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 43a58b30c6a4..00836f587b6d 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -2543,6 +2543,7 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo, if (last_rxstats->chains && !(sinfo->filled & (BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL) | BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG)))) { + /* Neither chain signal nor chain signal avg is filled */ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL); if (!sta->pcpu_rx_stats) sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG); @@ -2557,6 +2558,21 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo, } } + /* Check if chain signal is not filled, for cases avg was filled by + * driver bug last chain signal was not. + */ + if (last_rxstats->chains && + !(sinfo->filled & (BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL)))) { + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL); + + sinfo->chains = last_rxstats->chains; + + for (i = 0; i < ARRAY_SIZE(sinfo->chain_signal); i++) { + sinfo->chain_signal[i] = + last_rxstats->chain_signal_last[i]; + } + } + if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_BITRATE))) { sta_set_rate_info_tx(sta, &sta->tx_stats.last_rate, &sinfo->txrate); From patchwork Fri Feb 25 23:28:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Greear X-Patchwork-Id: 546165 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 547A9C433EF for ; Fri, 25 Feb 2022 23:28:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239323AbiBYX3Y (ORCPT ); Fri, 25 Feb 2022 18:29:24 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58216 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230190AbiBYX3X (ORCPT ); Fri, 25 Feb 2022 18:29:23 -0500 Received: from dispatch1-us1.ppe-hosted.com (dispatch1-us1.ppe-hosted.com [67.231.154.183]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7092512341F for ; Fri, 25 Feb 2022 15:28:50 -0800 (PST) X-Virus-Scanned: Proofpoint Essentials engine Received: from mx1-us1.ppe-hosted.com (unknown [10.110.51.178]) by mx1-us1.ppe-hosted.com (PPE Hosted ESMTP Server) with ESMTPS id C95D5A0072 for ; Fri, 25 Feb 2022 23:28:48 +0000 (UTC) Received: from mail3.candelatech.com (mail2.candelatech.com [208.74.158.173]) by mx1-us1.ppe-hosted.com (PPE Hosted ESMTP Server) with ESMTP id 8EA76B00073 for ; Fri, 25 Feb 2022 23:28:48 +0000 (UTC) Received: from ben-dt4.candelatech.com (50-251-239-81-static.hfc.comcastbusiness.net [50.251.239.81]) by mail3.candelatech.com (Postfix) with ESMTP id C519213C2B1; Fri, 25 Feb 2022 15:28:46 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 mail3.candelatech.com C519213C2B1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=candelatech.com; s=default; t=1645831726; bh=SOgNkJ+tVvxCbhPn62IQ55zzD8Q07mwJTViJe/ax/KY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PDONa9t1yTukSa/M6tVt+2HceAxQZyR13YPHV5f9OgfP1hPG4OdE06HjkVNeFHq5X +i7gLInYYIfr+xpvpXSG27KG0CiaQ4V0hvehmfS6sPZnHLYdRRi5QGpnqlQsk01KzE ZuswufbHGrKmhtw29ZdKgu3jwxGJPEId291iirR0= From: greearb@candelatech.com To: linux-wireless@vger.kernel.org Cc: Ben Greear Subject: [PATCH 2/2] iwlwifi: RX signal improvements. Date: Fri, 25 Feb 2022 15:28:42 -0800 Message-Id: <20220225232842.32028-2-greearb@candelatech.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20220225232842.32028-1-greearb@candelatech.com> References: <20220225232842.32028-1-greearb@candelatech.com> MIME-Version: 1.0 X-MDID: 1645831729-Yj5OanO9O2gZ Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Ben Greear Sum up multi-chain signals instead of just taking the maximum value. This gives more correct total on-air signal value. And, the firmware managed averages do not match expected per-packet values, so ignore those for MQ drivers and instead calculate averages in the driver and report that. Combined with the previous patch, this gives better looking RX signal report: signal: -39 [-42, -41] dBm signal avg: -39 [-42, -41] dBm beacon signal avg: -46 dBm Signed-off-by: Ben Greear --- .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 38 ++++++++++++++--- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 34 +++++++++++++++ drivers/net/wireless/intel/iwlwifi/mvm/rx.c | 4 +- drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 41 ++++++++++++++++--- drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 5 +++ drivers/net/wireless/intel/iwlwifi/mvm/sta.h | 7 ++++ 6 files changed, 117 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 959ad85e3430..c11b20d847f3 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -4869,9 +4869,32 @@ static void iwl_mvm_mac_sta_statistics(struct ieee80211_hw *hw, struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); - if (mvmsta->avg_energy) { - sinfo->signal_avg = -(s8)mvmsta->avg_energy; + if (iwl_mvm_has_new_rx_api(mvm)) { /* rxmq logic */ + /* Grab chain signal avg, mac80211 cannot do it because + * this driver uses RSS. Grab signal_avg here too because firmware + * appears go not do DB summing and/or has other bugs. --Ben + */ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); + sinfo->signal_avg = -ewma_signal_read(&mvmsta->rx_avg_signal); + + if (!mvmvif->bf_data.bf_enabled) { + /* The firmware reliably reports different signal (2db weaker in my case) + * than if I calculate it from the rx-status. So, fill that here. + * Beacons are only received if you turn off beacon filtering, however. + */ + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_BEACON_SIGNAL_AVG); + sinfo->rx_beacon_signal_avg = -ewma_signal_read(&mvmsta->rx_avg_beacon_signal); + } + + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG); + sinfo->chain_signal_avg[0] = -ewma_signal_read(&mvmsta->rx_avg_chain_signal[0]); + sinfo->chain_signal_avg[1] = -ewma_signal_read(&mvmsta->rx_avg_chain_signal[1]); + } + else { + if (mvmsta->avg_energy) { + sinfo->signal_avg = -(s8)mvmsta->avg_energy; + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); + } } if (iwl_mvm_has_tlc_offload(mvm)) { @@ -4899,10 +4922,13 @@ static void iwl_mvm_mac_sta_statistics(struct ieee80211_hw *hw, sinfo->rx_beacon = mvmvif->beacon_stats.num_beacons + mvmvif->beacon_stats.accu_num_beacons; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_BEACON_RX); - if (mvmvif->beacon_stats.avg_signal) { - /* firmware only reports a value after RXing a few beacons */ - sinfo->rx_beacon_signal_avg = mvmvif->beacon_stats.avg_signal; - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_BEACON_SIGNAL_AVG); + + if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_BEACON_SIGNAL_AVG))) { + if (mvmvif->beacon_stats.avg_signal) { + /* firmware only reports a value after RXing a few beacons */ + sinfo->rx_beacon_signal_avg = mvmvif->beacon_stats.avg_signal; + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_BEACON_SIGNAL_AVG); + } } unlock: mutex_unlock(&mvm->mutex); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index cd5645c3d15c..421094477edd 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -2150,4 +2150,38 @@ enum iwl_location_cipher iwl_mvm_cipher_to_location_cipher(u32 cipher) return IWL_LOCATION_CIPHER_INVALID; } } + +static inline int iwl_mvm_sum_sigs_2(int a, int b) +{ + int diff; + + /* S8_MIN means value-is-not-set */ + if (b == S8_MIN) + return a; + if (a == S8_MIN) + return b; + + if (a >= b) { + /* a is largest value, add to it. */ + diff = a - b; + if (diff == 0) + return a + 3; + else if (diff <= 2) + return a + 2; + else if (diff <= 6) + return a + 1; + return a; + } else { + /* b is largest value, add to it. */ + diff = b - a; + if (diff == 0) + return b + 3; + else if (diff <= 2) + return b + 2; + else if (diff <= 6) + return b + 1; + return b; + } +} + #endif /* __IWL_MVM_H__ */ diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c index d22f40a5354d..e8d753e855e1 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c @@ -114,7 +114,9 @@ static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm, energy_b = (val & IWL_RX_INFO_ENERGY_ANT_B_MSK) >> IWL_RX_INFO_ENERGY_ANT_B_POS; energy_b = energy_b ? -energy_b : S8_MIN; - max_energy = max(energy_a, energy_b); + + /* use DB summing to get better RSSI reporting */ + max_energy = iwl_mvm_sum_sigs_2(energy_a, energy_b); IWL_DEBUG_STATS(mvm, "energy In A %d B %d , and max %d\n", energy_a, energy_b, max_energy); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index 31a8c5083f61..489f8a843f82 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -278,14 +278,26 @@ static void iwl_mvm_pass_packet_to_mac80211(struct iwl_mvm *mvm, static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm, struct ieee80211_rx_status *rx_status, u32 rate_n_flags, int energy_a, - int energy_b) + int energy_b, struct ieee80211_sta *sta, + bool is_beacon, bool my_beacon) { int max_energy; u32 rate_flags = rate_n_flags; + struct iwl_mvm_sta *mvmsta = NULL; + + if (sta && !(is_beacon && !my_beacon)) { + mvmsta = iwl_mvm_sta_from_mac80211(sta); + if (energy_a) + ewma_signal_add(&mvmsta->rx_avg_chain_signal[0], energy_a); + if (energy_b) + ewma_signal_add(&mvmsta->rx_avg_chain_signal[1], energy_b); + } energy_a = energy_a ? -energy_a : S8_MIN; energy_b = energy_b ? -energy_b : S8_MIN; - max_energy = max(energy_a, energy_b); + + /* use DB summing to get better RSSI reporting */ + max_energy = iwl_mvm_sum_sigs_2(energy_a, energy_b); IWL_DEBUG_STATS(mvm, "energy In A %d B %d, and max %d\n", energy_a, energy_b, max_energy); @@ -295,6 +307,15 @@ static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm, (rate_flags & RATE_MCS_ANT_AB_MSK) >> RATE_MCS_ANT_POS; rx_status->chain_signal[0] = energy_a; rx_status->chain_signal[1] = energy_b; + + if (mvmsta) { + if (is_beacon) { + if (my_beacon) + ewma_signal_add(&mvmsta->rx_avg_beacon_signal, -max_energy); + } else { + ewma_signal_add(&mvmsta->rx_avg_signal, -max_energy); + } + } } static int iwl_mvm_rx_mgmt_prot(struct ieee80211_sta *sta, @@ -1685,6 +1706,8 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, }; u32 format; bool is_sgi; + bool is_beacon; + bool my_beacon = false; if (unlikely(test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))) return; @@ -1828,8 +1851,6 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, } rx_status->freq = ieee80211_channel_to_frequency(channel, rx_status->band); - iwl_mvm_get_signal_strength(mvm, rx_status, rate_n_flags, energy_a, - energy_b); /* update aggregation data for monitor sake on default queue */ if (!queue && (phy_info & IWL_RX_MPDU_PHY_AMPDU)) { @@ -1878,6 +1899,16 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, goto out; } + is_beacon = ieee80211_is_beacon(hdr->frame_control); + if (is_beacon && sta) { + /* see if it is beacon destined for us */ + if (memcmp(sta->addr, hdr->addr2, ETH_ALEN) == 0) + my_beacon = true; + } + + iwl_mvm_get_signal_strength(mvm, rx_status, rate_n_flags, energy_a, + energy_b, sta, is_beacon, my_beacon); + if (sta) { struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); struct ieee80211_vif *tx_blocked_vif = @@ -2138,7 +2169,7 @@ void iwl_mvm_rx_monitor_no_data(struct iwl_mvm *mvm, struct napi_struct *napi, rx_status->freq = ieee80211_channel_to_frequency(channel, rx_status->band); iwl_mvm_get_signal_strength(mvm, rx_status, rate_n_flags, energy_a, - energy_b); + energy_b, sta, false, false); rcu_read_lock(); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c index a64874c05ced..e54051830f1a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c @@ -1577,6 +1577,11 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm, spin_lock_init(&mvm_sta->lock); + ewma_signal_init(&mvm_sta->rx_avg_chain_signal[0]); + ewma_signal_init(&mvm_sta->rx_avg_chain_signal[1]); + ewma_signal_init(&mvm_sta->rx_avg_signal); + ewma_signal_init(&mvm_sta->rx_avg_beacon_signal); + /* if this is a HW restart re-alloc existing queues */ if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) { struct iwl_mvm_int_sta tmp_sta = { diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.h b/drivers/net/wireless/intel/iwlwifi/mvm/sta.h index 32b4d1935788..4c86e33e1667 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.h @@ -10,6 +10,7 @@ #include #include #include +#include #include "iwl-trans.h" /* for IWL_MAX_TID_COUNT */ #include "fw-api.h" /* IWL_MVM_STATION_COUNT_MAX */ @@ -18,6 +19,9 @@ struct iwl_mvm; struct iwl_mvm_vif; +/* This makes us a 'struct ewma_signal {' object. */ +DECLARE_EWMA(signal, 10, 8); + /** * DOC: DQA - Dynamic Queue Allocation -introduction * @@ -415,6 +419,9 @@ struct iwl_mvm_sta { u8 sleep_tx_count; u8 avg_energy; u8 tx_ant; + struct ewma_signal rx_avg_chain_signal[2]; + struct ewma_signal rx_avg_signal; + struct ewma_signal rx_avg_beacon_signal; }; u16 iwl_mvm_tid_queued(struct iwl_mvm *mvm, struct iwl_mvm_tid_data *tid_data);