From patchwork Thu Mar 6 02:11:40 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ping-Ke Shih X-Patchwork-Id: 871152 Received: from rtits2.realtek.com.tw (rtits2.realtek.com [211.75.126.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 65B2B18DB38 for ; Thu, 6 Mar 2025 02:12:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=211.75.126.72 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741227129; cv=none; b=b0Ca2lBNiJzVhX2b4hc70xHXQ/s/j3ydaEQc++eBn0CSpzVmo+R4K00zXuPqLPL9AnibgYkt6Fl0R/vKn8s885OhpKUn4LiJtjVNgB/qRaU7FTYOBZoP0WwQ2mdNXdr58EZi6NQC13C/9F2/SdPJOlZ+2VUbE+V3/BTok7yuzJI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741227129; c=relaxed/simple; bh=o31eNPDAgzPzHfLmaf1Yy4aC3NQ2DuT8sliClEJE5OM=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=syUcUNSVT5aPS+1epqTSsM/VpfNAtl9j8tsZ/7n1chqSJ2ah27kVAlHAz0ZtQYq3//lrkLXLiwV418myE0jZKEuYgjbQ0CXHRKwhfhKrcM94HVXJriFzraEEAayB/t9FGtQ9fjSjyQQRLKRZ9kT8q9QnMi9ChBON8cVWgudJ/nw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com; spf=pass smtp.mailfrom=realtek.com; dkim=temperror (0-bit key) header.d=realtek.com header.i=@realtek.com header.b=Kr+1fGsg; arc=none smtp.client-ip=211.75.126.72 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=realtek.com Authentication-Results: smtp.subspace.kernel.org; dkim=temperror (0-bit key) header.d=realtek.com header.i=@realtek.com header.b="Kr+1fGsg" X-SpamFilter-By: ArmorX SpamTrap 5.78 with qID 5262C3lG42495371, This message is accepted by code: ctloc85258 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=realtek.com; s=dkim; t=1741227123; bh=o31eNPDAgzPzHfLmaf1Yy4aC3NQ2DuT8sliClEJE5OM=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Transfer-Encoding:Content-Type; b=Kr+1fGsgrod4FS8JmqrtgoIVFBXp45QTksPTc6K/MFJqpGih6K5fZnqR9DBXlO5B0 L1QBSFwUjDilLKePkFEHoPWolp8jAdxj9nthxU1JOAdvTcJvJxnqFU531TX2aUEoKj DQPwDaTv+ZxFZDntLNyodlC41R0QMghSt/1+JrYUCvLT9NYsfITDVq2bn0k7avN6/+ /B/EduHDdPQ5O7tmnJ1kRtJXWfWfHxwAHRlQSb5aFGSKsUMcYZl30jJxL4+Dk9dQc5 vsVrw0251x+xx4SzVN+0p5sD72Deh+WFElSV8/ySwiTogM2esbRSK+XwUtj2BKkBGT rFcOi4azzQQWA== Received: from mail.realtek.com (rtexh36505.realtek.com.tw[172.21.6.25]) by rtits2.realtek.com.tw (8.15.2/3.06/5.92) with ESMTPS id 5262C3lG42495371 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Thu, 6 Mar 2025 10:12:03 +0800 Received: from RTEXMBS04.realtek.com.tw (172.21.6.97) by RTEXH36505.realtek.com.tw (172.21.6.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.39; Thu, 6 Mar 2025 10:12:03 +0800 Received: from [127.0.1.1] (172.21.69.94) by RTEXMBS04.realtek.com.tw (172.21.6.97) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.35; Thu, 6 Mar 2025 10:12:02 +0800 From: Ping-Ke Shih To: CC: , , Subject: [PATCH rtw-next 1/5] wifi: rtw89: add support for negative values of dBm to linear conversion Date: Thu, 6 Mar 2025 10:11:40 +0800 Message-ID: <20250306021144.12854-2-pkshih@realtek.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20250306021144.12854-1-pkshih@realtek.com> References: <20250306021144.12854-1-pkshih@realtek.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: RTEXMBS02.realtek.com.tw (172.21.6.95) To RTEXMBS04.realtek.com.tw (172.21.6.97) From: Kuan-Chung Chen Enhanced the dBm to linear conversion function to accommodate negative dBm values and improved the precision from 1 dBm to 0.25 dBm. Signed-off-by: Kuan-Chung Chen Signed-off-by: Ping-Ke Shih --- .../wireless/realtek/rtw89/rtw8852b_common.c | 6 +- drivers/net/wireless/realtek/rtw89/util.c | 215 +++++++++++------- drivers/net/wireless/realtek/rtw89/util.h | 8 +- 3 files changed, 137 insertions(+), 92 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b_common.c b/drivers/net/wireless/realtek/rtw89/rtw8852b_common.c index 0e094ce9c9b0..99c9505b3cbd 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852b_common.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_common.c @@ -621,9 +621,9 @@ static void rtw8852bt_ext_loss_avg_update(struct rtw89_dev *rtwdev, if (ext_loss_a == ext_loss_b) { ext_loss_avg = ext_loss_a; } else { - linear = rtw89_db_2_linear(abs(ext_loss_a - ext_loss_b)) + 1; - linear = DIV_ROUND_CLOSEST_ULL(linear / 2, 1 << RTW89_LINEAR_FRAC_BITS); - ext_loss_avg = rtw89_linear_2_db(linear); + linear = rtw89_db_to_linear(abs(ext_loss_a - ext_loss_b)) + 1; + linear /= 2; + ext_loss_avg = rtw89_linear_to_db(linear); ext_loss_avg += min(ext_loss_a, ext_loss_b); } diff --git a/drivers/net/wireless/realtek/rtw89/util.c b/drivers/net/wireless/realtek/rtw89/util.c index 33be26873473..073714db26f2 100644 --- a/drivers/net/wireless/realtek/rtw89/util.c +++ b/drivers/net/wireless/realtek/rtw89/util.c @@ -4,106 +4,151 @@ #include "util.h" -#define FRAC_ROWS 3 -#define FRAC_ROW_MAX (FRAC_ROWS - 1) -#define NORM_ROW_MIN FRAC_ROWS - -static const u32 db_invert_table[12][8] = { - /* rows 0~2 in unit of U(32,3) */ - {10, 13, 16, 20, 25, 32, 40, 50}, - {64, 80, 101, 128, 160, 201, 256, 318}, - {401, 505, 635, 800, 1007, 1268, 1596, 2010}, - /* rows 3~11 in unit of U(32,0) */ - {316, 398, 501, 631, 794, 1000, 1259, 1585}, - {1995, 2512, 3162, 3981, 5012, 6310, 7943, 10000}, - {12589, 15849, 19953, 25119, 31623, 39811, 50119, 63098}, - {79433, 100000, 125893, 158489, 199526, 251189, 316228, 398107}, - {501187, 630957, 794328, 1000000, 1258925, 1584893, 1995262, 2511886}, - {3162278, 3981072, 5011872, 6309573, 7943282, 1000000, 12589254, - 15848932}, - {19952623, 25118864, 31622777, 39810717, 50118723, 63095734, 79432823, - 100000000}, - {125892541, 158489319, 199526232, 251188643, 316227766, 398107171, - 501187234, 630957345}, - {794328235, 1000000000, 1258925412, 1584893192, 1995262315, 2511886432U, - 3162277660U, 3981071706U}, +#define RTW89_DBM_QUARTER_FACTOR 2 +#define RTW89_MIN_DBM (-41.25 * (1 << RTW89_DBM_QUARTER_FACTOR)) +#define RTW89_MAX_DBM (96 * (1 << RTW89_DBM_QUARTER_FACTOR)) +#define RTW89_DB_INVERT_TABLE_OFFSET (-RTW89_MIN_DBM) + +static const u64 db_invert_table[] = { + /* in unit of 0.000001 */ + 75, 79, 84, 89, 94, 100, 106, 112, 119, 126, 133, 141, 150, 158, 168, 178, 188, + 200, 211, 224, 237, 251, 266, 282, 299, 316, 335, 355, 376, 398, 422, 447, 473, + 501, 531, 562, 596, 631, 668, 708, 750, 794, 841, 891, 944, 1000, 1059, 1122, 1189, + 1259, 1334, 1413, 1496, 1585, 1679, 1778, 1884, 1995, 2113, 2239, 2371, 2512, 2661, + 2818, 2985, 3162, 3350, 3548, 3758, 3981, 4217, 4467, 4732, 5012, 5309, 5623, 5957, + 6310, 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000, 10593, 11220, 11885, 12589, + 13335, 14125, 14962, 15849, 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119, + 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811, 42170, 44668, 47315, 50119, + 53088, 56234, 59566, 63096, 66834, 70795, 74989, 79433, 84140, 89125, 94406, 100000, + 105925, 112202, 118850, 125893, 133352, 141254, 149624, 158489, 167880, 177828, + 188365, 199526, 211349, 223872, 237137, 251189, 266073, 281838, 298538, 316228, + 334965, 354813, 375837, 398107, 421697, 446684, 473151, 501187, 530884, 562341, + 595662, 630957, 668344, 707946, 749894, 794328, 841395, 891251, 944061, 1000000, + 1059254, 1122018, 1188502, 1258925, 1333521, 1412538, 1496236, 1584893, 1678804, + 1778279, 1883649, 1995262, 2113489, 2238721, 2371374, 2511886, 2660725, 2818383, + 2985383, 3162278, 3349654, 3548134, 3758374, 3981072, 4216965, 4466836, 4731513, + 5011872, 5308844, 5623413, 5956621, 6309573, 6683439, 7079458, 7498942, 7943282, + 8413951, 8912509, 9440609, 10000000, 10592537, 11220185, 11885022, 12589254, + 13335214, 14125375, 14962357, 15848932, 16788040, 17782794, 18836491, 19952623, + 21134890, 22387211, 23713737, 25118864, 26607251, 28183829, 29853826, 31622777, + 33496544, 35481339, 37583740, 39810717, 42169650, 44668359, 47315126, 50118723, + 53088444, 56234133, 59566214, 63095734, 66834392, 70794578, 74989421, 79432823, + 84139514, 89125094, 94406088, 100000000, 105925373, 112201845, 118850223, 125892541, + 133352143, 141253754, 149623566, 158489319, 167880402, 177827941, 188364909, 199526231, + 211348904, 223872114, 237137371, 251188643, 266072506, 281838293, 298538262, 316227766, + 334965439, 354813389, 375837404, 398107171, 421696503, 446683592, 473151259, 501187234, + 530884444, 562341325, 595662144, 630957344, 668343918, 707945784, 749894209, 794328235, + 841395142, 891250938, 944060876, 1000000000, 1059253725, 1122018454, 1188502227, + 1258925412, 1333521432, 1412537545, 1496235656, 1584893192, 1678804018, 1778279410, + 1883649089, 1995262315, 2113489040, 2238721139, 2371373706, 2511886432, 2660725060, + 2818382931, 2985382619, 3162277660, 3349654392, 3548133892, 3758374043, 3981071706, + 4216965034, 4466835922ULL, 4731512590ULL, 5011872336ULL, 5308844442ULL, 5623413252ULL, + 5956621435ULL, 6309573445ULL, 6683439176ULL, 7079457844ULL, 7498942093ULL, + 7943282347ULL, 8413951416ULL, 8912509381ULL, 9440608763ULL, 10000000000ULL, + 10592537252ULL, 11220184543ULL, 11885022274ULL, 12589254118ULL, 13335214322ULL, + 14125375446ULL, 14962356561ULL, 15848931925ULL, 16788040181ULL, 17782794100ULL, + 18836490895ULL, 19952623150ULL, 21134890398ULL, 22387211386ULL, 23713737057ULL, + 25118864315ULL, 26607250598ULL, 28183829313ULL, 29853826189ULL, 31622776602ULL, + 33496543916ULL, 35481338923ULL, 37583740429ULL, 39810717055ULL, 42169650343ULL, + 44668359215ULL, 47315125896ULL, 50118723363ULL, 53088444423ULL, 56234132519ULL, + 59566214353ULL, 63095734448ULL, 66834391757ULL, 70794578438ULL, 74989420933ULL, + 79432823472ULL, 84139514165ULL, 89125093813ULL, 94406087629ULL, 100000000000ULL, + 105925372518ULL, 112201845430ULL, 118850222744ULL, 125892541179ULL, 133352143216ULL, + 141253754462ULL, 149623565609ULL, 158489319246ULL, 167880401812ULL, 177827941004ULL, + 188364908949ULL, 199526231497ULL, 211348903984ULL, 223872113857ULL, 237137370566ULL, + 251188643151ULL, 266072505980ULL, 281838293126ULL, 298538261892ULL, 316227766017ULL, + 334965439158ULL, 354813389234ULL, 375837404288ULL, 398107170553ULL, 421696503429ULL, + 446683592151ULL, 473151258961ULL, 501187233627ULL, 530884444231ULL, 562341325190ULL, + 595662143529ULL, 630957344480ULL, 668343917569ULL, 707945784384ULL, 749894209332ULL, + 794328234724ULL, 841395141645ULL, 891250938134ULL, 944060876286ULL, 1000000000000ULL, + 1059253725177ULL, 1122018454302ULL, 1188502227437ULL, 1258925411794ULL, + 1333521432163ULL, 1412537544623ULL, 1496235656094ULL, 1584893192461ULL, + 1678804018123ULL, 1778279410039ULL, 1883649089490ULL, 1995262314969ULL, + 2113489039837ULL, 2238721138568ULL, 2371373705662ULL, 2511886431510ULL, + 2660725059799ULL, 2818382931264ULL, 2985382618918ULL, 3162277660168ULL, + 3349654391578ULL, 3548133892336ULL, 3758374042884ULL, 3981071705535ULL, + 4216965034286ULL, 4466835921510ULL, 4731512589615ULL, 5011872336273ULL, + 5308844442310ULL, 5623413251904ULL, 5956621435290ULL, 6309573444802ULL, + 6683439175686ULL, 7079457843841ULL, 7498942093325ULL, 7943282347243ULL, + 8413951416452ULL, 8912509381337ULL, 9440608762859ULL, 10000000000000ULL, + 10592537251773ULL, 11220184543020ULL, 11885022274370ULL, 12589254117942ULL, + 13335214321633ULL, 14125375446228ULL, 14962356560944ULL, 15848931924611ULL, + 16788040181226ULL, 17782794100389ULL, 18836490894898ULL, 19952623149689ULL, + 21134890398367ULL, 22387211385683ULL, 23713737056617ULL, 25118864315096ULL, + 26607250597988ULL, 28183829312645ULL, 29853826189180ULL, 31622776601684ULL, + 33496543915783ULL, 35481338923358ULL, 37583740428845ULL, 39810717055350ULL, + 42169650342858ULL, 44668359215096ULL, 47315125896148ULL, 50118723362727ULL, + 53088444423099ULL, 56234132519035ULL, 59566214352901ULL, 63095734448019ULL, + 66834391756862ULL, 70794578438414ULL, 74989420933246ULL, 79432823472428ULL, + 84139514164520ULL, 89125093813375ULL, 94406087628593ULL, 100000000000000ULL, + 105925372517729ULL, 112201845430197ULL, 118850222743702ULL, 125892541179417ULL, + 133352143216332ULL, 141253754462276ULL, 149623565609444ULL, 158489319246111ULL, + 167880401812256ULL, 177827941003893ULL, 188364908948981ULL, 199526231496888ULL, + 211348903983664ULL, 223872113856834ULL, 237137370566166ULL, 251188643150958ULL, + 266072505979882ULL, 281838293126446ULL, 298538261891796ULL, 316227766016838ULL, + 334965439157829ULL, 354813389233577ULL, 375837404288444ULL, 398107170553497ULL, + 421696503428583ULL, 446683592150964ULL, 473151258961482ULL, 501187233627272ULL, + 530884444230989ULL, 562341325190350ULL, 595662143529011ULL, 630957344480196ULL, + 668343917568615ULL, 707945784384138ULL, 749894209332456ULL, 794328234724284ULL, + 841395141645198ULL, 891250938133745ULL, 944060876285923ULL, 1000000000000000ULL, + 1059253725177290ULL, 1122018454301970ULL, 1188502227437020ULL, 1258925411794170ULL, + 1333521432163330ULL, 1412537544622760ULL, 1496235656094440ULL, 1584893192461110ULL, + 1678804018122560ULL, 1778279410038920ULL, 1883649089489810ULL, 1995262314968890ULL, + 2113489039836650ULL, 2238721138568340ULL, 2371373705661660ULL, 2511886431509590ULL, + 2660725059798820ULL, 2818382931264460ULL, 2985382618917960ULL, 3162277660168380ULL, + 3349654391578280ULL, 3548133892335770ULL, 3758374042884440ULL, 3981071705534970ULL }; -u32 rtw89_linear_2_db(u64 val) +s32 rtw89_linear_to_db_quarter(u64 val) { - u8 i, j; - u32 dB; - - for (i = 0; i < 12; i++) { - for (j = 0; j < 8; j++) { - if (i <= FRAC_ROW_MAX && - (val << RTW89_LINEAR_FRAC_BITS) <= db_invert_table[i][j]) - goto cnt; - else if (i > FRAC_ROW_MAX && val <= db_invert_table[i][j]) - goto cnt; - } - } + int r = ARRAY_SIZE(db_invert_table) - 1; + int l = 0; + int m; - return 96; /* maximum 96 dB */ - -cnt: - /* special cases */ - if (j == 0 && i == 0) - goto end; - - if (i == NORM_ROW_MIN && j == 0) { - if (db_invert_table[NORM_ROW_MIN][0] - val > - val - (db_invert_table[FRAC_ROW_MAX][7] >> RTW89_LINEAR_FRAC_BITS)) { - i = FRAC_ROW_MAX; - j = 7; - } - goto end; - } + while (l <= r) { + m = l + (r - l) / 2; - if (i <= FRAC_ROW_MAX) - val <<= RTW89_LINEAR_FRAC_BITS; + if (db_invert_table[m] == val) + return m - (s32)RTW89_DB_INVERT_TABLE_OFFSET; - /* compare difference to get precise dB */ - if (j == 0) { - if (db_invert_table[i][j] - val > - val - db_invert_table[i - 1][7]) { - i--; - j = 7; - } - } else { - if (db_invert_table[i][j] - val > - val - db_invert_table[i][j - 1]) { - j--; - } + if (db_invert_table[m] > val) + r = m - 1; + else + l = m + 1; } -end: - dB = (i << 3) + j + 1; - return dB; + if (l >= ARRAY_SIZE(db_invert_table)) + return RTW89_MAX_DBM; + else if (r < 0) + return RTW89_MIN_DBM; + else if (val - db_invert_table[r] <= db_invert_table[l] - val) + return r - (s32)RTW89_DB_INVERT_TABLE_OFFSET; + else + return l - (s32)RTW89_DB_INVERT_TABLE_OFFSET; } -EXPORT_SYMBOL(rtw89_linear_2_db); +EXPORT_SYMBOL(rtw89_linear_to_db_quarter); -u64 rtw89_db_2_linear(u32 db) +s32 rtw89_linear_to_db(u64 val) { - u64 linear; - u8 i, j; - - if (db > 96) - db = 96; - else if (db < 1) - return 1; - - i = (db - 1) >> 3; - j = (db - 1) & 0x7; + return rtw89_linear_to_db_quarter(val) >> RTW89_DBM_QUARTER_FACTOR; +} +EXPORT_SYMBOL(rtw89_linear_to_db); - linear = db_invert_table[i][j]; +u64 rtw89_db_quarter_to_linear(s32 db) +{ + /* supported range -41.25 to 96 dBm, in unit of 0.25 dBm */ + db = clamp_t(s32, db, RTW89_MIN_DBM, RTW89_MAX_DBM); + db += (s32)RTW89_DB_INVERT_TABLE_OFFSET; - if (i >= NORM_ROW_MIN) - linear = linear << RTW89_LINEAR_FRAC_BITS; + return db_invert_table[db]; +} +EXPORT_SYMBOL(rtw89_db_quarter_to_linear); - return linear; +u64 rtw89_db_to_linear(s32 db) +{ + return rtw89_db_quarter_to_linear(db << RTW89_DBM_QUARTER_FACTOR); } -EXPORT_SYMBOL(rtw89_db_2_linear); +EXPORT_SYMBOL(rtw89_db_to_linear); void rtw89_might_trailing_ellipsis(char *buf, size_t size, ssize_t used) { diff --git a/drivers/net/wireless/realtek/rtw89/util.h b/drivers/net/wireless/realtek/rtw89/util.h index 80441e8da60b..bd08495301e4 100644 --- a/drivers/net/wireless/realtek/rtw89/util.h +++ b/drivers/net/wireless/realtek/rtw89/util.h @@ -6,8 +6,6 @@ #include "core.h" -#define RTW89_LINEAR_FRAC_BITS 3 - #define rtw89_iterate_vifs_bh(rtwdev, iterator, data) \ ieee80211_iterate_active_interfaces_atomic((rtwdev)->hw, \ IEEE80211_IFACE_ITER_NORMAL, iterator, data) @@ -75,8 +73,10 @@ static inline void ether_addr_copy_mask(u8 *dst, const u8 *src, u8 mask) } } -u32 rtw89_linear_2_db(u64 linear); -u64 rtw89_db_2_linear(u32 db); +s32 rtw89_linear_to_db_quarter(u64 val); +s32 rtw89_linear_to_db(u64 val); +u64 rtw89_db_quarter_to_linear(s32 db); +u64 rtw89_db_to_linear(s32 db); void rtw89_might_trailing_ellipsis(char *buf, size_t size, ssize_t used); #endif From patchwork Thu Mar 6 02:11:41 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ping-Ke Shih X-Patchwork-Id: 871526 Received: from rtits2.realtek.com.tw (rtits2.realtek.com [211.75.126.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 89FB918DB3C for ; Thu, 6 Mar 2025 02:12:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=211.75.126.72 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741227132; cv=none; b=isVNyU+OMIEbTcZMkx48EPxb2ZDmvceiUH1EitDjUbVetb1MbSm08n6tuVfi9geFEfrcLQPAmSz6TiPeOq46NQ7dY00rgAbHFslpHq6Nf22TFfSiabA8Gx5KwYHAjAFQ0qlkvKF+QCDHUxiAwkqe771Fp9zdKCoEEaqRWr/H0Ic= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741227132; c=relaxed/simple; bh=mAF1SRGYMjSJYqtXVLNkar0szmTcGflMCTWKHAIowQU=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=K+mc64seYOmNQh4PJCdFz1X4cdq5La5ckJChlRKJOpHlINrcimrCwwR8IavhGBYy/ZhbLH0nvRmiaTrp3HAt7LU//mcyYONgOpTXKpt2eB7KO0KYLJdGyVj5QohatDz0KdL/g1X3yJTAA5Yux59KE66WNbwFoL+6OXBuZRuO9F8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com; spf=pass smtp.mailfrom=realtek.com; dkim=temperror (0-bit key) header.d=realtek.com header.i=@realtek.com header.b=Pwp9ELX8; arc=none smtp.client-ip=211.75.126.72 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=realtek.com Authentication-Results: smtp.subspace.kernel.org; dkim=temperror (0-bit key) header.d=realtek.com header.i=@realtek.com header.b="Pwp9ELX8" X-SpamFilter-By: ArmorX SpamTrap 5.78 with qID 5262C7Vy82495398, This message is accepted by code: ctloc85258 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=realtek.com; s=dkim; t=1741227127; bh=mAF1SRGYMjSJYqtXVLNkar0szmTcGflMCTWKHAIowQU=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Transfer-Encoding:Content-Type; b=Pwp9ELX862axvPNaGwMooD8KszlA5g+eYVNxxeLmfojFvTBRQM3ZoNk45k8ctqTq1 0kFkAxrV5VCpuQq5UAkOxIwC30UTT9ZjzskqfcU22inmg53Hx31G1NuvMTDSlGCzM8 uNrDxwG9Ci+BN4oLIxkaW9pUdm5dvP7cf5EbsvXZuQQwwuvybkv9wyDu1IW7jLSe3e TswFTBEJWHP6s+i3O8s6caLexgTHuwB5NREGE14lqoVPZHuqaDElI2+4Lm3d/kpnuj 057hYq3pRTgu2AOSynbCkkhH2LkFupIpkjQ8rsZ/ZGrF58+v1wAYZGgh3D4Nfe45Gb 94Xe/ESVC7WRQ== Received: from mail.realtek.com (rtexh36506.realtek.com.tw[172.21.6.27]) by rtits2.realtek.com.tw (8.15.2/3.06/5.92) with ESMTPS id 5262C7Vy82495398 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Thu, 6 Mar 2025 10:12:07 +0800 Received: from RTEXMBS04.realtek.com.tw (172.21.6.97) by RTEXH36506.realtek.com.tw (172.21.6.27) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.39; Thu, 6 Mar 2025 10:12:08 +0800 Received: from [127.0.1.1] (172.21.69.94) by RTEXMBS04.realtek.com.tw (172.21.6.97) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.35; Thu, 6 Mar 2025 10:12:06 +0800 From: Ping-Ke Shih To: CC: , , Subject: [PATCH rtw-next 2/5] wifi: rtw89: refine mechanism of TAS Date: Thu, 6 Mar 2025 10:11:41 +0800 Message-ID: <20250306021144.12854-3-pkshih@realtek.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20250306021144.12854-1-pkshih@realtek.com> References: <20250306021144.12854-1-pkshih@realtek.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: RTEXMBS02.realtek.com.tw (172.21.6.95) To RTEXMBS04.realtek.com.tw (172.21.6.97) From: Kuan-Chung Chen TAS state switching mechanism now incorporates the TX ratio as a decision parameter. The average power calculation has been improved by using a higher resolution conversion from dBm to linear. During scan or MCC operations, TAS state is forced to static SAR and suspend the average power calculation. Additionally, TAS window size depends on the regulatory domain and band to ensure compliance. TAS is enabled when permitted by the regulatory domain and is currently supported on the 8852CE. For debugging, add a flag to disable_dm that can stop TAS mechanism. Co-developed-by: Zong-Zhe Yang Signed-off-by: Zong-Zhe Yang Signed-off-by: Kuan-Chung Chen Signed-off-by: Ping-Ke Shih --- drivers/net/wireless/realtek/rtw89/chan.c | 10 +- drivers/net/wireless/realtek/rtw89/core.c | 4 +- drivers/net/wireless/realtek/rtw89/core.h | 28 +- drivers/net/wireless/realtek/rtw89/debug.c | 1 + drivers/net/wireless/realtek/rtw89/fw.h | 6 + drivers/net/wireless/realtek/rtw89/phy.c | 24 ++ drivers/net/wireless/realtek/rtw89/regd.c | 13 + drivers/net/wireless/realtek/rtw89/rtw8851b.c | 1 + drivers/net/wireless/realtek/rtw89/rtw8852a.c | 1 + drivers/net/wireless/realtek/rtw89/rtw8852b.c | 1 + .../net/wireless/realtek/rtw89/rtw8852bt.c | 1 + drivers/net/wireless/realtek/rtw89/rtw8852c.c | 3 + drivers/net/wireless/realtek/rtw89/rtw8922a.c | 1 + drivers/net/wireless/realtek/rtw89/sar.c | 369 ++++++++++++++---- drivers/net/wireless/realtek/rtw89/sar.h | 5 +- 15 files changed, 377 insertions(+), 91 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/chan.c b/drivers/net/wireless/realtek/rtw89/chan.c index be6d73273910..f60e93870b09 100644 --- a/drivers/net/wireless/realtek/rtw89/chan.c +++ b/drivers/net/wireless/realtek/rtw89/chan.c @@ -8,6 +8,7 @@ #include "fw.h" #include "mac.h" #include "ps.h" +#include "sar.h" #include "util.h" static void rtw89_swap_chanctx(struct rtw89_dev *rtwdev, @@ -2673,6 +2674,7 @@ int rtw89_chanctx_ops_assign_vif(struct rtw89_dev *rtwdev, struct rtw89_hal *hal = &rtwdev->hal; struct rtw89_entity_mgnt *mgnt = &hal->entity_mgnt; struct rtw89_entity_weight w = {}; + int ret; rtwvif_link->chanctx_idx = cfg->idx; rtwvif_link->chanctx_assigned = true; @@ -2692,7 +2694,13 @@ int rtw89_chanctx_ops_assign_vif(struct rtw89_dev *rtwdev, rtw89_swap_chanctx(rtwdev, cfg->idx, RTW89_CHANCTX_0); out: - return rtw89_set_channel(rtwdev); + ret = rtw89_set_channel(rtwdev); + if (ret) + return ret; + + rtw89_tas_reset(rtwdev, true); + + return 0; } void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev, diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index 4d286182e21d..cc9b014457ac 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -4601,8 +4601,6 @@ int rtw89_core_start(struct rtw89_dev *rtwdev) rtw89_mac_cfg_phy_rpt_bands(rtwdev, true); rtw89_mac_update_rts_threshold(rtwdev); - rtw89_tas_reset(rtwdev); - ret = rtw89_hci_start(rtwdev); if (ret) { rtw89_err(rtwdev, "failed to start hci\n"); @@ -4956,6 +4954,7 @@ void rtw89_core_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwv rtw89_chip_rfk_scan(rtwdev, rtwvif_link, true); rtw89_hci_recalc_int_mit(rtwdev); rtw89_phy_config_edcca(rtwdev, bb, true); + rtw89_tas_scan(rtwdev, true); rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, mac_addr); } @@ -4982,6 +4981,7 @@ void rtw89_core_scan_complete(struct rtw89_dev *rtwdev, rtw89_btc_ntfy_scan_finish(rtwdev, rtwvif_link->phy_idx); bb = rtw89_get_bb_ctx(rtwdev, rtwvif_link->phy_idx); rtw89_phy_config_edcca(rtwdev, bb, false); + rtw89_tas_scan(rtwdev, false); rtwdev->scanning = false; rtw89_for_each_active_bb(rtwdev, bb) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 3f62df657e1f..074c865e6d03 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -4240,6 +4240,7 @@ enum rtw89_chanctx_state { enum rtw89_chanctx_callbacks { RTW89_CHANCTX_CALLBACK_PLACEHOLDER, RTW89_CHANCTX_CALLBACK_RFK, + RTW89_CHANCTX_CALLBACK_TAS, NUM_OF_RTW89_CHANCTX_CALLBACKS, }; @@ -4281,6 +4282,7 @@ struct rtw89_chip_info { bool support_unii4; bool support_rnr; bool support_ant_gain; + bool support_tas; bool ul_tb_waveform_ctrl; bool ul_tb_pwr_diff; bool rx_freq_frome_ie; @@ -4679,18 +4681,29 @@ struct rtw89_6ghz_span { enum rtw89_tas_state { RTW89_TAS_STATE_DPR_OFF, RTW89_TAS_STATE_DPR_ON, - RTW89_TAS_STATE_DPR_FORBID, + RTW89_TAS_STATE_STATIC_SAR, }; -#define RTW89_TAS_MAX_WINDOW 50 +#define RTW89_TAS_TX_RATIO_WINDOW 6 +#define RTW89_TAS_TXPWR_WINDOW 180 struct rtw89_tas_info { - s16 txpwr_history[RTW89_TAS_MAX_WINDOW]; - s32 total_txpwr; - u8 cur_idx; - s8 dpr_gap; - s8 delta; + u16 tx_ratio_history[RTW89_TAS_TX_RATIO_WINDOW]; + u64 txpwr_history[RTW89_TAS_TXPWR_WINDOW]; + u8 txpwr_head_idx; + u8 txpwr_tail_idx; + u8 tx_ratio_idx; + u16 total_tx_ratio; + u64 total_txpwr; + u64 instant_txpwr; + u32 window_size; + s8 dpr_on_threshold; + s8 dpr_off_threshold; + enum rtw89_tas_state backup_state; enum rtw89_tas_state state; + bool keep_history; + bool block_regd; bool enable; + bool pause; }; struct rtw89_chanctx_cfg { @@ -4748,6 +4761,7 @@ struct rtw89_edcca_bak { enum rtw89_dm_type { RTW89_DM_DYNAMIC_EDCCA, RTW89_DM_THERMAL_PROTECT, + RTW89_DM_TAS, }; #define RTW89_THERMAL_PROT_LV_MAX 5 diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c index 885a5ebeb6cd..f2c5753fd386 100644 --- a/drivers/net/wireless/realtek/rtw89/debug.c +++ b/drivers/net/wireless/realtek/rtw89/debug.c @@ -4154,6 +4154,7 @@ static const struct rtw89_disabled_dm_info { } rtw89_disabled_dm_infos[] = { DM_INFO(DYNAMIC_EDCCA), DM_INFO(THERMAL_PROTECT), + DM_INFO(TAS), }; static ssize_t diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h index e0faed076150..55255b48bdb7 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.h +++ b/drivers/net/wireless/realtek/rtw89/fw.h @@ -4543,6 +4543,12 @@ struct rtw89_c2h_rfk_report { u8 version; } __packed; +struct rtw89_c2h_rf_tas_info { + struct rtw89_c2h_hdr hdr; + __le32 cur_idx; + __le16 txpwr_history[20]; +} __packed; + #define RTW89_FW_RSVD_PLE_SIZE 0x800 #define RTW89_FW_BACKTRACE_INFO_SIZE 8 diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c index e4b690a5febc..abc2a7e989eb 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.c +++ b/drivers/net/wireless/realtek/rtw89/phy.c @@ -3459,6 +3459,30 @@ rtw89_phy_c2h_rfk_report_state(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u3 static void rtw89_phy_c2h_rfk_log_tas_pwr(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len) { + const struct rtw89_c2h_rf_tas_info *rf_tas = + (const struct rtw89_c2h_rf_tas_info *)c2h->data; + const enum rtw89_sar_sources src = rtwdev->sar.src; + struct rtw89_tas_info *tas = &rtwdev->tas; + u64 linear = 0; + u32 i, cur_idx; + s16 txpwr; + + if (!tas->enable || src == RTW89_SAR_SOURCE_NONE) + return; + + cur_idx = le32_to_cpu(rf_tas->cur_idx); + for (i = 0; i < cur_idx; i++) { + txpwr = (s16)le16_to_cpu(rf_tas->txpwr_history[i]); + linear += rtw89_db_quarter_to_linear(txpwr); + + rtw89_debug(rtwdev, RTW89_DBG_SAR, + "tas: index: %u, txpwr: %d\n", i, txpwr); + } + + if (cur_idx == 0) + tas->instant_txpwr = rtw89_db_to_linear(0); + else + tas->instant_txpwr = DIV_ROUND_DOWN_ULL(linear, cur_idx); } static diff --git a/drivers/net/wireless/realtek/rtw89/regd.c b/drivers/net/wireless/realtek/rtw89/regd.c index 0e67d0f128dd..d31403f9009e 100644 --- a/drivers/net/wireless/realtek/rtw89/regd.c +++ b/drivers/net/wireless/realtek/rtw89/regd.c @@ -721,6 +721,18 @@ static void rtw89_regd_apply_policy_6ghz(struct rtw89_dev *rtwdev, sband->channels[i].flags |= IEEE80211_CHAN_DISABLED; } +static void rtw89_regd_apply_policy_tas(struct rtw89_dev *rtwdev) +{ + struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; + const struct rtw89_regd *regd = regulatory->regd; + struct rtw89_tas_info *tas = &rtwdev->tas; + + if (!tas->enable) + return; + + tas->block_regd = !test_bit(RTW89_REGD_FUNC_TAS, regd->func_bitmap); +} + static void rtw89_regd_notifier_apply(struct rtw89_dev *rtwdev, struct wiphy *wiphy, struct regulatory_request *request) @@ -738,6 +750,7 @@ static void rtw89_regd_notifier_apply(struct rtw89_dev *rtwdev, rtw89_regd_apply_policy_unii4(rtwdev, wiphy); rtw89_regd_apply_policy_6ghz(rtwdev, wiphy); + rtw89_regd_apply_policy_tas(rtwdev); } static diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851b.c b/drivers/net/wireless/realtek/rtw89/rtw8851b.c index b709dd71b06a..0d482cd57f6e 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c @@ -2498,6 +2498,7 @@ const struct rtw89_chip_info rtw8851b_chip_info = { BIT(NL80211_CHAN_WIDTH_80), .support_unii4 = true, .support_ant_gain = false, + .support_tas = false, .ul_tb_waveform_ctrl = true, .ul_tb_pwr_diff = false, .rx_freq_frome_ie = true, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c index 638236bffebb..286334e26c84 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c @@ -2216,6 +2216,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = { BIT(NL80211_CHAN_WIDTH_80), .support_unii4 = false, .support_ant_gain = false, + .support_tas = false, .ul_tb_waveform_ctrl = false, .ul_tb_pwr_diff = false, .rx_freq_frome_ie = true, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c index 8bec74716f84..eceb4fb9880d 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c @@ -852,6 +852,7 @@ const struct rtw89_chip_info rtw8852b_chip_info = { BIT(NL80211_CHAN_WIDTH_80), .support_unii4 = true, .support_ant_gain = true, + .support_tas = false, .ul_tb_waveform_ctrl = true, .ul_tb_pwr_diff = false, .rx_freq_frome_ie = true, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852bt.c b/drivers/net/wireless/realtek/rtw89/rtw8852bt.c index e62810660005..bbf37442c492 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852bt.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852bt.c @@ -785,6 +785,7 @@ const struct rtw89_chip_info rtw8852bt_chip_info = { BIT(NL80211_CHAN_WIDTH_80), .support_unii4 = true, .support_ant_gain = true, + .support_tas = false, .ul_tb_waveform_ctrl = true, .ul_tb_pwr_diff = false, .rx_freq_frome_ie = true, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c index 5d3e105dc87f..08bcdf246382 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c @@ -12,6 +12,7 @@ #include "rtw8852c.h" #include "rtw8852c_rfk.h" #include "rtw8852c_table.h" +#include "sar.h" #include "util.h" #define RTW8852C_FW_FORMAT_MAX 1 @@ -2880,6 +2881,7 @@ static int rtw8852c_mac_disable_bb_rf(struct rtw89_dev *rtwdev) static const struct rtw89_chanctx_listener rtw8852c_chanctx_listener = { .callbacks[RTW89_CHANCTX_CALLBACK_RFK] = rtw8852c_rfk_chanctx_cb, + .callbacks[RTW89_CHANCTX_CALLBACK_TAS] = rtw89_tas_chanctx_cb, }; #ifdef CONFIG_PM @@ -3011,6 +3013,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = { BIT(NL80211_CHAN_WIDTH_160), .support_unii4 = true, .support_ant_gain = true, + .support_tas = true, .ul_tb_waveform_ctrl = false, .ul_tb_pwr_diff = true, .rx_freq_frome_ie = false, diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922a.c b/drivers/net/wireless/realtek/rtw89/rtw8922a.c index 210fa818ffe8..d90af2daebcf 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8922a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8922a.c @@ -2770,6 +2770,7 @@ const struct rtw89_chip_info rtw8922a_chip_info = { BIT(NL80211_CHAN_WIDTH_160), .support_unii4 = true, .support_ant_gain = false, + .support_tas = false, .ul_tb_waveform_ctrl = false, .ul_tb_pwr_diff = false, .rx_freq_frome_ie = false, diff --git a/drivers/net/wireless/realtek/rtw89/sar.c b/drivers/net/wireless/realtek/rtw89/sar.c index 24a32dc4e67d..0b5af9528702 100644 --- a/drivers/net/wireless/realtek/rtw89/sar.c +++ b/drivers/net/wireless/realtek/rtw89/sar.c @@ -7,10 +7,16 @@ #include "phy.h" #include "reg.h" #include "sar.h" +#include "util.h" #define RTW89_TAS_FACTOR 2 /* unit: 0.25 dBm */ +#define RTW89_TAS_SAR_GAP (1 << RTW89_TAS_FACTOR) #define RTW89_TAS_DPR_GAP (1 << RTW89_TAS_FACTOR) #define RTW89_TAS_DELTA (2 << RTW89_TAS_FACTOR) +#define RTW89_TAS_TX_RATIO_THRESHOLD 70 +#define RTW89_TAS_DFLT_TX_RATIO 80 +#define RTW89_TAS_DPR_ON_OFFSET (RTW89_TAS_DELTA + RTW89_TAS_SAR_GAP) +#define RTW89_TAS_DPR_OFF_OFFSET (4 << RTW89_TAS_FACTOR) static enum rtw89_sar_subband rtw89_sar_get_subband(struct rtw89_dev *rtwdev, u32 center_freq) @@ -117,8 +123,8 @@ static s8 rtw89_txpwr_sar_to_mac(struct rtw89_dev *rtwdev, u8 fct, s32 cfg) RTW89_SAR_TXPWR_MAC_MAX); } -static s8 rtw89_txpwr_tas_to_sar(const struct rtw89_sar_handler *sar_hdl, - s8 cfg) +static s32 rtw89_txpwr_tas_to_sar(const struct rtw89_sar_handler *sar_hdl, + s32 cfg) { const u8 fct = sar_hdl->txpwr_factor_sar; @@ -128,8 +134,8 @@ static s8 rtw89_txpwr_tas_to_sar(const struct rtw89_sar_handler *sar_hdl, return cfg >> (RTW89_TAS_FACTOR - fct); } -static s8 rtw89_txpwr_sar_to_tas(const struct rtw89_sar_handler *sar_hdl, - s8 cfg) +static s32 rtw89_txpwr_sar_to_tas(const struct rtw89_sar_handler *sar_hdl, + s32 cfg) { const u8 fct = sar_hdl->txpwr_factor_sar; @@ -139,13 +145,43 @@ static s8 rtw89_txpwr_sar_to_tas(const struct rtw89_sar_handler *sar_hdl, return cfg << (RTW89_TAS_FACTOR - fct); } +static bool rtw89_tas_is_active(struct rtw89_dev *rtwdev) +{ + struct rtw89_tas_info *tas = &rtwdev->tas; + struct rtw89_vif *rtwvif; + + if (!tas->enable) + return false; + + rtw89_for_each_rtwvif(rtwdev, rtwvif) { + if (ieee80211_vif_is_mld(rtwvif_to_vif(rtwvif))) + return false; + } + + return true; +} + +static const char *rtw89_tas_state_str(enum rtw89_tas_state state) +{ + switch (state) { + case RTW89_TAS_STATE_DPR_OFF: + return "DPR OFF"; + case RTW89_TAS_STATE_DPR_ON: + return "DPR ON"; + case RTW89_TAS_STATE_STATIC_SAR: + return "STATIC SAR"; + default: + return NULL; + } +} + s8 rtw89_query_sar(struct rtw89_dev *rtwdev, u32 center_freq) { const enum rtw89_sar_sources src = rtwdev->sar.src; /* its members are protected by rtw89_sar_set_src() */ const struct rtw89_sar_handler *sar_hdl = &rtw89_sar_handlers[src]; struct rtw89_tas_info *tas = &rtwdev->tas; - s8 delta; + s32 offset; int ret; s32 cfg; u8 fct; @@ -159,15 +195,17 @@ s8 rtw89_query_sar(struct rtw89_dev *rtwdev, u32 center_freq) if (ret) return RTW89_SAR_TXPWR_MAC_MAX; - if (tas->enable) { + if (rtw89_tas_is_active(rtwdev)) { switch (tas->state) { case RTW89_TAS_STATE_DPR_OFF: - return RTW89_SAR_TXPWR_MAC_MAX; + offset = rtw89_txpwr_tas_to_sar(sar_hdl, RTW89_TAS_DPR_OFF_OFFSET); + cfg += offset; + break; case RTW89_TAS_STATE_DPR_ON: - delta = rtw89_txpwr_tas_to_sar(sar_hdl, tas->delta); - cfg -= delta; + offset = rtw89_txpwr_tas_to_sar(sar_hdl, RTW89_TAS_DPR_ON_OFFSET); + cfg -= offset; break; - case RTW89_TAS_STATE_DPR_FORBID: + case RTW89_TAS_STATE_STATIC_SAR: default: break; } @@ -223,13 +261,23 @@ int rtw89_print_tas(struct rtw89_dev *rtwdev, char *buf, size_t bufsz) struct rtw89_tas_info *tas = &rtwdev->tas; char *p = buf, *end = buf + bufsz; - if (!tas->enable) { + if (!rtw89_tas_is_active(rtwdev)) { p += scnprintf(p, end - p, "no TAS is applied\n"); goto out; } - p += scnprintf(p, end - p, "DPR gap: %d\n", tas->dpr_gap); - p += scnprintf(p, end - p, "TAS delta: %d\n", tas->delta); + p += scnprintf(p, end - p, "State: %s\n", + rtw89_tas_state_str(tas->state)); + p += scnprintf(p, end - p, "Average time: %d\n", + tas->window_size * 2); + p += scnprintf(p, end - p, "SAR gap: %d dBm\n", + RTW89_TAS_SAR_GAP >> RTW89_TAS_FACTOR); + p += scnprintf(p, end - p, "DPR gap: %d dBm\n", + RTW89_TAS_DPR_GAP >> RTW89_TAS_FACTOR); + p += scnprintf(p, end - p, "DPR ON offset: %d dBm\n", + RTW89_TAS_DPR_ON_OFFSET >> RTW89_TAS_FACTOR); + p += scnprintf(p, end - p, "DPR OFF offset: %d dBm\n", + RTW89_TAS_DPR_OFF_OFFSET >> RTW89_TAS_FACTOR); out: return p - buf; @@ -250,6 +298,7 @@ static int rtw89_apply_sar_common(struct rtw89_dev *rtwdev, rtw89_sar_set_src(rtwdev, RTW89_SAR_SOURCE_COMMON, cfg_common, sar); rtw89_core_set_chip_txpwr(rtwdev); + rtw89_tas_reset(rtwdev, false); return 0; } @@ -314,65 +363,174 @@ int rtw89_ops_set_sar_specs(struct ieee80211_hw *hw, return rtw89_apply_sar_common(rtwdev, &sar_common); } -static void rtw89_tas_state_update(struct rtw89_dev *rtwdev) +static bool rtw89_tas_query_sar_config(struct rtw89_dev *rtwdev, s32 *cfg) { + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0); const enum rtw89_sar_sources src = rtwdev->sar.src; /* its members are protected by rtw89_sar_set_src() */ const struct rtw89_sar_handler *sar_hdl = &rtw89_sar_handlers[src]; - struct rtw89_tas_info *tas = &rtwdev->tas; - s32 txpwr_avg = tas->total_txpwr / RTW89_TAS_MAX_WINDOW / PERCENT; - s32 dpr_on_threshold, dpr_off_threshold, cfg; - enum rtw89_tas_state state = tas->state; - const struct rtw89_chan *chan; int ret; - lockdep_assert_wiphy(rtwdev->hw->wiphy); - if (src == RTW89_SAR_SOURCE_NONE) - return; + return false; - chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0); - ret = sar_hdl->query_sar_config(rtwdev, chan->freq, &cfg); + ret = sar_hdl->query_sar_config(rtwdev, chan->freq, cfg); if (ret) + return false; + + *cfg = rtw89_txpwr_sar_to_tas(sar_hdl, *cfg); + + return true; +} + +static void rtw89_tas_state_update(struct rtw89_dev *rtwdev, + enum rtw89_tas_state state) +{ + struct rtw89_tas_info *tas = &rtwdev->tas; + + if (tas->state == state) return; - cfg = rtw89_txpwr_sar_to_tas(sar_hdl, cfg); + rtw89_debug(rtwdev, RTW89_DBG_SAR, "tas: switch state: %s -> %s\n", + rtw89_tas_state_str(tas->state), rtw89_tas_state_str(state)); + + tas->state = state; + rtw89_core_set_chip_txpwr(rtwdev); +} - if (tas->delta >= cfg) { +static u32 rtw89_tas_get_window_size(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0); + u8 band = chan->band_type; + u8 regd = rtw89_regd_get(rtwdev, band); + + switch (regd) { + default: rtw89_debug(rtwdev, RTW89_DBG_SAR, - "TAS delta exceed SAR limit\n"); - state = RTW89_TAS_STATE_DPR_FORBID; - goto out; + "tas: regd: %u is unhandled\n", regd); + fallthrough; + case RTW89_IC: + case RTW89_KCC: + return 180; + case RTW89_FCC: + switch (band) { + case RTW89_BAND_2G: + return 50; + case RTW89_BAND_5G: + return 30; + case RTW89_BAND_6G: + default: + return 15; + } + break; } +} + +static void rtw89_tas_window_update(struct rtw89_dev *rtwdev) +{ + u32 window_size = rtw89_tas_get_window_size(rtwdev); + struct rtw89_tas_info *tas = &rtwdev->tas; + u64 total_txpwr = 0; + u8 head_idx; + u32 i, j; + + WARN_ON_ONCE(tas->window_size > RTW89_TAS_TXPWR_WINDOW); + + if (tas->window_size == window_size) + return; + + rtw89_debug(rtwdev, RTW89_DBG_SAR, "tas: window update: %u -> %u\n", + tas->window_size, window_size); + + head_idx = (tas->txpwr_tail_idx - window_size + 1 + RTW89_TAS_TXPWR_WINDOW) % + RTW89_TAS_TXPWR_WINDOW; + for (i = 0; i < window_size; i++) { + j = (head_idx + i) % RTW89_TAS_TXPWR_WINDOW; + total_txpwr += tas->txpwr_history[j]; + } + + tas->window_size = window_size; + tas->total_txpwr = total_txpwr; + tas->txpwr_head_idx = head_idx; +} + +static void rtw89_tas_history_update(struct rtw89_dev *rtwdev) +{ + struct rtw89_bb_ctx *bb = rtw89_get_bb_ctx(rtwdev, RTW89_PHY_0); + struct rtw89_env_monitor_info *env = &bb->env_monitor; + struct rtw89_tas_info *tas = &rtwdev->tas; + u8 tx_ratio = env->ifs_clm_tx_ratio; + u64 instant_txpwr, txpwr; + + /* txpwr in unit of linear(mW) multiply by percentage */ + if (tx_ratio == 0) { + /* special case: idle tx power + * use -40 dBm * 100 tx ratio + */ + instant_txpwr = rtw89_db_to_linear(-40); + txpwr = instant_txpwr * 100; + } else { + instant_txpwr = tas->instant_txpwr; + txpwr = instant_txpwr * tx_ratio; + } + + tas->total_txpwr += txpwr - tas->txpwr_history[tas->txpwr_head_idx]; + tas->total_tx_ratio += tx_ratio - tas->tx_ratio_history[tas->tx_ratio_idx]; + tas->tx_ratio_history[tas->tx_ratio_idx] = tx_ratio; + + tas->txpwr_head_idx = (tas->txpwr_head_idx + 1) % RTW89_TAS_TXPWR_WINDOW; + tas->txpwr_tail_idx = (tas->txpwr_tail_idx + 1) % RTW89_TAS_TXPWR_WINDOW; + tas->tx_ratio_idx = (tas->tx_ratio_idx + 1) % RTW89_TAS_TX_RATIO_WINDOW; + tas->txpwr_history[tas->txpwr_tail_idx] = txpwr; - dpr_on_threshold = cfg; - dpr_off_threshold = cfg - tas->dpr_gap; rtw89_debug(rtwdev, RTW89_DBG_SAR, - "DPR_ON thold: %d, DPR_OFF thold: %d, txpwr_avg: %d\n", - dpr_on_threshold, dpr_off_threshold, txpwr_avg); + "tas: instant_txpwr: %d, tx_ratio: %u, txpwr: %d\n", + rtw89_linear_to_db_quarter(instant_txpwr), tx_ratio, + rtw89_linear_to_db_quarter(div_u64(txpwr, PERCENT))); +} - if (txpwr_avg >= dpr_on_threshold) +static void rtw89_tas_rolling_average(struct rtw89_dev *rtwdev) +{ + struct rtw89_tas_info *tas = &rtwdev->tas; + s32 dpr_on_threshold, dpr_off_threshold; + enum rtw89_tas_state state; + u16 tx_ratio_avg; + s32 txpwr_avg; + u64 linear; + + linear = DIV_ROUND_DOWN_ULL(tas->total_txpwr, tas->window_size * PERCENT); + txpwr_avg = rtw89_linear_to_db_quarter(linear); + tx_ratio_avg = tas->total_tx_ratio / RTW89_TAS_TX_RATIO_WINDOW; + dpr_on_threshold = tas->dpr_on_threshold; + dpr_off_threshold = tas->dpr_off_threshold; + + rtw89_debug(rtwdev, RTW89_DBG_SAR, + "tas: DPR_ON: %d, DPR_OFF: %d, txpwr_avg: %d, tx_ratio_avg: %u\n", + dpr_on_threshold, dpr_off_threshold, txpwr_avg, tx_ratio_avg); + + if (tx_ratio_avg >= RTW89_TAS_TX_RATIO_THRESHOLD) + state = RTW89_TAS_STATE_STATIC_SAR; + else if (txpwr_avg >= dpr_on_threshold) state = RTW89_TAS_STATE_DPR_ON; else if (txpwr_avg < dpr_off_threshold) state = RTW89_TAS_STATE_DPR_OFF; - -out: - if (tas->state == state) + else return; - rtw89_debug(rtwdev, RTW89_DBG_SAR, - "TAS old state: %d, new state: %d\n", tas->state, state); - tas->state = state; - rtw89_core_set_chip_txpwr(rtwdev); + rtw89_tas_state_update(rtwdev, state); } void rtw89_tas_init(struct rtw89_dev *rtwdev) { + const struct rtw89_chip_info *chip = rtwdev->chip; struct rtw89_tas_info *tas = &rtwdev->tas; struct rtw89_acpi_dsm_result res = {}; int ret; u8 val; + if (!chip->support_tas) + return; + ret = rtw89_acpi_evaluate_dsm(rtwdev, RTW89_ACPI_DSM_FUNC_TAS_EN, &res); if (ret) { rtw89_debug(rtwdev, RTW89_DBG_SAR, @@ -396,65 +554,116 @@ void rtw89_tas_init(struct rtw89_dev *rtwdev) rtw89_debug(rtwdev, RTW89_DBG_SAR, "TAS not enable\n"); return; } - - tas->dpr_gap = RTW89_TAS_DPR_GAP; - tas->delta = RTW89_TAS_DELTA; } -void rtw89_tas_reset(struct rtw89_dev *rtwdev) +void rtw89_tas_reset(struct rtw89_dev *rtwdev, bool force) { + const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0); struct rtw89_tas_info *tas = &rtwdev->tas; + u64 linear; + s32 cfg; + int i; - if (!tas->enable) + if (!rtw89_tas_is_active(rtwdev)) + return; + + if (!rtw89_tas_query_sar_config(rtwdev, &cfg)) + return; + + tas->dpr_on_threshold = cfg - RTW89_TAS_SAR_GAP; + tas->dpr_off_threshold = cfg - RTW89_TAS_SAR_GAP - RTW89_TAS_DPR_GAP; + + /* avoid history reset after new SAR apply */ + if (!force && tas->keep_history) return; - memset(&tas->txpwr_history, 0, sizeof(tas->txpwr_history)); - tas->total_txpwr = 0; - tas->cur_idx = 0; + linear = rtw89_db_quarter_to_linear(cfg) * RTW89_TAS_DFLT_TX_RATIO; + for (i = 0; i < RTW89_TAS_TXPWR_WINDOW; i++) + tas->txpwr_history[i] = linear; + + for (i = 0; i < RTW89_TAS_TX_RATIO_WINDOW; i++) + tas->tx_ratio_history[i] = RTW89_TAS_DFLT_TX_RATIO; + + tas->total_tx_ratio = RTW89_TAS_DFLT_TX_RATIO * RTW89_TAS_TX_RATIO_WINDOW; + tas->total_txpwr = linear * RTW89_TAS_TXPWR_WINDOW; + tas->window_size = RTW89_TAS_TXPWR_WINDOW; + tas->txpwr_head_idx = 0; + tas->txpwr_tail_idx = RTW89_TAS_TXPWR_WINDOW - 1; + tas->tx_ratio_idx = 0; tas->state = RTW89_TAS_STATE_DPR_OFF; -} + tas->backup_state = RTW89_TAS_STATE_DPR_OFF; + tas->keep_history = true; -static const struct rtw89_reg_def txpwr_regs[] = { - {R_PATH0_TXPWR, B_PATH0_TXPWR}, - {R_PATH1_TXPWR, B_PATH1_TXPWR}, -}; + rtw89_debug(rtwdev, RTW89_DBG_SAR, + "tas: band: %u, freq: %u\n", chan->band_type, chan->freq); +} void rtw89_tas_track(struct rtw89_dev *rtwdev) { - struct rtw89_bb_ctx *bb = rtw89_get_bb_ctx(rtwdev, RTW89_PHY_0); - struct rtw89_env_monitor_info *env = &bb->env_monitor; - const enum rtw89_sar_sources src = rtwdev->sar.src; - u8 max_nss_num = rtwdev->chip->rf_path_num; struct rtw89_tas_info *tas = &rtwdev->tas; - s16 tmp, txpwr, instant_txpwr = 0; - u32 val; - int i; + struct rtw89_hal *hal = &rtwdev->hal; + s32 cfg; - if (!tas->enable || src == RTW89_SAR_SOURCE_NONE) + if (hal->disabled_dm_bitmap & BIT(RTW89_DM_TAS)) return; - if (env->ccx_watchdog_result != RTW89_PHY_ENV_MON_IFS_CLM) + if (!rtw89_tas_is_active(rtwdev)) return; - for (i = 0; i < max_nss_num; i++) { - val = rtw89_phy_read32_mask(rtwdev, txpwr_regs[i].addr, - txpwr_regs[i].mask); - tmp = sign_extend32(val, 8); - if (tmp <= 0) - return; - instant_txpwr += tmp; + if (!rtw89_tas_query_sar_config(rtwdev, &cfg) || tas->block_regd) { + rtw89_tas_state_update(rtwdev, RTW89_TAS_STATE_STATIC_SAR); + return; } - instant_txpwr /= max_nss_num; - /* in unit of 0.25 dBm multiply by percentage */ - txpwr = instant_txpwr * env->ifs_clm_tx_ratio; - tas->total_txpwr += txpwr - tas->txpwr_history[tas->cur_idx]; - tas->txpwr_history[tas->cur_idx] = txpwr; - rtw89_debug(rtwdev, RTW89_DBG_SAR, - "instant_txpwr: %d, tx_ratio: %d, txpwr: %d\n", - instant_txpwr, env->ifs_clm_tx_ratio, txpwr); + if (tas->pause) + return; + + rtw89_tas_window_update(rtwdev); + rtw89_tas_history_update(rtwdev); + rtw89_tas_rolling_average(rtwdev); +} + +void rtw89_tas_scan(struct rtw89_dev *rtwdev, bool start) +{ + struct rtw89_tas_info *tas = &rtwdev->tas; + s32 cfg; + + if (!rtw89_tas_is_active(rtwdev)) + return; - tas->cur_idx = (tas->cur_idx + 1) % RTW89_TAS_MAX_WINDOW; + if (!rtw89_tas_query_sar_config(rtwdev, &cfg)) + return; - rtw89_tas_state_update(rtwdev); + if (start) { + tas->backup_state = tas->state; + rtw89_tas_state_update(rtwdev, RTW89_TAS_STATE_STATIC_SAR); + } else { + rtw89_tas_state_update(rtwdev, tas->backup_state); + } +} + +void rtw89_tas_chanctx_cb(struct rtw89_dev *rtwdev, + enum rtw89_chanctx_state state) +{ + struct rtw89_tas_info *tas = &rtwdev->tas; + s32 cfg; + + if (!rtw89_tas_is_active(rtwdev)) + return; + + if (!rtw89_tas_query_sar_config(rtwdev, &cfg)) + return; + + switch (state) { + case RTW89_CHANCTX_STATE_MCC_START: + tas->pause = true; + rtw89_tas_state_update(rtwdev, RTW89_TAS_STATE_STATIC_SAR); + break; + case RTW89_CHANCTX_STATE_MCC_STOP: + tas->pause = false; + break; + default: + break; + } } +EXPORT_SYMBOL(rtw89_tas_chanctx_cb); diff --git a/drivers/net/wireless/realtek/rtw89/sar.h b/drivers/net/wireless/realtek/rtw89/sar.h index 095277df5a71..0df1661db9a8 100644 --- a/drivers/net/wireless/realtek/rtw89/sar.h +++ b/drivers/net/wireless/realtek/rtw89/sar.h @@ -25,7 +25,10 @@ int rtw89_print_tas(struct rtw89_dev *rtwdev, char *buf, size_t bufsz); int rtw89_ops_set_sar_specs(struct ieee80211_hw *hw, const struct cfg80211_sar_specs *sar); void rtw89_tas_init(struct rtw89_dev *rtwdev); -void rtw89_tas_reset(struct rtw89_dev *rtwdev); +void rtw89_tas_reset(struct rtw89_dev *rtwdev, bool force); void rtw89_tas_track(struct rtw89_dev *rtwdev); +void rtw89_tas_scan(struct rtw89_dev *rtwdev, bool start); +void rtw89_tas_chanctx_cb(struct rtw89_dev *rtwdev, + enum rtw89_chanctx_state state); #endif From patchwork Thu Mar 6 02:11:42 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ping-Ke Shih X-Patchwork-Id: 871151 Received: from rtits2.realtek.com.tw (rtits2.realtek.com [211.75.126.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7DB40BE46 for ; Thu, 6 Mar 2025 02:12:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=211.75.126.72 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741227137; cv=none; b=KXFwDdTbB9ZFkBNDTlh7mtASAuXQ6RzlSw61RN7UJvuNUyUVgpL7fq35SfcTsZb3LT0J1ilO5T5q+5F2QoZWhq/VTzRL0BhQSrHeS+RqahxMKClFE4r/nY3cokY12/erThiq3lnUrB8xjrnFCCZE5MY1Zyniz3tPPrAUixrTfi8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741227137; c=relaxed/simple; bh=bgN43kR6Ygy5RQzo6nArZD5f0T9kevcCPIwAGwzaRz8=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Oq+dp7lOROzeAWWOTpUY9Rd4Z4cYY6HpazGzIMsMqJqLdHVuXn+4M7SQSwdOfNHHPMdEaZ2IYcvVvB11j5a2mJX5mgalDgO2m/x5vlnQmxoNe3Od/Se2pL2aXGfIsoO5uGB+Td7a0sZjY5CXQfgwiGwlaFegXU7bW1Nh7Jss2Mc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com; spf=pass smtp.mailfrom=realtek.com; dkim=temperror (0-bit key) header.d=realtek.com header.i=@realtek.com header.b=XjCvsKED; arc=none smtp.client-ip=211.75.126.72 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=realtek.com Authentication-Results: smtp.subspace.kernel.org; dkim=temperror (0-bit key) header.d=realtek.com header.i=@realtek.com header.b="XjCvsKED" X-SpamFilter-By: ArmorX SpamTrap 5.78 with qID 5262CBy742495410, This message is accepted by code: ctloc85258 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=realtek.com; s=dkim; t=1741227132; bh=bgN43kR6Ygy5RQzo6nArZD5f0T9kevcCPIwAGwzaRz8=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Transfer-Encoding:Content-Type; b=XjCvsKEDHsq165xtGtJudlwUZmfudyGbCQF8IByZZLy25lnOc2ITVKRGeNix9lSMh OVw8X9HQLBAWnun4qQHbmgOF70MhWgbw3n3EbtZtaCb4IcRNVOG2LqELXhTFXUddU7 goy9qpfrkUdFzRo4Io623Rh4w9AeexiBjjMW4C5KbKgDfm8TTSeXsaMecESfcqcqJB /UAijVWDCz4sevss48R3NX3pDKa8KEbCzNyLVRTywZEcQBM0lX+TFvRy9eOBUerkLq 9uVr0BQg+ywJ6ouStN6H9tNkkirS6d7jLJaSKXBE3ZYgljAbpFgD8i6tHur57EfQP5 3iFJv2RPDRtOg== Received: from mail.realtek.com (rtexh36505.realtek.com.tw[172.21.6.25]) by rtits2.realtek.com.tw (8.15.2/3.06/5.92) with ESMTPS id 5262CBy742495410 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Thu, 6 Mar 2025 10:12:11 +0800 Received: from RTEXMBS04.realtek.com.tw (172.21.6.97) by RTEXH36505.realtek.com.tw (172.21.6.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.39; Thu, 6 Mar 2025 10:12:12 +0800 Received: from [127.0.1.1] (172.21.69.94) by RTEXMBS04.realtek.com.tw (172.21.6.97) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.35; Thu, 6 Mar 2025 10:12:11 +0800 From: Ping-Ke Shih To: CC: , , Subject: [PATCH rtw-next 3/5] wifi: rtw89: enable dynamic antenna gain based on country Date: Thu, 6 Mar 2025 10:11:42 +0800 Message-ID: <20250306021144.12854-4-pkshih@realtek.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20250306021144.12854-1-pkshih@realtek.com> References: <20250306021144.12854-1-pkshih@realtek.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: RTEXMBS02.realtek.com.tw (172.21.6.95) To RTEXMBS04.realtek.com.tw (172.21.6.97) From: Kuan-Chung Chen The dynamic antenna gain (DAG) considers the country, meaning DAG can be activated only when countries and regulatory domains allow it. Signed-off-by: Kuan-Chung Chen Signed-off-by: Ping-Ke Shih --- drivers/net/wireless/realtek/rtw89/core.h | 1 + drivers/net/wireless/realtek/rtw89/phy.c | 11 ++++++++--- drivers/net/wireless/realtek/rtw89/regd.c | 14 ++++++++++++++ 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index 074c865e6d03..b8f46207141e 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -4666,6 +4666,7 @@ enum rtw89_ant_gain_domain_type { struct rtw89_ant_gain_info { s8 offset[RTW89_ANT_GAIN_CHAIN_NUM][RTW89_ANT_GAIN_SUBBAND_NR]; u32 regd_enabled; + bool block_country; }; struct rtw89_6ghz_span { diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c index abc2a7e989eb..bd736417f467 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.c +++ b/drivers/net/wireless/realtek/rtw89/phy.c @@ -2044,7 +2044,7 @@ static s8 rtw89_phy_ant_gain_offset(struct rtw89_dev *rtwdev, u8 band, u32 cente if (!chip->support_ant_gain) return 0; - if (!(ant_gain->regd_enabled & BIT(regd))) + if (ant_gain->block_country || !(ant_gain->regd_enabled & BIT(regd))) return 0; offset_patha = rtw89_phy_ant_gain_query(rtwdev, RF_PATH_A, center_freq); @@ -2057,10 +2057,14 @@ s16 rtw89_phy_ant_gain_pwr_offset(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan) { struct rtw89_ant_gain_info *ant_gain = &rtwdev->ant_gain; + const struct rtw89_chip_info *chip = rtwdev->chip; u8 regd = rtw89_regd_get(rtwdev, chan->band_type); s8 offset_patha, offset_pathb; - if (!(ant_gain->regd_enabled & BIT(regd))) + if (!chip->support_ant_gain) + return 0; + + if (ant_gain->block_country || !(ant_gain->regd_enabled & BIT(regd))) return 0; offset_patha = rtw89_phy_ant_gain_query(rtwdev, RF_PATH_A, chan->freq); @@ -2079,7 +2083,8 @@ int rtw89_print_ant_gain(struct rtw89_dev *rtwdev, char *buf, size_t bufsz, char *p = buf, *end = buf + bufsz; s8 offset_patha, offset_pathb; - if (!chip->support_ant_gain || !(ant_gain->regd_enabled & BIT(regd))) { + if (!(chip->support_ant_gain && (ant_gain->regd_enabled & BIT(regd))) || + ant_gain->block_country) { p += scnprintf(p, end - p, "no DAG is applied\n"); goto out; } diff --git a/drivers/net/wireless/realtek/rtw89/regd.c b/drivers/net/wireless/realtek/rtw89/regd.c index d31403f9009e..655323a79608 100644 --- a/drivers/net/wireless/realtek/rtw89/regd.c +++ b/drivers/net/wireless/realtek/rtw89/regd.c @@ -733,6 +733,19 @@ static void rtw89_regd_apply_policy_tas(struct rtw89_dev *rtwdev) tas->block_regd = !test_bit(RTW89_REGD_FUNC_TAS, regd->func_bitmap); } +static void rtw89_regd_apply_policy_ant_gain(struct rtw89_dev *rtwdev) +{ + struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory; + struct rtw89_ant_gain_info *ant_gain = &rtwdev->ant_gain; + const struct rtw89_chip_info *chip = rtwdev->chip; + const struct rtw89_regd *regd = regulatory->regd; + + if (!chip->support_ant_gain) + return; + + ant_gain->block_country = !test_bit(RTW89_REGD_FUNC_DAG, regd->func_bitmap); +} + static void rtw89_regd_notifier_apply(struct rtw89_dev *rtwdev, struct wiphy *wiphy, struct regulatory_request *request) @@ -751,6 +764,7 @@ static void rtw89_regd_notifier_apply(struct rtw89_dev *rtwdev, rtw89_regd_apply_policy_unii4(rtwdev, wiphy); rtw89_regd_apply_policy_6ghz(rtwdev, wiphy); rtw89_regd_apply_policy_tas(rtwdev); + rtw89_regd_apply_policy_ant_gain(rtwdev); } static From patchwork Thu Mar 6 02:11:43 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ping-Ke Shih X-Patchwork-Id: 871525 Received: from rtits2.realtek.com.tw (rtits2.realtek.com [211.75.126.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 75DB4BE46 for ; Thu, 6 Mar 2025 02:12:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=211.75.126.72 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741227141; cv=none; b=eDEd09YjLvqvhNFYCPD1yjCjO5tDomNLYhrPDCUmyd1onCegELSpEq/7HXtqszfZYujhmm6BvUaV/aH+EhuIYkl8LNT9p5b5lMNo6IljhnPSfengAx6vwGNemh4ncMcJHLGG9LYK8GJQjJKUt+e9P1yLIb4Iaiqzue0+xUeyanw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741227141; c=relaxed/simple; bh=1n/BhON7mwgVOmVDEPsg1lXrmAXDqjhe2+aIQSafXzE=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Czp7+DGrIsTHllLERW3zmvdIIgksc298ZYApkYgTd59s0Zkcwgh/xfBF5M67usDBeD8DlQnhaH/xugwNtRFr/ee18PrKdcQZtsZ7Q0QAHyZAP5zeyljBudagDHYmpLB738/VCVuLITDruXx7PAA16HCnd3v1RxBjM1bh28HjPNc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com; spf=pass smtp.mailfrom=realtek.com; dkim=temperror (0-bit key) header.d=realtek.com header.i=@realtek.com header.b=V4eRQVKN; arc=none smtp.client-ip=211.75.126.72 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=realtek.com Authentication-Results: smtp.subspace.kernel.org; dkim=temperror (0-bit key) header.d=realtek.com header.i=@realtek.com header.b="V4eRQVKN" X-SpamFilter-By: ArmorX SpamTrap 5.78 with qID 5262CFtbC2495417, This message is accepted by code: ctloc85258 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=realtek.com; s=dkim; t=1741227135; bh=1n/BhON7mwgVOmVDEPsg1lXrmAXDqjhe2+aIQSafXzE=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Transfer-Encoding:Content-Type; b=V4eRQVKNk0zrywhTdv6QDWr1nLd+MrRC4+aShFVKsxDxv7tQkrdt1xSrwxe+LfnP8 13Pg8aEU0eWXptt5VXAhKszgaAHCTxjxBnS0bozy4EUMK/8t/TnMgVFXiUPBDI7cDA lZNdHaECIu+I/VV8Z+0+Y9D8OL6ADTCCvX4OVRlOLkOjGF1PSAKflP36t3ncYhYEyV kOlBji2/Vw8Pcr6Z96cn300iULuzW7VuBV/hZAJXHELauY9oAP6x28Nfgz1usXkta7 AmBlhp15/oRuGyZULjJOm6+drn6UbsOX2P3aptupWH18qymsJxWGeYOaJ/RCaMChjv DTKDyNKOqq85A== Received: from mail.realtek.com (rtexh36506.realtek.com.tw[172.21.6.27]) by rtits2.realtek.com.tw (8.15.2/3.06/5.92) with ESMTPS id 5262CFtbC2495417 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Thu, 6 Mar 2025 10:12:15 +0800 Received: from RTEXMBS04.realtek.com.tw (172.21.6.97) by RTEXH36506.realtek.com.tw (172.21.6.27) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.39; Thu, 6 Mar 2025 10:12:15 +0800 Received: from [127.0.1.1] (172.21.69.94) by RTEXMBS04.realtek.com.tw (172.21.6.97) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.35; Thu, 6 Mar 2025 10:12:15 +0800 From: Ping-Ke Shih To: CC: , , Subject: [PATCH rtw-next 4/5] wifi: rtw89: 8922a: enable dynamic antenna gain Date: Thu, 6 Mar 2025 10:11:43 +0800 Message-ID: <20250306021144.12854-5-pkshih@realtek.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20250306021144.12854-1-pkshih@realtek.com> References: <20250306021144.12854-1-pkshih@realtek.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: RTEXMBS02.realtek.com.tw (172.21.6.95) To RTEXMBS04.realtek.com.tw (172.21.6.97) From: Kuan-Chung Chen The 8922A now supports dynamic antenna gain. However, in firmware before v0.35.64.0, different transmit powers cannot be applied to each RF path. To comply with regulatory limits in these older firmware, the lower of the two requested transmit powers will be used for both paths when they differ. Signed-off-by: Kuan-Chung Chen Signed-off-by: Ping-Ke Shih --- drivers/net/wireless/realtek/rtw89/core.h | 1 + drivers/net/wireless/realtek/rtw89/fw.c | 1 + drivers/net/wireless/realtek/rtw89/phy.c | 6 +++ drivers/net/wireless/realtek/rtw89/phy.h | 7 +++ drivers/net/wireless/realtek/rtw89/reg.h | 28 +++++++--- drivers/net/wireless/realtek/rtw89/rtw8922a.c | 54 ++++++++++++++++++- 6 files changed, 88 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index b8f46207141e..c32b74df1443 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -4492,6 +4492,7 @@ enum rtw89_fw_feature { RTW89_FW_FEATURE_CH_INFO_BE_V0, RTW89_FW_FEATURE_LPS_CH_INFO, RTW89_FW_FEATURE_NO_PHYCAP_P1, + RTW89_FW_FEATURE_NO_POWER_DIFFERENCE, }; struct rtw89_fw_suit { diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index d0a246f415ff..8643b17866f8 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -849,6 +849,7 @@ static const struct __fw_feat_cfg fw_feat_tbl[] = { __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 47, 0, CH_INFO_BE_V0), __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 49, 0, RFK_PRE_NOTIFY_V1), __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 51, 0, NO_PHYCAP_P1), + __CFG_FW_FEAT(RTL8922A, lt, 0, 35, 64, 0, NO_POWER_DIFFERENCE), }; static void rtw89_fw_iterate_feature_cfg(struct rtw89_fw_info *fw, diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c index bd736417f467..f4eee642e5ce 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.c +++ b/drivers/net/wireless/realtek/rtw89/phy.c @@ -2050,6 +2050,9 @@ static s8 rtw89_phy_ant_gain_offset(struct rtw89_dev *rtwdev, u8 band, u32 cente offset_patha = rtw89_phy_ant_gain_query(rtwdev, RF_PATH_A, center_freq); offset_pathb = rtw89_phy_ant_gain_query(rtwdev, RF_PATH_B, center_freq); + if (RTW89_CHK_FW_FEATURE(NO_POWER_DIFFERENCE, &rtwdev->fw)) + return min(offset_patha, offset_pathb); + return max(offset_patha, offset_pathb); } @@ -2067,6 +2070,9 @@ s16 rtw89_phy_ant_gain_pwr_offset(struct rtw89_dev *rtwdev, if (ant_gain->block_country || !(ant_gain->regd_enabled & BIT(regd))) return 0; + if (RTW89_CHK_FW_FEATURE(NO_POWER_DIFFERENCE, &rtwdev->fw)) + return 0; + offset_patha = rtw89_phy_ant_gain_query(rtwdev, RF_PATH_A, chan->freq); offset_pathb = rtw89_phy_ant_gain_query(rtwdev, RF_PATH_B, chan->freq); diff --git a/drivers/net/wireless/realtek/rtw89/phy.h b/drivers/net/wireless/realtek/rtw89/phy.h index e20fff9bac3e..518a100375fb 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.h +++ b/drivers/net/wireless/realtek/rtw89/phy.h @@ -914,6 +914,13 @@ static inline s8 rtw89_phy_txpwr_rf_to_bb(struct rtw89_dev *rtwdev, s8 txpwr_rf) return txpwr_rf << (chip->txpwr_factor_bb - chip->txpwr_factor_rf); } +static inline s8 rtw89_phy_txpwr_bb_to_rf(struct rtw89_dev *rtwdev, s8 txpwr_bb) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + + return txpwr_bb >> (chip->txpwr_factor_bb - chip->txpwr_factor_rf); +} + static inline s8 rtw89_phy_txpwr_rf_to_mac(struct rtw89_dev *rtwdev, s8 txpwr_rf) { const struct rtw89_chip_info *chip = rtwdev->chip; diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index ec06f5bd0fab..44201efee01c 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -9181,6 +9181,16 @@ #define B_IQKINF2_FCNT GENMASK(23, 16) #define B_IQKINF2_KCNT GENMASK(15, 8) #define B_IQKINF2_NCTLV GENMASK(7, 0) +#define R_TXAGC_REF_DBM_RF1_P0 0xBC04 +#define B_TXAGC_OFDM_REF_DBM_RF1_P0 GENMASK(10, 2) +#define B_TXAGC_CCK_REF_DBM_RF1_P0 GENMASK(19, 11) +#define R_TSSI_K_RF1_P0 0xBC28 +#define B_TSSI_K_OFDM_RF1_P0 GENMASK(9, 0) +#define R_TXAGC_REF_DBM_RF1_P1 0xBD04 +#define B_TXAGC_OFDM_REF_DBM_RF1_P1 GENMASK(10, 2) +#define B_TXAGC_CCK_REF_DBM_RF1_P1 GENMASK(19, 11) +#define R_TSSI_K_RF1_P1 0xBD28 +#define B_TSSI_K_OFDM_RF1_P1 GENMASK(9, 0) #define R_RFK_ST 0xBFF8 #define R_DCOF0 0xC000 #define B_DCOF0_RST BIT(17) @@ -9350,16 +9360,18 @@ #define R_TSSI_MAP_OFST_P1 0xE720 #define B_TSSI_MAP_OFST_OFDM GENMASK(17, 9) #define B_TSSI_MAP_OFST_CCK GENMASK(26, 18) -#define R_TXAGC_REF0_P0 0xE628 -#define R_TXAGC_REF0_P1 0xE728 -#define B_TXAGC_REF0_OFDM_DBM GENMASK(8, 0) -#define B_TXAGC_REF0_CCK_DBM GENMASK(17, 9) -#define B_TXAGC_REF0_OFDM_CW GENMASK(26, 18) -#define R_TXAGC_REF1_P0 0xE62C -#define R_TXAGC_REF1_P1 0xE72C -#define B_TXAGC_REF1_CCK_CW GENMASK(8, 0) +#define R_TXAGC_REF_DBM_P0 0xE628 +#define B_TXAGC_OFDM_REF_DBM_P0 GENMASK(8, 0) +#define B_TXAGC_CCK_REF_DBM_P0 GENMASK(17, 9) +#define R_TSSI_K_P0 0xE6A0 +#define B_TSSI_K_OFDM_P0 GENMASK(29, 20) #define R_TXPWR_RSTB 0xE70C #define B_TXPWR_RSTB BIT(16) +#define R_TXAGC_REF_DBM_P1 0xE728 +#define B_TXAGC_OFDM_REF_DBM_P1 GENMASK(8, 0) +#define B_TXAGC_CCK_REF_DBM_P1 GENMASK(17, 9) +#define R_TSSI_K_P1 0xE7A0 +#define B_TSSI_K_OFDM_P1 GENMASK(29, 20) /* WiFi CPU local domain */ #define R_AX_WDT_CTRL 0x0040 diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922a.c b/drivers/net/wireless/realtek/rtw89/rtw8922a.c index d90af2daebcf..8082592db84a 100644 --- a/drivers/net/wireless/realtek/rtw89/rtw8922a.c +++ b/drivers/net/wireless/realtek/rtw89/rtw8922a.c @@ -2156,6 +2156,56 @@ static void rtw8922a_set_txpwr_ref(struct rtw89_dev *rtwdev, B_BE_PWR_REF_CTRL_CCK, ref_cck); } +static const struct rtw89_reg_def rtw8922a_txpwr_ref[][3] = { + {{ .addr = R_TXAGC_REF_DBM_P0, .mask = B_TXAGC_OFDM_REF_DBM_P0}, + { .addr = R_TXAGC_REF_DBM_P0, .mask = B_TXAGC_CCK_REF_DBM_P0}, + { .addr = R_TSSI_K_P0, .mask = B_TSSI_K_OFDM_P0} + }, + {{ .addr = R_TXAGC_REF_DBM_RF1_P0, .mask = B_TXAGC_OFDM_REF_DBM_RF1_P0}, + { .addr = R_TXAGC_REF_DBM_RF1_P0, .mask = B_TXAGC_CCK_REF_DBM_RF1_P0}, + { .addr = R_TSSI_K_RF1_P0, .mask = B_TSSI_K_OFDM_RF1_P0} + }, +}; + +static void rtw8922a_set_txpwr_diff(struct rtw89_dev *rtwdev, + const struct rtw89_chan *chan, + enum rtw89_phy_idx phy_idx) +{ + s16 pwr_ofst = rtw89_phy_ant_gain_pwr_offset(rtwdev, chan); + const struct rtw89_chip_info *chip = rtwdev->chip; + static const u32 path_ofst[] = {0x0, 0x100}; + const struct rtw89_reg_def *txpwr_ref; + static const s16 tssi_k_base = 0x12; + s16 tssi_k_ofst = abs(pwr_ofst) + tssi_k_base; + s16 ofst_dec[RF_PATH_NUM_8922A]; + s16 tssi_k[RF_PATH_NUM_8922A]; + s16 pwr_ref_ofst; + s16 pwr_ref = 0; + u8 i; + + if (rtwdev->hal.cv == CHIP_CAV) + pwr_ref = 16; + + pwr_ref <<= chip->txpwr_factor_rf; + pwr_ref_ofst = pwr_ref - rtw89_phy_txpwr_bb_to_rf(rtwdev, abs(pwr_ofst)); + + ofst_dec[RF_PATH_A] = pwr_ofst > 0 ? pwr_ref : pwr_ref_ofst; + ofst_dec[RF_PATH_B] = pwr_ofst > 0 ? pwr_ref_ofst : pwr_ref; + tssi_k[RF_PATH_A] = pwr_ofst > 0 ? tssi_k_base : tssi_k_ofst; + tssi_k[RF_PATH_B] = pwr_ofst > 0 ? tssi_k_ofst : tssi_k_base; + + for (i = 0; i < RF_PATH_NUM_8922A; i++) { + txpwr_ref = rtw8922a_txpwr_ref[phy_idx]; + + rtw89_phy_write32_mask(rtwdev, txpwr_ref[0].addr + path_ofst[i], + txpwr_ref[0].mask, ofst_dec[i]); + rtw89_phy_write32_mask(rtwdev, txpwr_ref[1].addr + path_ofst[i], + txpwr_ref[1].mask, ofst_dec[i]); + rtw89_phy_write32_mask(rtwdev, txpwr_ref[2].addr + path_ofst[i], + txpwr_ref[2].mask, tssi_k[i]); + } +} + static void rtw8922a_bb_tx_triangular(struct rtw89_dev *rtwdev, bool en, enum rtw89_phy_idx phy_idx) { @@ -2192,6 +2242,8 @@ static void rtw8922a_set_txpwr(struct rtw89_dev *rtwdev, rtw8922a_set_tx_shape(rtwdev, chan, phy_idx); rtw89_phy_set_txpwr_limit(rtwdev, chan, phy_idx); rtw89_phy_set_txpwr_limit_ru(rtwdev, chan, phy_idx); + rtw8922a_set_txpwr_diff(rtwdev, chan, phy_idx); + rtw8922a_set_txpwr_ref(rtwdev, phy_idx); } static void rtw8922a_set_txpwr_ctrl(struct rtw89_dev *rtwdev, @@ -2769,7 +2821,7 @@ const struct rtw89_chip_info rtw8922a_chip_info = { BIT(NL80211_CHAN_WIDTH_80) | BIT(NL80211_CHAN_WIDTH_160), .support_unii4 = true, - .support_ant_gain = false, + .support_ant_gain = true, .support_tas = false, .ul_tb_waveform_ctrl = false, .ul_tb_pwr_diff = false, From patchwork Thu Mar 6 02:11:44 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ping-Ke Shih X-Patchwork-Id: 871150 Received: from rtits2.realtek.com.tw (rtits2.realtek.com [211.75.126.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7DC0D18DB1D for ; Thu, 6 Mar 2025 02:12:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=211.75.126.72 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741227143; cv=none; b=M/0jpg9Rk0ueB0GZ7LKBmDIQEP3ymGO2fItUZ58XSodO+Klm1dpcxHHLb47pWq3rZs+QVmyJt8ymUVg0mkHLjSd8UPid9FswSYEhYBrdP2zUBPrerNVID5aQH38KTPAig+t5XSyVaHM33rfrtDzVdSUdCos8p0UBkgv1ks7oyQc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741227143; c=relaxed/simple; bh=STcdnDx4fLEy8iuMBLRaKtzoDqitYpFoR6I9WfPq7j8=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=J2IvrB46OOqpLQgGM5xywC0yel7scBD2YoslVsSBe//EIvTySOgDhyFDtxtHRa4aL52nlItenY3h8GA5ZVY29VgVX1I/wOigfcMPjDr7fA0sCEq7yvexp4moMA03VOqFr3RkExBQJxDUpvK4sEfNmN1ZZbh6blw9zmgyvV0p9FY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com; spf=pass smtp.mailfrom=realtek.com; dkim=temperror (0-bit key) header.d=realtek.com header.i=@realtek.com header.b=QbGIrmnV; arc=none smtp.client-ip=211.75.126.72 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=realtek.com Authentication-Results: smtp.subspace.kernel.org; dkim=temperror (0-bit key) header.d=realtek.com header.i=@realtek.com header.b="QbGIrmnV" X-SpamFilter-By: ArmorX SpamTrap 5.78 with qID 5262CJQN02495429, This message is accepted by code: ctloc85258 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=realtek.com; s=dkim; t=1741227139; bh=STcdnDx4fLEy8iuMBLRaKtzoDqitYpFoR6I9WfPq7j8=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Transfer-Encoding:Content-Type; b=QbGIrmnVu7AbMNAAfYYhJW4pqfhUYBaLZeo2KN84BLFjz41NxKacmsmaTGd8O6/rC 4PU3G6ahhM45llWB0CRJ4vh9RUejAbdVjiB0iB/FaxyUhhI7fVuNaLTt1Spwakhthe 0kuT3zNNKkQ3UqUUqzl8jpXxBHfEoNY9RI2rKenXd/Jos6Cgfovjzk/9LzbHClFFO5 gSg5mrDhiqqF5LFWxkCXCRNpg/qQCpSyxJx4aTGueVn0+RfzUcLWWpQJrtnW57IfVd Qnaw7lyGQ5cVPTG4GmqjAtUtBeQrd1E241pzVcqMuy3VDx4+sSinEgd6HwO9IBxHuf MQwKZqamu7USg== Received: from mail.realtek.com (rtexh36505.realtek.com.tw[172.21.6.25]) by rtits2.realtek.com.tw (8.15.2/3.06/5.92) with ESMTPS id 5262CJQN02495429 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Thu, 6 Mar 2025 10:12:19 +0800 Received: from RTEXMBS04.realtek.com.tw (172.21.6.97) by RTEXH36505.realtek.com.tw (172.21.6.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.39; Thu, 6 Mar 2025 10:12:19 +0800 Received: from [127.0.1.1] (172.21.69.94) by RTEXMBS04.realtek.com.tw (172.21.6.97) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.35; Thu, 6 Mar 2025 10:12:18 +0800 From: Ping-Ke Shih To: CC: , , Subject: [PATCH rtw-next 5/5] wifi: rtw89: set force HE TB mode when connecting to 11ax AP Date: Thu, 6 Mar 2025 10:11:44 +0800 Message-ID: <20250306021144.12854-6-pkshih@realtek.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20250306021144.12854-1-pkshih@realtek.com> References: <20250306021144.12854-1-pkshih@realtek.com> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: RTEXMBS02.realtek.com.tw (172.21.6.95) To RTEXMBS04.realtek.com.tw (172.21.6.97) From: Dian-Syuan Yang Some of 11ax AP set the UL HE-SIG-A2 reserved subfield to all 0s, which will cause the 11be chip to recognize trigger frame as EHT. We propose a method to bypass the "UL HE-SIG-A2 reserved subfield" and always uses HE TB in response to the AP's trigger frame. Signed-off-by: Dian-Syuan Yang Signed-off-by: Ping-Ke Shih --- drivers/net/wireless/realtek/rtw89/mac.c | 26 +++++++++++++++++++ drivers/net/wireless/realtek/rtw89/mac.h | 2 ++ drivers/net/wireless/realtek/rtw89/mac80211.c | 1 + drivers/net/wireless/realtek/rtw89/reg.h | 4 +++ 4 files changed, 33 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index 513c317b286c..b4841f948ec1 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -4837,6 +4837,32 @@ void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev, rtw89_write32_set(rtwdev, reg, mac->narrow_bw_ru_dis.mask); } +void rtw89_mac_set_he_tb(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link) +{ + struct ieee80211_bss_conf *bss_conf; + bool set; + u32 reg; + + if (rtwdev->chip->chip_gen != RTW89_CHIP_BE) + return; + + rcu_read_lock(); + + bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true); + set = bss_conf->he_support && !bss_conf->eht_support; + + rcu_read_unlock(); + + reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_CLIENT_OM_CTRL, + rtwvif_link->mac_idx); + + if (set) + rtw89_write32_set(rtwdev, reg, B_BE_TRIG_DIS_EHTTB); + else + rtw89_write32_clr(rtwdev, reg, B_BE_TRIG_DIS_EHTTB); +} + void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link) { rtw89_mac_port_cfg_func_sw(rtwdev, rtwvif_link); diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h index 4d5a06a2fe9b..fd7935d24501 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.h +++ b/drivers/net/wireless/realtek/rtw89/mac.h @@ -1188,6 +1188,8 @@ void rtw89_mac_port_cfg_rx_sync(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, bool en); void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link); +void rtw89_mac_set_he_tb(struct rtw89_dev *rtwdev, + struct rtw89_vif_link *rtwvif_link); void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link); void rtw89_mac_enable_beacon_for_ap_vifs(struct rtw89_dev *rtwdev, bool en); int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif_link *vif); diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c index 778ca8589284..4fded07d0bee 100644 --- a/drivers/net/wireless/realtek/rtw89/mac80211.c +++ b/drivers/net/wireless/realtek/rtw89/mac80211.c @@ -656,6 +656,7 @@ static void __rtw89_ops_bss_link_assoc(struct rtw89_dev *rtwdev, rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, rtwvif_link); rtw89_mac_port_update(rtwdev, rtwvif_link); rtw89_mac_set_he_obss_narrow_bw_ru(rtwdev, rtwvif_link); + rtw89_mac_set_he_tb(rtwdev, rtwvif_link); } static void __rtw89_ops_bss_assoc(struct rtw89_dev *rtwdev, diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h index 44201efee01c..c776954ad360 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -7102,6 +7102,10 @@ #define B_BE_MACLBK_RDY_NUM_MASK GENMASK(7, 3) #define B_BE_MACLBK_EN BIT(0) +#define R_BE_CLIENT_OM_CTRL 0x11040 +#define R_BE_CLIENT_OM_CTRL_C1 0x15040 +#define B_BE_TRIG_DIS_EHTTB BIT(24) + #define R_BE_WMAC_NAV_CTL 0x11080 #define R_BE_WMAC_NAV_CTL_C1 0x15080 #define B_BE_WMAC_NAV_UPPER_EN BIT(26)