Received: by 2002:a25:d7c1:0:0:0:0:0 with SMTP id o184csp5426121ybg; Tue, 22 Oct 2019 03:07:08 -0700 (PDT) X-Google-Smtp-Source: APXvYqyEeAHJhKsliFF/dbthanNypBnbcvB30xmPfy6mAwMugz4o0q9ESnn0ljfGYau6fmRpDoVi X-Received: by 2002:a17:906:6a43:: with SMTP id n3mr26005588ejs.292.1571738828099; Tue, 22 Oct 2019 03:07:08 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1571738828; cv=none; d=google.com; s=arc-20160816; b=tsglqiRo/QmHP7+YaT4/8TCdUxrUmMzfrHQG9NiMDvRzszlySD+Op7YpEANIOgrGoo WqwJls9oNRXrAUUi+DZW8UnX9dRSpddNLzl+J27AQmMv6WyMPVJ0QYxAQvODgUUGNrcF 843AmWwMKfPU9grngzsDWCqiMPSIP0hSY11dvCAtXM3u+CcummP0FZOxc0USsdRpxj// sXu52NR1l9TFgF2ny0tJ8KA8PczctG19cbJYMAym5uAfowvGCRIJwJ8SkA5yU0vjYoXq +NMmitwEiSDROERbqve459Xue58pKPA6MAdh56WycgcrrsA0t8RRVqL8LltlXD7pnRTA imEw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:authenticated-by; bh=KmRATo3rnFAVvArY2uAVryC+bkpJmdd6o3qI8RKb07U=; b=w7lpRMm/XI45Fq9iPIl3cLp6VHvy88jzAihyD1Nj+yji8s0pFfEfeBszQpHJu68y2B iUnl+iYT+R4sHcnb31Y1Pa90ycsSw59MlmtUDKkm/GPECOGYKEgOx1JFGqK1LynaJtDB IM+ronKXczRWTEm6xzPufuiwIZqxfayg91uGJTF7bRo9/zxE1a5nFylfG+o5ZudPRHfL VdA8kzv6ki4CBDW90YPfMAXQef/e79y91k+M2q27+CR3h/z2nMaZJJA4rnsy2OtMYqps yXM9CodAXDri3FIlRr0dn6/dH97zlwpqt+HcphXvy74wzhLMkhvmY9Pzktsd8u+jaaKL XcGw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-wireless-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-wireless-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id t10si11186444edd.447.2019.10.22.03.06.43; Tue, 22 Oct 2019 03:07:07 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-wireless-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-wireless-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-wireless-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731734AbfJVKEb (ORCPT + 99 others); Tue, 22 Oct 2019 06:04:31 -0400 Received: from rtits2.realtek.com ([211.75.126.72]:37559 "EHLO rtits2.realtek.com.tw" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731635AbfJVKEa (ORCPT ); Tue, 22 Oct 2019 06:04:30 -0400 Authenticated-By: X-SpamFilter-By: BOX Solutions SpamTrap 5.62 with qID x9MA4PCW017644, This message is accepted by code: ctloc85258 Received: from mail.realtek.com (RTITCASV01.realtek.com.tw[172.21.6.18]) by rtits2.realtek.com.tw (8.15.2/2.57/5.78) with ESMTPS id x9MA4PCW017644 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT); Tue, 22 Oct 2019 18:04:25 +0800 Received: from localhost.localdomain (172.21.68.126) by RTITCASV01.realtek.com.tw (172.21.6.18) with Microsoft SMTP Server id 14.3.468.0; Tue, 22 Oct 2019 18:04:24 +0800 From: To: CC: , Subject: [PATCH v3 4/5] rtw88: add set_bitrate_mask support Date: Tue, 22 Oct 2019 18:04:19 +0800 Message-ID: <20191022100420.25116-5-yhchuang@realtek.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191022100420.25116-1-yhchuang@realtek.com> References: <20191022100420.25116-1-yhchuang@realtek.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [172.21.68.126] Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Tzu-En Huang Support setting bit rate from upper layer. After configuring the original rate control result in the driver, the result is then masked by the bit rate mask received from the ops set_bitrate_mask. Lastly, the masked result will be sent to firmware. Signed-off-by: Tzu-En Huang Signed-off-by: Yan-Hsuan Chuang --- v1 -> v2 * No change v2 -> v3 * use u64_encode_bits drivers/net/wireless/realtek/rtw88/mac80211.c | 53 +++++++++++++ drivers/net/wireless/realtek/rtw88/main.c | 78 +++++++++++++++---- drivers/net/wireless/realtek/rtw88/main.h | 3 + 3 files changed, 118 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c index bc04cc280a96..2247bd61e716 100644 --- a/drivers/net/wireless/realtek/rtw88/mac80211.c +++ b/drivers/net/wireless/realtek/rtw88/mac80211.c @@ -475,6 +475,8 @@ static int rtw_ops_sta_remove(struct ieee80211_hw *hw, for (i = 0; i < ARRAY_SIZE(sta->txq); i++) rtw_txq_cleanup(rtwdev, sta->txq[i]); + kfree(si->mask); + rtwdev->sta_cnt--; rtw_info(rtwdev, "sta %pM with macid %d left\n", @@ -684,6 +686,56 @@ static void rtw_ops_flush(struct ieee80211_hw *hw, mutex_unlock(&rtwdev->mutex); } +struct rtw_iter_bitrate_mask_data { + struct rtw_dev *rtwdev; + struct ieee80211_vif *vif; + const struct cfg80211_bitrate_mask *mask; +}; + +static void rtw_ra_mask_info_update_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtw_iter_bitrate_mask_data *br_data = data; + struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; + + if (si->vif != br_data->vif) + return; + + /* free previous mask setting */ + kfree(si->mask); + si->mask = kmemdup(br_data->mask, sizeof(struct cfg80211_bitrate_mask), + GFP_ATOMIC); + if (!si->mask) { + si->use_cfg_mask = false; + return; + } + + si->use_cfg_mask = true; + rtw_update_sta_info(br_data->rtwdev, si); +} + +static void rtw_ra_mask_info_update(struct rtw_dev *rtwdev, + struct ieee80211_vif *vif, + const struct cfg80211_bitrate_mask *mask) +{ + struct rtw_iter_bitrate_mask_data br_data; + + br_data.rtwdev = rtwdev; + br_data.vif = vif; + br_data.mask = mask; + rtw_iterate_stas_atomic(rtwdev, rtw_ra_mask_info_update_iter, &br_data); +} + +static int rtw_ops_set_bitrate_mask(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + const struct cfg80211_bitrate_mask *mask) +{ + struct rtw_dev *rtwdev = hw->priv; + + rtw_ra_mask_info_update(rtwdev, vif, mask); + + return 0; +} + const struct ieee80211_ops rtw_ops = { .tx = rtw_ops_tx, .wake_tx_queue = rtw_ops_wake_tx_queue, @@ -705,5 +757,6 @@ const struct ieee80211_ops rtw_ops = { .set_rts_threshold = rtw_ops_set_rts_threshold, .sta_statistics = rtw_ops_sta_statistics, .flush = rtw_ops_flush, + .set_bitrate_mask = rtw_ops_set_bitrate_mask, }; EXPORT_SYMBOL(rtw_ops); diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c index 47e74f0aec06..e53143132a9b 100644 --- a/drivers/net/wireless/realtek/rtw88/main.c +++ b/drivers/net/wireless/realtek/rtw88/main.c @@ -612,12 +612,71 @@ static u8 get_rate_id(u8 wireless_set, enum rtw_bandwidth bw_mode, u8 tx_num) #define RA_MASK_OFDM_IN_HT_2G 0x00010 #define RA_MASK_OFDM_IN_HT_5G 0x00030 +static u64 rtw_update_rate_mask(struct rtw_dev *rtwdev, + struct rtw_sta_info *si, + u64 ra_mask, bool is_vht_enable, + u8 wireless_set) +{ + struct rtw_hal *hal = &rtwdev->hal; + const struct cfg80211_bitrate_mask *mask = si->mask; + u64 cfg_mask = GENMASK(63, 0); + u8 rssi_level, band; + + if (wireless_set != WIRELESS_CCK) { + rssi_level = si->rssi_level; + if (rssi_level == 0) + ra_mask &= 0xffffffffffffffffULL; + else if (rssi_level == 1) + ra_mask &= 0xfffffffffffffff0ULL; + else if (rssi_level == 2) + ra_mask &= 0xffffffffffffefe0ULL; + else if (rssi_level == 3) + ra_mask &= 0xffffffffffffcfc0ULL; + else if (rssi_level == 4) + ra_mask &= 0xffffffffffff8f80ULL; + else if (rssi_level >= 5) + ra_mask &= 0xffffffffffff0f00ULL; + } + + if (!si->use_cfg_mask) + return ra_mask; + + band = hal->current_band_type; + if (band == RTW_BAND_2G) { + band = NL80211_BAND_2GHZ; + cfg_mask = mask->control[band].legacy; + } else if (band == RTW_BAND_5G) { + band = NL80211_BAND_5GHZ; + cfg_mask = u64_encode_bits(mask->control[band].legacy, + RA_MASK_OFDM_RATES); + } + + if (!is_vht_enable) { + if (ra_mask & RA_MASK_HT_RATES_1SS) + cfg_mask |= u64_encode_bits(mask->control[band].ht_mcs[0], + RA_MASK_HT_RATES_1SS); + if (ra_mask & RA_MASK_HT_RATES_2SS) + cfg_mask |= u64_encode_bits(mask->control[band].ht_mcs[1], + RA_MASK_HT_RATES_2SS); + } else { + if (ra_mask & RA_MASK_VHT_RATES_1SS) + cfg_mask |= u64_encode_bits(mask->control[band].vht_mcs[0], + RA_MASK_VHT_RATES_1SS); + if (ra_mask & RA_MASK_VHT_RATES_2SS) + cfg_mask |= u64_encode_bits(mask->control[band].vht_mcs[1], + RA_MASK_VHT_RATES_2SS); + } + + ra_mask &= cfg_mask; + + return ra_mask; +} + void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si) { struct ieee80211_sta *sta = si->sta; struct rtw_efuse *efuse = &rtwdev->efuse; struct rtw_hal *hal = &rtwdev->hal; - u8 rssi_level; u8 wireless_set; u8 bw_mode; u8 rate_id; @@ -710,21 +769,8 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si) rate_id = get_rate_id(wireless_set, bw_mode, tx_num); - if (wireless_set != WIRELESS_CCK) { - rssi_level = si->rssi_level; - if (rssi_level == 0) - ra_mask &= 0xffffffffffffffffULL; - else if (rssi_level == 1) - ra_mask &= 0xfffffffffffffff0ULL; - else if (rssi_level == 2) - ra_mask &= 0xffffffffffffefe0ULL; - else if (rssi_level == 3) - ra_mask &= 0xffffffffffffcfc0ULL; - else if (rssi_level == 4) - ra_mask &= 0xffffffffffff8f80ULL; - else if (rssi_level >= 5) - ra_mask &= 0xffffffffffff0f00ULL; - } + ra_mask = rtw_update_rate_mask(rtwdev, si, ra_mask, is_vht_enable, + wireless_set); si->bw_mode = bw_mode; si->stbc_en = stbc_en; diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h index 14b35152fe9f..5e33b7e47a9d 100644 --- a/drivers/net/wireless/realtek/rtw88/main.h +++ b/drivers/net/wireless/realtek/rtw88/main.h @@ -646,6 +646,9 @@ struct rtw_sta_info { DECLARE_BITMAP(tid_ba, IEEE80211_NUM_TIDS); struct rtw_ra_report ra_report; + + bool use_cfg_mask; + struct cfg80211_bitrate_mask *mask; }; enum rtw_bfee_role { -- 2.17.1