AI Trajectory


Trajectory: (Expand/Collapse All)
Seq Timestamp Type Name Duration
0/0 2026/08/12 17:24 flow patch-triage
3m Args:
null

Results:
{
  "EnableConfigs": [
    "MAC80211",
    "RTW88",
    "RTW88_8822CU"
  ],
  "FocusSymbols": [
    "rtw8822c_phy_set_param",
    "rtw8822c_phy_calibration"
  ],
  "KMSANReasoning": "The patch refactors the IQ calibration logic in the rtw88 driver by replacing custom 10-bit sign-magnitude/two's-complement arithmetic and a custom bubble sort with standard `s32` types, `sign_extend32()`, and the kernel's built-in `sort()` function. \n\nWhile the stack-allocated arrays `iv` and `qv` could potentially contain uninitialized memory if the sampling loop in `rtw8822c_dac_cal_iq_sample()` terminates early (due to the `cnt \u003c 10000` condition), this behavior and the subsequent reads of the entire array were already present in the old code. The patch does not introduce any new uninitialized memory allocations, does not expose new data to user space, and does not introduce any new uninitialized memory risks. The changes are purely arithmetic and sorting refactoring. Therefore, a dedicated KMSAN fuzzing session is not required for this patch.",
  "NeedsKMSAN": false,
  "Reasoning": "The patch modifies the DAC IQ calibration logic in the Realtek rtw8822c wireless driver, simplifying sorting and offset calculations. This driver can be reached in virtualized environments via USB emulation (dummy HCD) by enabling the USB variant of the driver (CONFIG_RTW88_8822CU). The modified code is executed during PHY parameter setup and calibration, which are accessible via the `rtw8822c_phy_set_param` and `rtw8822c_phy_calibration` callbacks. These callbacks are not inlined as they are assigned to function pointers in the chip operations struct.",
  "WorthFuzzing": true
}

1/1 2026/08/12 17:24 action read-patch-diff
0m Args:
null

Results:
{
  "PatchDiff": "commit ef4677cfbe8646efc8b67245bafbb9abb7cdc864\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate:   Wed Aug 12 17:24:07 2026 +0000\n\n    syz-cluster: applied patch under review\n\ndiff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c\nindex 244c8026479c2..6fcdfc64c3b1d 100644\n--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c\n+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c\n@@ -3,6 +3,8 @@\n  */\n \n #include \u003clinux/module.h\u003e\n+#include \u003clinux/bitops.h\u003e\n+#include \u003clinux/sort.h\u003e\n #include \"main.h\"\n #include \"coex.h\"\n #include \"fw.h\"\n@@ -153,84 +155,30 @@ static void rtw8822c_dac_restore_reg(struct rtw_dev *rtwdev,\n \t}\n }\n \n-static void rtw8822c_rf_minmax_cmp(struct rtw_dev *rtwdev, u32 value,\n-\t\t\t\t   u32 *min, u32 *max)\n+static int rtw8822c_dac_iq_cmp_s32(const void *a, const void *b)\n {\n-\tif (value \u003e= 0x200) {\n-\t\tif (*min \u003e= 0x200) {\n-\t\t\tif (*min \u003e value)\n-\t\t\t\t*min = value;\n-\t\t} else {\n-\t\t\t*min = value;\n-\t\t}\n-\t\tif (*max \u003e= 0x200) {\n-\t\t\tif (*max \u003c value)\n-\t\t\t\t*max = value;\n-\t\t}\n-\t} else {\n-\t\tif (*min \u003c 0x200) {\n-\t\t\tif (*min \u003e value)\n-\t\t\t\t*min = value;\n-\t\t}\n-\n-\t\tif (*max  \u003e= 0x200) {\n-\t\t\t*max = value;\n-\t\t} else {\n-\t\t\tif (*max \u003c value)\n-\t\t\t\t*max = value;\n-\t\t}\n-\t}\n-}\n+\ts32 va = *(const s32 *)a;\n+\ts32 vb = *(const s32 *)b;\n \n-static void __rtw8822c_dac_iq_sort(struct rtw_dev *rtwdev, u32 *v1, u32 *v2)\n-{\n-\tif (*v1 \u003e= 0x200 \u0026\u0026 *v2 \u003e= 0x200) {\n-\t\tif (*v1 \u003e *v2)\n-\t\t\tswap(*v1, *v2);\n-\t} else if (*v1 \u003c 0x200 \u0026\u0026 *v2 \u003c 0x200) {\n-\t\tif (*v1 \u003e *v2)\n-\t\t\tswap(*v1, *v2);\n-\t} else if (*v1 \u003c 0x200 \u0026\u0026 *v2 \u003e= 0x200) {\n-\t\tswap(*v1, *v2);\n-\t}\n+\treturn (va \u003e vb) - (va \u003c vb);\n }\n \n-static void rtw8822c_dac_iq_sort(struct rtw_dev *rtwdev, u32 *iv, u32 *qv)\n+static void rtw8822c_dac_iq_sort(struct rtw_dev *rtwdev, s32 *iv, s32 *qv)\n {\n-\tu32 i, j;\n-\n-\tfor (i = 0; i \u003c DACK_SN_8822C - 1; i++) {\n-\t\tfor (j = 0; j \u003c (DACK_SN_8822C - 1 - i) ; j++) {\n-\t\t\t__rtw8822c_dac_iq_sort(rtwdev, \u0026iv[j], \u0026iv[j + 1]);\n-\t\t\t__rtw8822c_dac_iq_sort(rtwdev, \u0026qv[j], \u0026qv[j + 1]);\n-\t\t}\n-\t}\n+\tsort(iv, DACK_SN_8822C, sizeof(s32), rtw8822c_dac_iq_cmp_s32, NULL);\n+\tsort(qv, DACK_SN_8822C, sizeof(s32), rtw8822c_dac_iq_cmp_s32, NULL);\n }\n \n-static void rtw8822c_dac_iq_offset(struct rtw_dev *rtwdev, u32 *vec, u32 *val)\n+static s32 rtw8822c_dac_iq_offset(struct rtw_dev *rtwdev, s32 *vec)\n {\n-\tu32 p, m, t, i;\n+\ts32 sum = 0;\n \n-\tm = 0;\n-\tp = 0;\n-\tfor (i = 10; i \u003c DACK_SN_8822C - 10; i++) {\n-\t\tif (vec[i] \u003e 0x200)\n-\t\t\tm = (0x400 - vec[i]) + m;\n-\t\telse\n-\t\t\tp = vec[i] + p;\n-\t}\n+\tfor (u32 i = 10; i \u003c DACK_SN_8822C - 10; i++)\n+\t\tsum += vec[i];\n \n-\tif (p \u003e m) {\n-\t\tt = p - m;\n-\t\tt = t / (DACK_SN_8822C - 20);\n-\t} else {\n-\t\tt = m - p;\n-\t\tt = t / (DACK_SN_8822C - 20);\n-\t\tif (t != 0x0)\n-\t\t\tt = 0x400 - t;\n-\t}\n+\ts32 avg = sum / (DACK_SN_8822C - 20);\n \n-\t*val = t;\n+\treturn avg \u003e= 0 ? avg : 0x400 + avg;\n }\n \n static u32 rtw8822c_get_path_write_addr(u8 path)\n@@ -271,29 +219,27 @@ static u32 rtw8822c_get_path_read_addr(u8 path)\n \treturn base_addr;\n }\n \n-static bool rtw8822c_dac_iq_check(struct rtw_dev *rtwdev, u32 value)\n+static bool rtw8822c_dac_iq_check(struct rtw_dev *rtwdev, s32 value)\n {\n-\tbool ret = true;\n \n-\tif ((value \u003e= 0x200 \u0026\u0026 (0x400 - value) \u003e 0x64) ||\n-\t    (value \u003c 0x200 \u0026\u0026 value \u003e 0x64)) {\n-\t\tret = false;\n+\tif (value \u003e 100 || value \u003c -100) {\n \t\trtw_dbg(rtwdev, RTW_DBG_RFK, \"[DACK] Error overflow\\n\");\n+\t\treturn false;\n \t}\n \n-\treturn ret;\n+\treturn true;\n }\n \n-static void rtw8822c_dac_cal_iq_sample(struct rtw_dev *rtwdev, u32 *iv, u32 *qv)\n+static void rtw8822c_dac_cal_iq_sample(struct rtw_dev *rtwdev, s32 *iv, s32 *qv)\n {\n \tu32 temp;\n-\tint i = 0, cnt = 0;\n+\tu32 i = 0, cnt = 0;\n \n \twhile (i \u003c DACK_SN_8822C \u0026\u0026 cnt \u003c 10000) {\n \t\tcnt++;\n \t\ttemp = rtw_read32_mask(rtwdev, 0x2dbc, 0x3fffff);\n-\t\tiv[i] = (temp \u0026 0x3ff000) \u003e\u003e 12;\n-\t\tqv[i] = temp \u0026 0x3ff;\n+\t\tiv[i] = sign_extend32((temp \u0026 0x3ff000) \u003e\u003e 12, 9);\n+\t\tqv[i] = sign_extend32(temp \u0026 0x3ff, 9);\n \n \t\tif (rtw8822c_dac_iq_check(rtwdev, iv[i]) \u0026\u0026\n \t\t    rtw8822c_dac_iq_check(rtwdev, qv[i]))\n@@ -302,13 +248,12 @@ static void rtw8822c_dac_cal_iq_sample(struct rtw_dev *rtwdev, u32 *iv, u32 *qv)\n }\n \n static void rtw8822c_dac_cal_iq_search(struct rtw_dev *rtwdev,\n-\t\t\t\t       u32 *iv, u32 *qv,\n+\t\t\t\t       s32 *iv, s32 *qv,\n \t\t\t\t       u32 *i_value, u32 *q_value)\n {\n-\tu32 i_max = 0, q_max = 0, i_min = 0, q_min = 0;\n-\tu32 i_delta, q_delta;\n+\ts32 i_max = 0, q_max = 0, i_min = 0, q_min = 0;\n \tu32 temp;\n-\tint i, cnt = 0;\n+\tu32 i, cnt = 0;\n \n \tdo {\n \t\ti_min = iv[0];\n@@ -316,23 +261,18 @@ static void rtw8822c_dac_cal_iq_search(struct rtw_dev *rtwdev,\n \t\tq_min = qv[0];\n \t\tq_max = qv[0];\n \t\tfor (i = 0; i \u003c DACK_SN_8822C; i++) {\n-\t\t\trtw8822c_rf_minmax_cmp(rtwdev, iv[i], \u0026i_min, \u0026i_max);\n-\t\t\trtw8822c_rf_minmax_cmp(rtwdev, qv[i], \u0026q_min, \u0026q_max);\n+\t\t\tif (iv[i] \u003c i_min)\n+\t\t\t\ti_min = iv[i];\n+\t\t\tif (iv[i] \u003e i_max)\n+\t\t\t\ti_max = iv[i];\n+\t\t\tif (qv[i] \u003c q_min)\n+\t\t\t\tq_min = qv[i];\n+\t\t\tif (qv[i] \u003e q_max)\n+\t\t\t\tq_max = qv[i];\n \t\t}\n \n-\t\tif (i_max \u003c 0x200 \u0026\u0026 i_min \u003c 0x200)\n-\t\t\ti_delta = i_max - i_min;\n-\t\telse if (i_max \u003e= 0x200 \u0026\u0026 i_min \u003e= 0x200)\n-\t\t\ti_delta = i_max - i_min;\n-\t\telse\n-\t\t\ti_delta = i_max + (0x400 - i_min);\n-\n-\t\tif (q_max \u003c 0x200 \u0026\u0026 q_min \u003c 0x200)\n-\t\t\tq_delta = q_max - q_min;\n-\t\telse if (q_max \u003e= 0x200 \u0026\u0026 q_min \u003e= 0x200)\n-\t\t\tq_delta = q_max - q_min;\n-\t\telse\n-\t\t\tq_delta = q_max + (0x400 - q_min);\n+\t\tu32 i_delta = (u32)(i_max - i_min);\n+\t\tu32 q_delta = (u32)(q_max - q_min);\n \n \t\trtw_dbg(rtwdev, RTW_DBG_RFK,\n \t\t\t\"[DACK] i: min=0x%08x, max=0x%08x, delta=0x%08x\\n\",\n@@ -345,24 +285,24 @@ static void rtw8822c_dac_cal_iq_search(struct rtw_dev *rtwdev,\n \n \t\tif (i_delta \u003e 5 || q_delta \u003e 5) {\n \t\t\ttemp = rtw_read32_mask(rtwdev, 0x2dbc, 0x3fffff);\n-\t\t\tiv[0] = (temp \u0026 0x3ff000) \u003e\u003e 12;\n-\t\t\tqv[0] = temp \u0026 0x3ff;\n+\t\t\tiv[0] = sign_extend32((temp \u0026 0x3ff000) \u003e\u003e 12, 9);\n+\t\t\tqv[0] = sign_extend32(temp \u0026 0x3ff, 9);\n \t\t\ttemp = rtw_read32_mask(rtwdev, 0x2dbc, 0x3fffff);\n-\t\t\tiv[DACK_SN_8822C - 1] = (temp \u0026 0x3ff000) \u003e\u003e 12;\n-\t\t\tqv[DACK_SN_8822C - 1] = temp \u0026 0x3ff;\n+\t\t\tiv[DACK_SN_8822C - 1] = sign_extend32((temp \u0026 0x3ff000) \u003e\u003e 12, 9);\n+\t\t\tqv[DACK_SN_8822C - 1] = sign_extend32(temp \u0026 0x3ff, 9);\n \t\t} else {\n \t\t\tbreak;\n \t\t}\n \t} while (cnt++ \u003c 100);\n \n-\trtw8822c_dac_iq_offset(rtwdev, iv, i_value);\n-\trtw8822c_dac_iq_offset(rtwdev, qv, q_value);\n+\t*i_value = rtw8822c_dac_iq_offset(rtwdev, iv);\n+\t*q_value = rtw8822c_dac_iq_offset(rtwdev, qv);\n }\n \n static void rtw8822c_dac_cal_rf_mode(struct rtw_dev *rtwdev,\n \t\t\t\t     u32 *i_value, u32 *q_value)\n {\n-\tu32 iv[DACK_SN_8822C], qv[DACK_SN_8822C];\n+\ts32 iv[DACK_SN_8822C], qv[DACK_SN_8822C];\n \tu32 rf_a, rf_b;\n \n \trf_a = rtw_read_rf(rtwdev, RF_PATH_A, 0x0, RFREG_MASK);\n"
}

2/1 2026/08/12 17:24 agent patch-evaluator
1m Model:
best-expensive

Args:
null

Results:
{
  "EnableConfigs": [
    "MAC80211",
    "RTW88",
    "RTW88_8822CU"
  ],
  "FocusSymbols": [
    "rtw8822c_phy_set_param",
    "rtw8822c_phy_calibration"
  ],
  "Reasoning": "The patch modifies the DAC IQ calibration logic in the Realtek rtw8822c wireless driver, simplifying sorting and offset calculations. This driver can be reached in virtualized environments via USB emulation (dummy HCD) by enabling the USB variant of the driver (CONFIG_RTW88_8822CU). The modified code is executed during PHY parameter setup and calibration, which are accessible via the `rtw8822c_phy_set_param` and `rtw8822c_phy_calibration` callbacks. These callbacks are not inlined as they are assigned to function pointers in the chip operations struct.",
  "WorthFuzzing": true
}

Instruction:
You are an expert Linux kernel maintainer.
Your job is to review a provided patch series and determine
if it makes functional changes to the kernel that should be fuzzed.

IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in
your workspace. Do NOT rely on your internal knowledge of the kernel. You must actively
use your code access tools to examine the actual source code and confirm any assumptions.

Return WorthFuzzing=false if the patch only contains:
- Modifications to Documentation/, Kconfig files, or code comments.
- Purely decorative changes, such as logging (e.g., pr_err, printk) or tracepoints.
- Changes to numeric constants or macros that do not functionally alter execution flow.
- Code paths that are impossible to reach in virtualized environments like GCE or QEMU,
  even when utilizing software-emulated hardware (e.g., usb gadget, mac80211_hwsim).
- Code in vendor-specific PCIe switch, SmartNIC, or GPU drivers (e.g., mlxsw, pds_core, qed,
  ionic, amdgpu) that require physical PCIe hardware cards not emulated in standard QEMU.
- Driver .remove, .shutdown, or pci_unregister_driver teardown callbacks (e.g., igb_remove)
  that are executed only during PCI hot-unplug or sysfs driver unbind operations.

If it modifies reachable core kernel logic, drivers, or architectures, use your code search
tools to verify the code can be executed, then return WorthFuzzing=true.

When returning WorthFuzzing=true, you MUST ALSO:
1. Extract any specific kernel functions that should be heavily fuzzed into FocusSymbols.
   Avoid listing generic hot-path functions to prevent skewed test distributions.
   Prefer non-static, non-inlined API entrypoint functions over internal static helper functions
   (which are inlined by the compiler and do not have distinct symbol addresses).
2. Identify any specific CONFIG_ options required to properly test this new/modified feature.
   Go and look into the Kconfig files and check for ifdefs around the code, do not make assumptions.
   Also check "depends on" lines in Kconfig to include any non-standard parent subsystem configs
   needed for Kbuild to compile the code statically into vmlinux. List them in the EnableConfigs
   output array, and DO NOT add a 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4").
Prefer calling several tools at the same time to save round-trips.


Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.

Prompt:
For your convenience, here is the diff of the changes:
commit ef4677cfbe8646efc8b67245bafbb9abb7cdc864
Author: syz-cluster <triage@syzkaller.com>
Date:   Wed Aug 12 17:24:07 2026 +0000

    syz-cluster: applied patch under review

diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
index 244c8026479c2..6fcdfc64c3b1d 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
@@ -3,6 +3,8 @@
  */
 
 #include <linux/module.h>
+#include <linux/bitops.h>
+#include <linux/sort.h>
 #include "main.h"
 #include "coex.h"
 #include "fw.h"
@@ -153,84 +155,30 @@ static void rtw8822c_dac_restore_reg(struct rtw_dev *rtwdev,
 	}
 }
 
-static void rtw8822c_rf_minmax_cmp(struct rtw_dev *rtwdev, u32 value,
-				   u32 *min, u32 *max)
+static int rtw8822c_dac_iq_cmp_s32(const void *a, const void *b)
 {
-	if (value >= 0x200) {
-		if (*min >= 0x200) {
-			if (*min > value)
-				*min = value;
-		} else {
-			*min = value;
-		}
-		if (*max >= 0x200) {
-			if (*max < value)
-				*max = value;
-		}
-	} else {
-		if (*min < 0x200) {
-			if (*min > value)
-				*min = value;
-		}
-
-		if (*max  >= 0x200) {
-			*max = value;
-		} else {
-			if (*max < value)
-				*max = value;
-		}
-	}
-}
+	s32 va = *(const s32 *)a;
+	s32 vb = *(const s32 *)b;
 
-static void __rtw8822c_dac_iq_sort(struct rtw_dev *rtwdev, u32 *v1, u32 *v2)
-{
-	if (*v1 >= 0x200 && *v2 >= 0x200) {
-		if (*v1 > *v2)
-			swap(*v1, *v2);
-	} else if (*v1 < 0x200 && *v2 < 0x200) {
-		if (*v1 > *v2)
-			swap(*v1, *v2);
-	} else if (*v1 < 0x200 && *v2 >= 0x200) {
-		swap(*v1, *v2);
-	}
+	return (va > vb) - (va < vb);
 }
 
-static void rtw8822c_dac_iq_sort(struct rtw_dev *rtwdev, u32 *iv, u32 *qv)
+static void rtw8822c_dac_iq_sort(struct rtw_dev *rtwdev, s32 *iv, s32 *qv)
 {
-	u32 i, j;
-
-	for (i = 0; i < DACK_SN_8822C - 1; i++) {
-		for (j = 0; j < (DACK_SN_8822C - 1 - i) ; j++) {
-			__rtw8822c_dac_iq_sort(rtwdev, &iv[j], &iv[j + 1]);
-			__rtw8822c_dac_iq_sort(rtwdev, &qv[j], &qv[j + 1]);
-		}
-	}
+	sort(iv, DACK_SN_8822C, sizeof(s32), rtw8822c_dac_iq_cmp_s32, NULL);
+	sort(qv, DACK_SN_8822C, sizeof(s32), rtw8822c_dac_iq_cmp_s32, NULL);
 }
 
-static void rtw8822c_dac_iq_offset(struct rtw_dev *rtwdev, u32 *vec, u32 *val)
+static s32 rtw8822c_dac_iq_offset(struct rtw_dev *rtwdev, s32 *vec)
 {
-	u32 p, m, t, i;
+	s32 sum = 0;
 
-	m = 0;
-	p = 0;
-	for (i = 10; i < DACK_SN_8822C - 10; i++) {
-		if (vec[i] > 0x200)
-			m = (0x400 - vec[i]) + m;
-		else
-			p = vec[i] + p;
-	}
+	for (u32 i = 10; i < DACK_SN_8822C - 10; i++)
+		sum += vec[i];
 
-	if (p > m) {
-		t = p - m;
-		t = t / (DACK_SN_8822C - 20);
-	} else {
-		t = m - p;
-		t = t / (DACK_SN_8822C - 20);
-		if (t != 0x0)
-			t = 0x400 - t;
-	}
+	s32 avg = sum / (DACK_SN_8822C - 20);
 
-	*val = t;
+	return avg >= 0 ? avg : 0x400 + avg;
 }
 
 static u32 rtw8822c_get_path_write_addr(u8 path)
@@ -271,29 +219,27 @@ static u32 rtw8822c_get_path_read_addr(u8 path)
 	return base_addr;
 }
 
-static bool rtw8822c_dac_iq_check(struct rtw_dev *rtwdev, u32 value)
+static bool rtw8822c_dac_iq_check(struct rtw_dev *rtwdev, s32 value)
 {
-	bool ret = true;
 
-	if ((value >= 0x200 && (0x400 - value) > 0x64) ||
-	    (value < 0x200 && value > 0x64)) {
-		ret = false;
+	if (value > 100 || value < -100) {
 		rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] Error overflow\n");
+		return false;
 	}
 
-	return ret;
+	return true;
 }
 
-static void rtw8822c_dac_cal_iq_sample(struct rtw_dev *rtwdev, u32 *iv, u32 *qv)
+static void rtw8822c_dac_cal_iq_sample(struct rtw_dev *rtwdev, s32 *iv, s32 *qv)
 {
 	u32 temp;
-	int i = 0, cnt = 0;
+	u32 i = 0, cnt = 0;
 
 	while (i < DACK_SN_8822C && cnt < 10000) {
 		cnt++;
 		temp = rtw_read32_mask(rtwdev, 0x2dbc, 0x3fffff);
-		iv[i] = (temp & 0x3ff000) >> 12;
-		qv[i] = temp & 0x3ff;
+		iv[i] = sign_extend32((temp & 0x3ff000) >> 12, 9);
+		qv[i] = sign_extend32(temp & 0x3ff, 9);
 
 		if (rtw8822c_dac_iq_check(rtwdev, iv[i]) &&
 		    rtw8822c_dac_iq_check(rtwdev, qv[i]))
@@ -302,13 +248,12 @@ static void rtw8822c_dac_cal_iq_sample(struct rtw_dev *rtwdev, u32 *iv, u32 *qv)
 }
 
 static void rtw8822c_dac_cal_iq_search(struct rtw_dev *rtwdev,
-				       u32 *iv, u32 *qv,
+				       s32 *iv, s32 *qv,
 				       u32 *i_value, u32 *q_value)
 {
-	u32 i_max = 0, q_max = 0, i_min = 0, q_min = 0;
-	u32 i_delta, q_delta;
+	s32 i_max = 0, q_max = 0, i_min = 0, q_min = 0;
 	u32 temp;
-	int i, cnt = 0;
+	u32 i, cnt = 0;
 
 	do {
 		i_min = iv[0];
@@ -316,23 +261,18 @@ static void rtw8822c_dac_cal_iq_search(struct rtw_dev *rtwdev,
 		q_min = qv[0];
 		q_max = qv[0];
 		for (i = 0; i < DACK_SN_8822C; i++) {
-			rtw8822c_rf_minmax_cmp(rtwdev, iv[i], &i_min, &i_max);
-			rtw8822c_rf_minmax_cmp(rtwdev, qv[i], &q_min, &q_max);
+			if (iv[i] < i_min)
+				i_min = iv[i];
+			if (iv[i] > i_max)
+				i_max = iv[i];
+			if (qv[i] < q_min)
+				q_min = qv[i];
+			if (qv[i] > q_max)
+				q_max = qv[i];
 		}
 
-		if (i_max < 0x200 && i_min < 0x200)
-			i_delta = i_max - i_min;
-		else if (i_max >= 0x200 && i_min >= 0x200)
-			i_delta = i_max - i_min;
-		else
-			i_delta = i_max + (0x400 - i_min);
-
-		if (q_max < 0x200 && q_min < 0x200)
-			q_delta = q_max - q_min;
-		else if (q_max >= 0x200 && q_min >= 0x200)
-			q_delta = q_max - q_min;
-		else
-			q_delta = q_max + (0x400 - q_min);
+		u32 i_delta = (u32)(i_max - i_min);
+		u32 q_delta = (u32)(q_max - q_min);
 
 		rtw_dbg(rtwdev, RTW_DBG_RFK,
 			"[DACK] i: min=0x%08x, max=0x%08x, delta=0x%08x\n",
@@ -345,24 +285,24 @@ static void rtw8822c_dac_cal_iq_search(struct rtw_dev *rtwdev,
 
 		if (i_delta > 5 || q_delta > 5) {
 			temp = rtw_read32_mask(rtwdev, 0x2dbc, 0x3fffff);
-			iv[0] = (temp & 0x3ff000) >> 12;
-			qv[0] = temp & 0x3ff;
+			iv[0] = sign_extend32((temp & 0x3ff000) >> 12, 9);
+			qv[0] = sign_extend32(temp & 0x3ff, 9);
 			temp = rtw_read32_mask(rtwdev, 0x2dbc, 0x3fffff);
-			iv[DACK_SN_8822C - 1] = (temp & 0x3ff000) >> 12;
-			qv[DACK_SN_8822C - 1] = temp & 0x3ff;
+			iv[DACK_SN_8822C - 1] = sign_extend32((temp & 0x3ff000) >> 12, 9);
+			qv[DACK_SN_8822C - 1] = sign_extend32(temp & 0x3ff, 9);
 		} else {
 			break;
 		}
 	} while (cnt++ < 100);
 
-	rtw8822c_dac_iq_offset(rtwdev, iv, i_value);
-	rtw8822c_dac_iq_offset(rtwdev, qv, q_value);
+	*i_value = rtw8822c_dac_iq_offset(rtwdev, iv);
+	*q_value = rtw8822c_dac_iq_offset(rtwdev, qv);
 }
 
 static void rtw8822c_dac_cal_rf_mode(struct rtw_dev *rtwdev,
 				     u32 *i_value, u32 *q_value)
 {
-	u32 iv[DACK_SN_8822C], qv[DACK_SN_8822C];
+	s32 iv[DACK_SN_8822C], qv[DACK_SN_8822C];
 	u32 rf_a, rf_b;
 
 	rf_a = rtw_read_rf(rtwdev, RF_PATH_A, 0x0, RFREG_MASK);

3/2 2026/08/12 17:24 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 5531
							output: 41
							thoughts: 431
						

Thoughts:
**Analyzing a Realtek Wireless Driver Patch for Virtualization Feasibility**

Okay, so I'm looking at this patch for the `rtw8822c.c` driver, specifically for Realtek wireless hardware. It looks like they're simplifying some IQ comparison and sorting logic across several functions: `rtw8822c_dac_iq_cmp_s32`, `rtw8822c_dac_iq_sort`, and a few others dealing with DAC calibration. They're leveraging `sign_extend32` and `sort` from `linux/sort.h`, which is pretty standard. The key question in my mind is always, can I actually test this thing effectively within a virtualized environment? Wireless drivers are notoriously tricky. I know the `rtw88` family is a mac80211 driver, but generally, these need physical hardware – a Realtek Wi-Fi card. `mac80211_hwsim` isn't going to help here; it's a separate thing. It's rare to get a good software emulation going for a full wireless stack like this unless there's some very specific QEMU device or USB gadget setup. I'm thinking about the hardware connection – is it PCIe or USB for the 8822c? Wait... I remember `rtw88` does have USB support (`rtw88_usb`), doesn't it? Okay, that's interesting. If `rtw8822c` *can* be a USB device, then there's a possibility. If it's USB, then it becomes potentially fuzzable using something like syzkaller's dummy USB driver. Let me dig into `drivers/net/wireless/realtek/rtw88/rtw8822cu.c` and see if there is USB code there.



4/2 2026/08/12 17:24 tool grepper
0m Args:
{
  "Expression": "rtw8822c",
  "PathPrefix": "drivers/net/wireless/realtek/rtw88/"
}

Results:
{
  "Output": "\nFull output is too long, showing 500 out of 1633 lines.\nUse more precise expression if possible.\n\ndrivers/net/wireless/realtek/rtw88/Makefile=37=obj-$(CONFIG_RTW88_8822C)\t+= rtw88_8822c.o\ndrivers/net/wireless/realtek/rtw88/Makefile:38:rtw88_8822c-objs\t\t:= rtw8822c.o rtw8822c_table.o\ndrivers/net/wireless/realtek/rtw88/Makefile-39-\ndrivers/net/wireless/realtek/rtw88/Makefile=40=obj-$(CONFIG_RTW88_8822CE)\t+= rtw88_8822ce.o\ndrivers/net/wireless/realtek/rtw88/Makefile:41:rtw88_8822ce-objs\t\t:= rtw8822ce.o\ndrivers/net/wireless/realtek/rtw88/Makefile-42-\ndrivers/net/wireless/realtek/rtw88/Makefile=43=obj-$(CONFIG_RTW88_8822CS)\t+= rtw88_8822cs.o\ndrivers/net/wireless/realtek/rtw88/Makefile:44:rtw88_8822cs-objs\t\t:= rtw8822cs.o\ndrivers/net/wireless/realtek/rtw88/Makefile-45-\ndrivers/net/wireless/realtek/rtw88/Makefile=46=obj-$(CONFIG_RTW88_8822CU)\t+= rtw88_8822cu.o\ndrivers/net/wireless/realtek/rtw88/Makefile:47:rtw88_8822cu-objs\t\t:= rtw8822cu.o\ndrivers/net/wireless/realtek/rtw88/Makefile-48-\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-13-#include \"phy.h\"\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:14:#include \"rtw8822c.h\"\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:15:#include \"rtw8822c_table.h\"\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-16-#include \"mac.h\"\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-24-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:25:static void rtw8822c_config_trx_mode(struct rtw_dev *rtwdev, u8 tx_path,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-26-\t\t\t\t     u8 rx_path, bool is_tx2_path);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-27-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:28:static void rtw8822ce_efuse_parsing(struct rtw_efuse *efuse,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:29:\t\t\t\t    struct rtw8822c_efuse *map)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-30-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-33-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:34:static void rtw8822cu_efuse_parsing(struct rtw_efuse *efuse,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:35:\t\t\t\t    struct rtw8822c_efuse *map)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-36-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-39-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:40:static void rtw8822cs_efuse_parsing(struct rtw_efuse *efuse,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:41:\t\t\t\t    struct rtw8822c_efuse *map)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-42-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-45-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:46:static int rtw8822c_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-47-{\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-48-\tstruct rtw_efuse *efuse = \u0026rtwdev-\u003eefuse;\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:49:\tstruct rtw8822c_efuse *map;\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-50-\tint i;\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-51-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:52:\tmap = (struct rtw8822c_efuse *)log_map;\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-53-\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-73-\tcase RTW_HCI_TYPE_PCIE:\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:74:\t\trtw8822ce_efuse_parsing(efuse, map);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-75-\t\tbreak;\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-76-\tcase RTW_HCI_TYPE_USB:\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:77:\t\trtw8822cu_efuse_parsing(efuse, map);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-78-\t\tbreak;\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-79-\tcase RTW_HCI_TYPE_SDIO:\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:80:\t\trtw8822cs_efuse_parsing(efuse, map);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-81-\t\tbreak;\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-89-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:90:static void rtw8822c_header_file_init(struct rtw_dev *rtwdev, bool pre)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-91-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-102-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:103:static void rtw8822c_bb_reset(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-104-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-109-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:110:static void rtw8822c_dac_backup_reg(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-111-\t\t\t\t    struct rtw_backup_info *backup,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-138-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:139:static void rtw8822c_dac_restore_reg(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-140-\t\t\t\t     struct rtw_backup_info *backup,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-157-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:158:static int rtw8822c_dac_iq_cmp_s32(const void *a, const void *b)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-159-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-165-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:166:static void rtw8822c_dac_iq_sort(struct rtw_dev *rtwdev, s32 *iv, s32 *qv)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-167-{\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:168:\tsort(iv, DACK_SN_8822C, sizeof(s32), rtw8822c_dac_iq_cmp_s32, NULL);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:169:\tsort(qv, DACK_SN_8822C, sizeof(s32), rtw8822c_dac_iq_cmp_s32, NULL);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-170-}\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-171-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:172:static s32 rtw8822c_dac_iq_offset(struct rtw_dev *rtwdev, s32 *vec)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-173-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-183-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:184:static u32 rtw8822c_get_path_write_addr(u8 path)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-185-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-202-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:203:static u32 rtw8822c_get_path_read_addr(u8 path)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-204-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-221-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:222:static bool rtw8822c_dac_iq_check(struct rtw_dev *rtwdev, s32 value)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-223-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-232-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:233:static void rtw8822c_dac_cal_iq_sample(struct rtw_dev *rtwdev, s32 *iv, s32 *qv)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-234-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-243-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:244:\t\tif (rtw8822c_dac_iq_check(rtwdev, iv[i]) \u0026\u0026\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:245:\t\t    rtw8822c_dac_iq_check(rtwdev, qv[i]))\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-246-\t\t\ti++;\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-249-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:250:static void rtw8822c_dac_cal_iq_search(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-251-\t\t\t\t       s32 *iv, s32 *qv,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-283-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:284:\t\trtw8822c_dac_iq_sort(rtwdev, iv, qv);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-285-\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-297-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:298:\t*i_value = rtw8822c_dac_iq_offset(rtwdev, iv);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:299:\t*q_value = rtw8822c_dac_iq_offset(rtwdev, qv);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-300-}\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-301-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:302:static void rtw8822c_dac_cal_rf_mode(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-303-\t\t\t\t     u32 *i_value, u32 *q_value)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-313-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:314:\trtw8822c_dac_cal_iq_sample(rtwdev, iv, qv);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:315:\trtw8822c_dac_cal_iq_search(rtwdev, iv, qv, i_value, q_value);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-316-}\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-317-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:318:static void rtw8822c_dac_bb_setting(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-319-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-333-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:334:static void rtw8822c_dac_cal_adc(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-335-\t\t\t\t u8 path, u32 *adc_ic, u32 *adc_qc)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-344-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:345:\tbase_addr = rtw8822c_get_path_write_addr(path);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-346-\tswitch (path) {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-371-\t\trtw_write32(rtwdev, 0x1c24, 0x00010002);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:372:\t\trtw8822c_dac_cal_rf_mode(rtwdev, \u0026ic, \u0026qc);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-373-\t\trtw_dbg(rtwdev, RTW_DBG_RFK,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-391-\t\trtw_write32(rtwdev, 0x1c3c, path_sel + 0x8103);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:392:\t\trtw8822c_dac_cal_rf_mode(rtwdev, \u0026ic, \u0026qc);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-393-\t\trtw_dbg(rtwdev, RTW_DBG_RFK,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-411-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:412:static void rtw8822c_dac_cal_step1(struct rtw_dev *rtwdev, u8 path)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-413-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-417-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:418:\tbase_addr = rtw8822c_get_path_write_addr(path);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:419:\tread_addr = rtw8822c_get_path_read_addr(path);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-420-\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-456-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:457:static void rtw8822c_dac_cal_step2(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-458-\t\t\t\t   u8 path, u32 *ic_out, u32 *qc_out)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-462-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:463:\tbase_addr = rtw8822c_get_path_write_addr(path);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-464-\trtw_write32_mask(rtwdev, base_addr + 0xbc, 0xf0000000, 0x0);\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-474-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:475:\trtw8822c_dac_cal_rf_mode(rtwdev, \u0026ic_in, \u0026qc_in);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-476-\tic = ic_in;\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-505-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:506:static void rtw8822c_dac_cal_step3(struct rtw_dev *rtwdev, u8 path,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-507-\t\t\t\t   u32 adc_ic, u32 adc_qc,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-515-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:516:\tbase_addr = rtw8822c_get_path_write_addr(path);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:517:\tread_addr = rtw8822c_get_path_read_addr(path);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-518-\tic = *ic_in;\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-556-\trtw_write32(rtwdev, base_addr + 0x60, 0xf0000000);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:557:\trtw8822c_dac_cal_rf_mode(rtwdev, \u0026ic, \u0026qc);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-558-\tif (ic \u003e= 0x10)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-582-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:583:static void rtw8822c_dac_cal_step4(struct rtw_dev *rtwdev, u8 path)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-584-{\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:585:\tu32 base_addr = rtw8822c_get_path_write_addr(path);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-586-\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-592-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:593:static void rtw8822c_dac_cal_backup_vec(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-594-\t\t\t\t\tu8 path, u8 vec, u32 w_addr, u32 r_addr)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-609-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:610:static void rtw8822c_dac_cal_backup_path(struct rtw_dev *rtwdev, u8 path)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-611-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-619-\t/* backup I vector */\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:620:\tw_addr = rtw8822c_get_path_write_addr(path) + 0xb0;\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:621:\tr_addr = rtw8822c_get_path_read_addr(path) + 0x10;\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:622:\trtw8822c_dac_cal_backup_vec(rtwdev, path, 0, w_addr, r_addr);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-623-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-624-\t/* backup Q vector */\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:625:\tw_addr = rtw8822c_get_path_write_addr(path) + 0xb0 + w_off;\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:626:\tr_addr = rtw8822c_get_path_read_addr(path) + 0x10 + r_off;\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:627:\trtw8822c_dac_cal_backup_vec(rtwdev, path, 1, w_addr, r_addr);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-628-}\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-629-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:630:static void rtw8822c_dac_cal_backup_dck(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-631-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-653-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:654:static void rtw8822c_dac_cal_backup(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-655-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-667-\trtw_write32_mask(rtwdev, 0x1860, 0xfc000000, 0x3c);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:668:\trtw8822c_dac_cal_backup_path(rtwdev, RF_PATH_A);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-669-\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-672-\trtw_write32_mask(rtwdev, 0x4160, 0xfc000000, 0x3c);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:673:\trtw8822c_dac_cal_backup_path(rtwdev, RF_PATH_B);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-674-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:675:\trtw8822c_dac_cal_backup_dck(rtwdev);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-676-\trtw_write32_set(rtwdev, 0x1830, BIT(30));\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-683-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:684:static void rtw8822c_dac_cal_restore_dck(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-685-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-713-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:714:static void rtw8822c_dac_cal_restore_prepare(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-715-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-742-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:743:\trtw8822c_dac_cal_restore_dck(rtwdev);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-744-\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-766-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:767:static bool rtw8822c_dac_cal_restore_wait(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-768-\t\t\t\t\t  u32 target_addr, u32 toggle_addr)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-783-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:784:static bool rtw8822c_dac_cal_restore_path(struct rtw_dev *rtwdev, u8 path)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-785-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-792-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:793:\tw_i = rtw8822c_get_path_write_addr(path) + 0xb0;\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:794:\tr_i = rtw8822c_get_path_read_addr(path) + 0x08;\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:795:\tw_q = rtw8822c_get_path_write_addr(path) + 0xb0 + w_off;\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:796:\tr_q = rtw8822c_get_path_read_addr(path) + 0x08 + r_off;\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-797-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:798:\tif (!rtw8822c_dac_cal_restore_wait(rtwdev, r_i, w_i + 0x8))\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-799-\t\treturn false;\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-810-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:811:\tif (!rtw8822c_dac_cal_restore_wait(rtwdev, r_q, w_q + 0x8))\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-812-\t\treturn false;\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-830-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:831:static bool __rtw8822c_dac_cal_restore(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-832-{\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:833:\tif (!rtw8822c_dac_cal_restore_path(rtwdev, RF_PATH_A))\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-834-\t\treturn false;\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-835-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:836:\tif (!rtw8822c_dac_cal_restore_path(rtwdev, RF_PATH_B))\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-837-\t\treturn false;\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-841-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:842:static bool rtw8822c_dac_cal_restore(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-843-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-857-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:858:\trtw8822c_dac_cal_restore_prepare(rtwdev);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-859-\tif (!check_hw_ready(rtwdev, 0x2808, 0x7fff80, 0xffff) ||\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-864-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:865:\tif (!__rtw8822c_dac_cal_restore(rtwdev)) {\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-866-\t\trtw_err(rtwdev, \"failed to restore dack vectors\\n\");\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-882-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:883:static void rtw8822c_rf_dac_cal(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-884-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-891-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:892:\tif (rtw8822c_dac_cal_restore(rtwdev))\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-893-\t\treturn;\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-896-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:897:\trtw8822c_dac_backup_reg(rtwdev, backup, backup_rf);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-898-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:899:\trtw8822c_dac_bb_setting(rtwdev);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-900-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-901-\t/* path-A */\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:902:\trtw8822c_dac_cal_adc(rtwdev, RF_PATH_A, \u0026adc_ic_a, \u0026adc_qc_a);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-903-\tfor (i = 0; i \u003c 10; i++) {\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:904:\t\trtw8822c_dac_cal_step1(rtwdev, RF_PATH_A);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:905:\t\trtw8822c_dac_cal_step2(rtwdev, RF_PATH_A, \u0026ic, \u0026qc);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-906-\t\tic_a = ic;\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-908-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:909:\t\trtw8822c_dac_cal_step3(rtwdev, RF_PATH_A, adc_ic_a, adc_qc_a,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-910-\t\t\t\t       \u0026ic, \u0026qc, \u0026i_a, \u0026q_a);\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-914-\t}\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:915:\trtw8822c_dac_cal_step4(rtwdev, RF_PATH_A);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-916-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-917-\t/* path-B */\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:918:\trtw8822c_dac_cal_adc(rtwdev, RF_PATH_B, \u0026adc_ic_b, \u0026adc_qc_b);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-919-\tfor (i = 0; i \u003c 10; i++) {\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:920:\t\trtw8822c_dac_cal_step1(rtwdev, RF_PATH_B);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:921:\t\trtw8822c_dac_cal_step2(rtwdev, RF_PATH_B, \u0026ic, \u0026qc);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-922-\t\tic_b = ic;\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-924-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:925:\t\trtw8822c_dac_cal_step3(rtwdev, RF_PATH_B, adc_ic_b, adc_qc_b,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-926-\t\t\t\t       \u0026ic, \u0026qc, \u0026i_b, \u0026q_b);\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-930-\t}\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:931:\trtw8822c_dac_cal_step4(rtwdev, RF_PATH_B);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-932-\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-938-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:939:\trtw8822c_dac_restore_reg(rtwdev, backup, backup_rf);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-940-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-941-\t/* backup results to restore, saving a lot of time */\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:942:\trtw8822c_dac_cal_backup(rtwdev);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-943-\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-949-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:950:static void rtw8822c_rf_x2_check(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-951-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-963-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:964:static void rtw8822c_set_power_trim(struct rtw_dev *rtwdev, s8 bb_gain[2][8])\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-965-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-995-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:996:static void rtw8822c_power_trim(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-997-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1027-\tif (set)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1028:\t\trtw8822c_set_power_trim(rtwdev, bb_gain);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1029-\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1032-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1033:static void rtw8822c_thermal_trim(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1034-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1050-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1051:static void rtw8822c_pa_bias(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1052-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1072-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1073:static void rtw8822c_rfk_handshake(struct rtw_dev *rtwdev, bool is_before_k)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1074-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1118-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1119:static void rtw8822c_rfk_power_save(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1120-\t\t\t\t    bool is_power_save)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1130-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1131:static void rtw8822c_txgapk_backup_bb_reg(struct rtw_dev *rtwdev, const u32 reg[],\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1132-\t\t\t\t\t  u32 reg_backup[], u32 reg_num)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1143-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1144:static void rtw8822c_txgapk_reload_bb_reg(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1145-\t\t\t\t\t  const u32 reg[], u32 reg_backup[],\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=1157=static bool check_rf_status(struct rtw_dev *rtwdev, u8 status)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1171-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1172:static void rtw8822c_txgapk_tx_pause(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1173-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1187-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1188:static void rtw8822c_txgapk_bb_dpk(struct rtw_dev *rtwdev, u8 path)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1189-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1219-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1220:static void rtw8822c_txgapk_afe_dpk(struct rtw_dev *rtwdev, u8 path)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1221-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1255-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1256:static void rtw8822c_txgapk_afe_dpk_restore(struct rtw_dev *rtwdev, u8 path)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1257-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1288-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1289:static void rtw8822c_txgapk_bb_dpk_restore(struct rtw_dev *rtwdev, u8 path)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1290-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1328-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1329:static bool _rtw8822c_txgapk_gain_valid(struct rtw_dev *rtwdev, u32 gain)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1330-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1337-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1338:static void _rtw8822c_txgapk_write_gain_bb_table(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1339-\t\t\t\t\t\t u8 band, u8 path)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1368-\t\tv = txgapk-\u003erf3f_bp[band][gain][path];\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1369:\t\tif (_rtw8822c_txgapk_gain_valid(rtwdev, v)) {\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1370-\t\t\tif (!check_txgain) {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1391-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1392:static void rtw8822c_txgapk_write_gain_bb_table(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1393-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1400-\t\tfor (path = 0; path \u003c rtwdev-\u003ehal.rf_path_num; path++) {\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1401:\t\t\t_rtw8822c_txgapk_write_gain_bb_table(rtwdev,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1402-\t\t\t\t\t\t\t     band, path);\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1406-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1407:static void rtw8822c_txgapk_read_offset(struct rtw_dev *rtwdev, u8 path)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1408-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1483-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1484:static void rtw8822c_txgapk_calculate_offset(struct rtw_dev *rtwdev, u8 path)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1485-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1494-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1495:\trtw8822c_txgapk_backup_bb_reg(rtwdev, bb_reg,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1496-\t\t\t\t      reg_backup, ARRAY_SIZE(bb_reg));\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1516-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1517:\t\trtw8822c_txgapk_read_offset(rtwdev, path);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1518-\t\trtw_dbg(rtwdev, RTW_DBG_RFK, \"=============================\\n\");\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1550-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1551:\t\trtw8822c_txgapk_read_offset(rtwdev, path);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1552-\t\trtw_dbg(rtwdev, RTW_DBG_RFK, \"=============================\\n\");\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1553-\t}\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1554:\trtw8822c_txgapk_reload_bb_reg(rtwdev, bb_reg,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1555-\t\t\t\t      reg_backup, ARRAY_SIZE(bb_reg));\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1557-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1558:static void rtw8822c_txgapk_rf_restore(struct rtw_dev *rtwdev, u8 path)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1559-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1569-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1570:static u32 rtw8822c_txgapk_cal_gain(struct rtw_dev *rtwdev, u32 gain, s8 offset)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1571-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1575-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1576:\tif (_rtw8822c_txgapk_gain_valid(rtwdev, gain)) {\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1577-\t\tnew_gain = gain;\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1593-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1594:static void rtw8822c_txgapk_write_tx_gain(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1595-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1624-\t\t\t\tv = txgapk-\u003erf3f_bp[band][j][path];\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1625:\t\t\t\tif (_rtw8822c_txgapk_gain_valid(rtwdev, v))\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1626-\t\t\t\t\tcontinue;\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1632-\t\t\tv = txgapk-\u003erf3f_bp[band][i][path];\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1633:\t\t\tif (_rtw8822c_txgapk_gain_valid(rtwdev, v)) {\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1634-\t\t\t\trtw_dbg(rtwdev, RTW_DBG_RFK,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1649-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1650:\t\t\ttmp_3f = rtw8822c_txgapk_cal_gain(rtwdev,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1651-\t\t\t\t\t\t\t  txgapk-\u003erf3f_bp[band][i][path],\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1663-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1664:static void rtw8822c_txgapk_save_all_tx_gain_table(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1665-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1681-\t\t\t\"[TXGAPK] Already Read txgapk-\u003eread_txgain return!!!\\n\");\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1682:\t\trtw8822c_txgapk_write_gain_bb_table(rtwdev);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1683-\t\treturn;\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1718-\t}\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1719:\trtw8822c_txgapk_write_gain_bb_table(rtwdev);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1720-\ttxgapk-\u003eread_txgain = 1;\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1722-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1723:static void rtw8822c_txgapk(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1724-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1731-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1732:\trtw8822c_txgapk_save_all_tx_gain_table(rtwdev);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1733-\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1746-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1747:\trtw8822c_txgapk_backup_bb_reg(rtwdev, bb_reg,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1748-\t\t\t\t      bb_reg_backup, ARRAY_SIZE(bb_reg));\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1749:\trtw8822c_txgapk_tx_pause(rtwdev);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1750-\tfor (path = 0; path \u003c rtwdev-\u003ehal.rf_path_num; path++) {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1752-\t\t\t\t\t      RF_CFGCH, RFREG_MASK) \u0026 MASKBYTE0;\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1753:\t\trtw8822c_txgapk_bb_dpk(rtwdev, path);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1754:\t\trtw8822c_txgapk_afe_dpk(rtwdev, path);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1755:\t\trtw8822c_txgapk_calculate_offset(rtwdev, path);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1756:\t\trtw8822c_txgapk_rf_restore(rtwdev, path);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1757:\t\trtw8822c_txgapk_afe_dpk_restore(rtwdev, path);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1758:\t\trtw8822c_txgapk_bb_dpk_restore(rtwdev, path);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1759-\t}\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1760:\trtw8822c_txgapk_write_tx_gain(rtwdev);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1761:\trtw8822c_txgapk_reload_bb_reg(rtwdev, bb_reg,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1762-\t\t\t\t      bb_reg_backup, ARRAY_SIZE(bb_reg));\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1764-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1765:static void rtw8822c_do_gapk(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1766-{\n\n"
}

5/2 2026/08/12 17:24 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 23737
							output: 45
							thoughts: 253
						

Thoughts:
**WorthFuzzing Assessment of the rtw8822c Driver**

Okay, so the `rtw8822c` driver gets built when `CONFIG_RTW88_8822C` is flipped. This family also encompasses PCIe (`CONFIG_RTW88_8822CE`), SDIO (`CONFIG_RTW88_8822CS`), and critically, a USB version (`CONFIG_RTW88_8822CU`). That USB variant is the key here. Since a USB device is available, this driver *should* be amenable to fuzzing with syzkaller's USB dummy driver, emulating that hardware interface.

Wait a minute, let's re-read the prompt. It's asking for a `WorthFuzzing=false` return if the changes are unreachable in virtualized environments, which is the case of something like usb gadget. But a USB driver *is* reachable in a virtualized environment by using the USB gadget or a dummy HCD.

Therefore, because this driver has a USB variant, and USB gadget functionality *is* available in these virtualized environments (like GCE and QEMU), this looks like a good candidate for fuzzing. To be absolutely sure, I'll need to double-check the configuration options and dependencies of `CONFIG_RTW88_8822CU` to make sure there are no obvious showstoppers, but the presence of the USB version is a strong indicator that this patch is, in fact, worth fuzzing.



6/2 2026/08/12 17:24 tool grepper
0m Args:
{
  "Expression": "config RTW88_8822CU",
  "PathPrefix": "drivers/net/wireless/realtek/rtw88/"
}

Results:
{
  "Output": "drivers/net/wireless/realtek/rtw88/Kconfig=104=config RTW88_8822CS\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-114-\ndrivers/net/wireless/realtek/rtw88/Kconfig:115:config RTW88_8822CU\ndrivers/net/wireless/realtek/rtw88/Kconfig-116-\ttristate \"Realtek 8822CU USB wireless network adapter\"\n"
}

7/2 2026/08/12 17:24 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 24509
							output: 47
							thoughts: 19
						

Thoughts:
Here's my thought process, summarized as if I were considering the dependencies of `RTW88_8822CU`:

**Analyzing `RTW88_8822CU` Dependencies**

Okay, so we're diving into the dependencies of `RTW88_8822CU`. My initial approach is to mentally map out the typical driver structure. What are the likely foundational elements? We're talking about a wireless driver, so I'm thinking immediately about the hardware abstraction layer (HAL), likely some sort of power management interface, and of course, the network stack interactions.

I need to quickly assess if this is a standard Realtek design or if there are any specific custom elements to consider, such as a vendor-specific firmware loading mechanism. Are there any existing Realtek driver architectures I should be familiar with, or any known quirks? That would be useful information to have to understand its interrelationship with other systems.

Then there are the kernel interfaces. What specific kernel modules or functions is this driver going to rely on? Is it using the standard wireless extensions (WE) or iwlwifi, or is this driver implementing something more bespoke? I should be thinking about the kernel version compatibility here, as that could also reveal a lot about the dependency tree. Also, will it use any custom kernel modules to get data from the board?

I have to think about the toolchain as well. What compiler version and libraries are likely needed for compilation? Are there any specific build flags or configuration options I should be aware of, perhaps related to debug symbols or specific hardware revisions? Let's assume it supports the latest build, but it will be useful to check the compatibility list, if it exists.

I'm mentally creating a dependency graph, seeing how `RTW88_8822CU` fits within the bigger picture. I'm imagining a multi-tiered architecture, and want to quickly determine each of its components. I need to understand its dependencies at each level to ensure I can address any potential issues.



8/2 2026/08/12 17:24 tool grepper
0m Args:
{
  "Expression": "config RTW88_8822CU",
  "PathPrefix": "drivers/net/wireless/realtek/rtw88/Kconfig"
}

Results:
{
  "Output": "drivers/net/wireless/realtek/rtw88/Kconfig=104=config RTW88_8822CS\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-114-\ndrivers/net/wireless/realtek/rtw88/Kconfig:115:config RTW88_8822CU\ndrivers/net/wireless/realtek/rtw88/Kconfig-116-\ttristate \"Realtek 8822CU USB wireless network adapter\"\n"
}

9/2 2026/08/12 17:24 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 25143
							output: 44
							thoughts: 29
						

Thoughts:
Here's a summary of my thought process, as requested:

**Diving into the Realtek Wireless Kconfig**

Okay, time to dig into the Realtek wireless driver configuration. I need to understand how some feature or option is controlled. Let's see... I'll start by looking at the `drivers/net/wireless/realtek/rtw88/Kconfig` file, around line 115. That should be a good starting point to check the general settings and dependencies for this driver. Hopefully, it'll provide some clarity regarding the configuration options I'm interested in and their dependencies. This Kconfig file is the key to understanding how these drivers are built and configured, and line 115 feels like a good spot to start my search.



10/2 2026/08/12 17:24 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/realtek/rtw88/Kconfig",
  "FirstLine": 100,
  "LineCount": 30
}

Results:
{
  "Contents": " 100:\t\t  Select this option will enable support for 8822CE chipset\n 101:\t\n 102:\t\t  802.11ac PCIe wireless network adapter\n 103:\t\n 104:\tconfig RTW88_8822CS\n 105:\t\ttristate \"Realtek 8822CS SDIO wireless network adapter\"\n 106:\t\tdepends on MMC\n 107:\t\tselect RTW88_CORE\n 108:\t\tselect RTW88_SDIO\n 109:\t\tselect RTW88_8822C\n 110:\t\thelp\n 111:\t\t  Select this option will enable support for 8822CS chipset\n 112:\t\n 113:\t\t  802.11ac SDIO wireless network adapter\n 114:\t\n 115:\tconfig RTW88_8822CU\n 116:\t\ttristate \"Realtek 8822CU USB wireless network adapter\"\n 117:\t\tdepends on USB\n 118:\t\tselect RTW88_CORE\n 119:\t\tselect RTW88_USB\n 120:\t\tselect RTW88_8822C\n 121:\t\thelp\n 122:\t\t  Select this option will enable support for 8822CU chipset\n 123:\t\n 124:\t\t  802.11ac USB wireless network adapter\n 125:\t\n 126:\tconfig RTW88_8723DE\n 127:\t\ttristate \"Realtek 8723DE PCI wireless network adapter\"\n 128:\t\tdepends on PCI\n 129:\t\tselect RTW88_CORE\n"
}

11/2 2026/08/12 17:24 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 25839
							output: 47
							thoughts: 373
						

Thoughts:
**Analyzing the `RTW88_8822CU` Dependency and Modified Functions**

Alright, let's break this down. It looks like `RTW88_8822CU` has a dependency on `USB` and implicitly enables `RTW88_8822C`. This makes sense; if it's a USB implementation, it will likely be built on top of the base chip. The patch targets `rtw8822c.c`, which is only compiled if `RTW88_8822C` is configured. Therefore, to effectively test this, I need to enable `RTW88_8822CU` because that should allow me to test through USB emulation.

Now, which functions are being modified? Let's take a look. I see: `rtw8822c_dac_iq_cmp_s32` (a new function), `rtw8822c_dac_iq_sort`, `rtw8822c_dac_iq_offset`, `rtw8822c_dac_iq_check`, `rtw8822c_dac_cal_iq_sample`, `rtw8822c_dac_cal_iq_search`, and `rtw8822c_dac_cal_rf_mode`. These are all declared as static, so they're internal to the file. That means I need to figure out which non-static entry points call these functions, to understand the flow.

Okay, let's start with the calls to `rtw8822c_dac_cal_rf_mode`. I see that it's called by `rtw8822c_dac_cal_step2`, `rtw8822c_dac_cal_step3`, `rtw8822c_dac_cal_step4`, and `rtw8822c_dac_cal_adc`. Those four are all called by `rtw8822c_rf_dac_cal`. Now, my next question is, who calls `rtw8822c_rf_dac_cal`? That's the key to understanding the execution path.



12/2 2026/08/12 17:24 tool grepper
0m Args:
{
  "Expression": "rtw8822c_rf_dac_cal",
  "PathPrefix": "drivers/net/wireless/realtek/rtw88/"
}

Results:
{
  "Output": "drivers/net/wireless/realtek/rtw88/rtw8822c.c=842=static bool rtw8822c_dac_cal_restore(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-882-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:883:static void rtw8822c_rf_dac_cal(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-884-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=1778=static void rtw8822c_rf_init(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1779-{\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1780:\trtw8822c_rf_dac_cal(rtwdev);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1781-\trtw8822c_rf_x2_check(rtwdev);\n"
}

13/2 2026/08/12 17:24 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 27121
							output: 45
							thoughts: 16
						

Thoughts:
Okay, here's my attempt at summarizing that thought process, tailored for an expert audience:

**Investigating the RF Initialization Call**

Alright, so the immediate question that pops into my head is, "Who's calling `rtw8822c_rf_init`?". That's the crux of this. Understanding the *caller* of this function is absolutely critical to understanding its role in the overall RF initialization flow and, consequently, the state of the system when RF is ready. Is it being invoked directly during driver initialization, perhaps from the board bring-up code? Or is it being called later, likely as a response to some event like a PCI probe, a power-up sequence, or a connection attempt?

Knowing the call path will immediately give me a ton of valuable context. It informs me if I need to look upstream at the hardware initializations or downstream to the state machines. It will show how it fits into the broader picture of the driver’s operation. It will indicate the conditions under which the RF portion is initialized and that's the core. It’s the starting point.

From the caller, I can deduce:

*   **Timing:** When the RF is initialized relative to the rest of the system bring-up or network stack initialization.
*   **Context:** What other operations are already completed when the RF initialization happens.
*   **Dependencies:** What preconditions are *assumed* to be met before this call.

I can then trace that to see where the call came from and what the implications are in order to understand how that RF initialization function works in relation to its caller.



14/2 2026/08/12 17:24 tool grepper
0m Args:
{
  "Expression": "rtw8822c_rf_init",
  "PathPrefix": "drivers/net/wireless/realtek/rtw88/"
}

Results:
{
  "Output": "drivers/net/wireless/realtek/rtw88/rtw8822c.c=1765=static void rtw8822c_do_gapk(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1777-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1778:static void rtw8822c_rf_init(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1779-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=1803=static void rtw8822c_phy_set_param(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1848-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1849:\trtw8822c_rf_init(rtwdev);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1850-\trtw8822c_pwrtrack_init(rtwdev);\n"
}

15/2 2026/08/12 17:24 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 27890
							output: 47
							thoughts: 18
						

Thoughts:
Okay, here's my interpretation of that thought process, tailored for an expert audience, and presented as if it were my own internal monologue:

**Investigating the Caller of `rtw8822c_phy_set_param`**

Alright, so `rtw8822c_phy_set_param`... that's a key function in the PHY configuration for that specific Realtek WiFi chip, right? My initial thought is always *who* is calling that? It's a fundamental question when debugging, optimizing, or even just understanding a driver's architecture. I need to know the context.

Is it called directly from a higher-level function, maybe something exposed to the MAC layer? Perhaps it's being triggered by an interrupt handler, meaning it's reacting to hardware events? Maybe it's buried deep within some sort of power management routine, adjusting PHY parameters based on link state or power profiles? It could even be part of the initialization sequence. Determining the calling context is paramount to understanding *why* it's being called and what the implications are.

The dependency tree is key: Is it called by a core function, or some optional feature? What does it do for the PHY, what parts of the PHY does it talk to? The answers to those questions are all necessary to understand the system.

I need to trace the call paths to get the full picture. Cross-referencing the code, using a debugger, that's the next step.



16/2 2026/08/12 17:24 tool grepper
0m Args:
{
  "Expression": "rtw8822c_phy_set_param",
  "PathPrefix": "drivers/net/wireless/realtek/rtw88/"
}

Results:
{
  "Output": "drivers/net/wireless/realtek/rtw88/rtw8822c.c=1787=static void rtw8822c_pwrtrack_init(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1802-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1803:static void rtw8822c_phy_set_param(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1804-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=4899=static const struct rtw_chip_ops rtw8822c_ops = {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-4901-\t.power_off\t\t= rtw_power_off,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4902:\t.phy_set_param\t\t= rtw8822c_phy_set_param,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-4903-\t.read_efuse\t\t= rtw8822c_read_efuse,\n"
}

17/2 2026/08/12 17:24 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 28656
							output: 39
							thoughts: 59
						

Thoughts:
Okay, let's break this down.

**Diving into the `phy_set_param` Function Call**

Alright, so I'm looking at something within `rtw8822c_ops`. Right, that's part of the broader `struct rtw_chip_ops` structure. This means it's a critical component of the driver's interface. Now, I see that `phy_set_param` is being invoked – and the core driver is the one calling it. That’s a key detail! I need to understand the control flow here. My next step is to pinpoint the exact location(s) where `phy_set_param` is called within the driver's core logic. Knowing the call sites will provide valuable context around what parameters are being set and under what circumstances, and will inform my diagnosis. This is the starting point for understanding its behavior and potential issues.



18/2 2026/08/12 17:24 tool grepper
0m Args:
{
  "Expression": "phy_set_param",
  "PathPrefix": "drivers/net/wireless/realtek/rtw88/"
}

Results:
{
  "Output": "drivers/net/wireless/realtek/rtw88/main.c=1374=int rtw_power_on(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/main.c-1412-\ndrivers/net/wireless/realtek/rtw88/main.c:1413:\tchip-\u003eops-\u003ephy_set_param(rtwdev);\ndrivers/net/wireless/realtek/rtw88/main.c-1414-\n--\ndrivers/net/wireless/realtek/rtw88/main.h=862=struct rtw_chip_ops {\n--\ndrivers/net/wireless/realtek/rtw88/main.h-869-\tint (*read_efuse)(struct rtw_dev *rtwdev, u8 *map);\ndrivers/net/wireless/realtek/rtw88/main.h:870:\tvoid (*phy_set_param)(struct rtw_dev *rtwdev);\ndrivers/net/wireless/realtek/rtw88/main.h-871-\tvoid (*set_channel)(struct rtw_dev *rtwdev, u8 channel,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8703b.c=553=static void rtw8703b_pwrtrack_init(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8703b.c-577-\ndrivers/net/wireless/realtek/rtw88/rtw8703b.c:578:static void rtw8703b_phy_set_param(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8703b.c-579-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8703b.c=1836=static const struct rtw_chip_ops rtw8703b_ops = {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8703b.c-1843-\t.read_efuse\t\t= rtw8703b_read_efuse,\ndrivers/net/wireless/realtek/rtw88/rtw8703b.c:1844:\t.phy_set_param\t\t= rtw8703b_phy_set_param,\ndrivers/net/wireless/realtek/rtw88/rtw8703b.c-1845-\t.set_channel\t\t= rtw8703b_set_channel,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8723d.c=67=static void rtw8723d_pwrtrack_init(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8723d.c-84-\ndrivers/net/wireless/realtek/rtw88/rtw8723d.c:85:static void rtw8723d_phy_set_param(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8723d.c-86-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8723d.c=1392=static const struct rtw_chip_ops rtw8723d_ops = {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8723d.c-1394-\t.power_off\t\t= rtw_power_off,\ndrivers/net/wireless/realtek/rtw88/rtw8723d.c:1395:\t.phy_set_param\t\t= rtw8723d_phy_set_param,\ndrivers/net/wireless/realtek/rtw88/rtw8723d.c-1396-\t.read_efuse\t\t= rtw8723x_read_efuse,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8812a.c=914=static const struct rtw_chip_ops rtw8812a_ops = {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8812a.c-916-\t.power_off\t\t= rtw8812a_power_off,\ndrivers/net/wireless/realtek/rtw88/rtw8812a.c:917:\t.phy_set_param\t\t= NULL,\ndrivers/net/wireless/realtek/rtw88/rtw8812a.c-918-\t.read_efuse\t\t= rtw88xxa_read_efuse,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8814a.c=265=static void rtw8814a_config_cck_rx_antenna_init(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8814a.c-282-\ndrivers/net/wireless/realtek/rtw88/rtw8814a.c:283:static void rtw8814a_phy_set_param(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8814a.c-284-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8814a.c=2050=static const struct rtw_chip_ops rtw8814a_ops = {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8814a.c-2052-\t.power_off\t\t= rtw_power_off,\ndrivers/net/wireless/realtek/rtw88/rtw8814a.c:2053:\t.phy_set_param\t\t= rtw8814a_phy_set_param,\ndrivers/net/wireless/realtek/rtw88/rtw8814a.c-2054-\t.read_efuse\t\t= rtw8814a_read_efuse,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8821a.c=860=static const struct rtw_chip_ops rtw8821a_ops = {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8821a.c-862-\t.power_off\t\t= rtw8821a_power_off,\ndrivers/net/wireless/realtek/rtw88/rtw8821a.c:863:\t.phy_set_param\t\t= NULL,\ndrivers/net/wireless/realtek/rtw88/rtw8821a.c-864-\t.read_efuse\t\t= rtw88xxa_read_efuse,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8821c.c=151=static void rtw8821c_phy_bf_init(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8821c.c-157-\ndrivers/net/wireless/realtek/rtw88/rtw8821c.c:158:static void rtw8821c_phy_set_param(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8821c.c-159-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8821c.c=1658=static const struct rtw_chip_ops rtw8821c_ops = {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8821c.c-1660-\t.power_off\t\t= rtw_power_off,\ndrivers/net/wireless/realtek/rtw88/rtw8821c.c:1661:\t.phy_set_param\t\t= rtw8821c_phy_set_param,\ndrivers/net/wireless/realtek/rtw88/rtw8821c.c-1662-\t.read_efuse\t\t= rtw8821c_read_efuse,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822b.c=145=static void rtw8822b_phy_bf_init(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822b.c-151-\ndrivers/net/wireless/realtek/rtw88/rtw8822b.c:152:static void rtw8822b_phy_set_param(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8822b.c-153-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822b.c=2150=static const struct rtw_chip_ops rtw8822b_ops = {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822b.c-2152-\t.power_off\t\t= rtw_power_off,\ndrivers/net/wireless/realtek/rtw88/rtw8822b.c:2153:\t.phy_set_param\t\t= rtw8822b_phy_set_param,\ndrivers/net/wireless/realtek/rtw88/rtw8822b.c-2154-\t.read_efuse\t\t= rtw8822b_read_efuse,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=1787=static void rtw8822c_pwrtrack_init(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1802-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1803:static void rtw8822c_phy_set_param(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1804-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=4899=static const struct rtw_chip_ops rtw8822c_ops = {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-4901-\t.power_off\t\t= rtw_power_off,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4902:\t.phy_set_param\t\t= rtw8822c_phy_set_param,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-4903-\t.read_efuse\t\t= rtw8822c_read_efuse,\n"
}

19/2 2026/08/12 17:24 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 31891
							output: 40
							thoughts: 445
						

Thoughts:
**Analyzing the Initialization Flow**

Okay, so I'm looking at how this Realtek wireless device comes to life. My initial thought was `rtw_power_on`, that seems like the obvious entry point, right? But then I saw that `rtw8822c_rf_dac_cal` is also called by `rtw8822c_dac_cal_restore`. That feels internal though, so I dismissed it.

So, the trace looks like `rtw_power_on` -> `phy_set_param` -> `rtw8822c_phy_set_param` -> `rtw8822c_rf_init` -> `rtw8822c_rf_dac_cal`.

Now, the prompt specifically wants me to avoid hot-path functions to prevent skewed test distributions. My first thought was whether `rtw_power_on` would be suitable, but it’s probably too generic, so I should dig deeper.

The prompt wants non-static, non-inlined entry points. Okay, `rtw8822c_phy_set_param` is a possibility. But that's static! Wait, it's assigned to a function pointer in `rtw8822c_ops`. *Ah*, that's the key. Function pointers avoid inlining because the compiler needs to be able to resolve an address. That's good; it means `rtw8822c_phy_set_param` has a distinct symbol address even though it's static.

But, the prompt wants to avoid static functions, so I should look into this further. I'll check its definition to confirm it's static. Yes, it is static.

But, the prompt also says it prefers non-static entry points, so what about `rtw_power_on`? That's not static. I'll check `rtw_power_on` in `drivers/net/wireless/realtek/rtw88/main.c` to see if it's the right choice.



20/2 2026/08/12 17:25 tool grepper
0m Args:
{
  "Expression": "rtw_power_on",
  "PathPrefix": "drivers/net/wireless/realtek/rtw88/"
}

Results:
{
  "Output": "drivers/net/wireless/realtek/rtw88/main.c=1354=static enum rtw_lps_deep_mode rtw_update_lps_deep_mode(struct rtw_dev *rtwdev,\n--\ndrivers/net/wireless/realtek/rtw88/main.c-1373-\ndrivers/net/wireless/realtek/rtw88/main.c:1374:int rtw_power_on(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/main.c-1375-{\n--\ndrivers/net/wireless/realtek/rtw88/main.c-1442-}\ndrivers/net/wireless/realtek/rtw88/main.c:1443:EXPORT_SYMBOL(rtw_power_on);\ndrivers/net/wireless/realtek/rtw88/main.c-1444-\n--\ndrivers/net/wireless/realtek/rtw88/main.h=2271=int rtw_wait_firmware_completion(struct rtw_dev *rtwdev);\ndrivers/net/wireless/realtek/rtw88/main.h:2272:int rtw_power_on(struct rtw_dev *rtwdev);\ndrivers/net/wireless/realtek/rtw88/main.h-2273-void rtw_core_fw_scan_notify(struct rtw_dev *rtwdev, bool start);\n--\ndrivers/net/wireless/realtek/rtw88/rtw8703b.c=1836=static const struct rtw_chip_ops rtw8703b_ops = {\ndrivers/net/wireless/realtek/rtw88/rtw8703b.c:1837:\t.power_on\t\t= rtw_power_on,\ndrivers/net/wireless/realtek/rtw88/rtw8703b.c-1838-\t.power_off\t\t= rtw_power_off,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8723d.c=1392=static const struct rtw_chip_ops rtw8723d_ops = {\ndrivers/net/wireless/realtek/rtw88/rtw8723d.c:1393:\t.power_on\t\t= rtw_power_on,\ndrivers/net/wireless/realtek/rtw88/rtw8723d.c-1394-\t.power_off\t\t= rtw_power_off,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8814a.c=2050=static const struct rtw_chip_ops rtw8814a_ops = {\ndrivers/net/wireless/realtek/rtw88/rtw8814a.c:2051:\t.power_on\t\t= rtw_power_on,\ndrivers/net/wireless/realtek/rtw88/rtw8814a.c-2052-\t.power_off\t\t= rtw_power_off,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8821c.c=1658=static const struct rtw_chip_ops rtw8821c_ops = {\ndrivers/net/wireless/realtek/rtw88/rtw8821c.c:1659:\t.power_on\t\t= rtw_power_on,\ndrivers/net/wireless/realtek/rtw88/rtw8821c.c-1660-\t.power_off\t\t= rtw_power_off,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822b.c=2150=static const struct rtw_chip_ops rtw8822b_ops = {\ndrivers/net/wireless/realtek/rtw88/rtw8822b.c:2151:\t.power_on\t\t= rtw_power_on,\ndrivers/net/wireless/realtek/rtw88/rtw8822b.c-2152-\t.power_off\t\t= rtw_power_off,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=4899=static const struct rtw_chip_ops rtw8822c_ops = {\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4900:\t.power_on\t\t= rtw_power_on,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-4901-\t.power_off\t\t= rtw_power_off,\n"
}

21/2 2026/08/12 17:25 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 34054
							output: 46
							thoughts: 306
						

Thoughts:
**Analyzing the rtw_power_on Call Chain**

Okay, so `rtw_power_on` is exported, that's the starting point. But, hang on a second, my intuition kicks in, it's called by mac80211 when the interface comes up. Now, are there any other functions in the call chain? Let's trace it and see.

The patch focuses on modifying several functions: `rtw8822c_dac_iq_cmp_s32`, `rtw8822c_dac_iq_sort`, `rtw8822c_dac_iq_offset`, `rtw8822c_dac_iq_check`, `rtw8822c_dac_cal_iq_sample`, `rtw8822c_dac_cal_iq_search`, and `rtw8822c_dac_cal_rf_mode`. Immediately I recognize that they all relate to DAC calibration, as expected. They are all called from `rtw8822c_rf_dac_cal`. Excellent, that's our next link.

Now, `rtw8822c_rf_dac_cal` is triggered by `rtw8822c_rf_init`. Makes perfect sense. `rtw8822c_rf_init` is called by both `rtw8822c_phy_set_param` and `rtw8822c_do_gapk`. Aha!

But what about `rtw8822c_do_gapk`? is it called by `rtw8822c_phy_set_param`, that's an interesting question. Let's make sure.



22/2 2026/08/12 17:25 tool grepper
0m Args:
{
  "Expression": "rtw8822c_do_gapk",
  "PathPrefix": "drivers/net/wireless/realtek/rtw88/"
}

Results:
{
  "Output": "drivers/net/wireless/realtek/rtw88/rtw8822c.c=1723=static void rtw8822c_txgapk(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1764-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:1765:static void rtw8822c_do_gapk(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-1766-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=4119=static void rtw8822c_phy_calibration(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-4121-\trtw8822c_rfk_power_save(rtwdev, false);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4122:\trtw8822c_do_gapk(rtwdev);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-4123-\trtw8822c_do_iqk(rtwdev);\n"
}

23/2 2026/08/12 17:25 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 35185
							output: 45
							thoughts: 37
						

Thoughts:
Here's a summary of my thought process:

**Diving into the PHY Calibration Routine**

Okay, so I see `rtw8822c_phy_calibration` is mentioned in the code. My immediate question is: where is it being *called* from? I suspect it's likely called within the `rtw8822c_phy_set_param` function. That seems like the logical place, given the name. To confirm this, I need to trace the call graph and verify the relationship. Let me quickly cross-reference these two functions and see if my hunch is correct. I want to understand the exact triggering mechanism for this calibration; is it based on parameter changes, power-up sequence, or something else entirely? A quick check should confirm my initial assumption.



24/2 2026/08/12 17:25 tool grepper
0m Args:
{
  "Expression": "rtw8822c_phy_calibration",
  "PathPrefix": "drivers/net/wireless/realtek/rtw88/"
}

Results:
{
  "Output": "drivers/net/wireless/realtek/rtw88/rtw8822c.c=4077=static void rtw8822c_do_dpk(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-4118-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4119:static void rtw8822c_phy_calibration(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-4120-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=4899=static const struct rtw_chip_ops rtw8822c_ops = {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-4916-\t.dpk_track\t\t= rtw8822c_dpk_track,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4917:\t.phy_calibration\t= rtw8822c_phy_calibration,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-4918-\t.cck_pd_set\t\t= rtw8822c_phy_cck_pd_set,\n"
}

25/2 2026/08/12 17:25 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 35829
							output: 37
							thoughts: 30
						

Thoughts:
Okay, here's my interpretation of those thoughts, framed as my own mental process, given my expertise:

**Diving Deeper into the Calibration Routine**

Alright, so the initial clue points to `rtw8822c_ops`, that's where I need to focus. I need to understand the full context of the `phy_calibration` call. To do that, I need to trace it. Where exactly is this calibration function invoked? I need to quickly identify all the points in the code where `phy_calibration` is called within that module, or potentially even further afield if it's a critical component. This will allow me to assess dependencies and potential areas of impact. I need to understand its relationship to other functions, what triggers it, and what data it utilizes to achieve its goal. Let's start the search...



26/2 2026/08/12 17:25 tool grepper
0m Args:
{
  "Expression": "phy_calibration",
  "PathPrefix": "drivers/net/wireless/realtek/rtw88/"
}

Results:
{
  "Output": "drivers/net/wireless/realtek/rtw88/mac80211.c=462=static int rtw_ops_start_ap(struct ieee80211_hw *hw,\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-472-\trtw_store_op_chan(rtwdev, true);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:473:\tchip-\u003eops-\u003ephy_calibration(rtwdev);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-474-\tmutex_unlock(\u0026rtwdev-\u003emutex);\n--\ndrivers/net/wireless/realtek/rtw88/main.c=915=void rtw_chip_prepare_tx(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/main.c-920-\t\trtwdev-\u003eneed_rfk = false;\ndrivers/net/wireless/realtek/rtw88/main.c:921:\t\tchip-\u003eops-\u003ephy_calibration(rtwdev);\ndrivers/net/wireless/realtek/rtw88/main.c-922-\t}\n--\ndrivers/net/wireless/realtek/rtw88/main.h=862=struct rtw_chip_ops {\n--\ndrivers/net/wireless/realtek/rtw88/main.h-888-\tvoid (*false_alarm_statistics)(struct rtw_dev *rtwdev);\ndrivers/net/wireless/realtek/rtw88/main.h:889:\tvoid (*phy_calibration)(struct rtw_dev *rtwdev);\ndrivers/net/wireless/realtek/rtw88/main.h-890-\tvoid (*dpk_track)(struct rtw_dev *rtwdev);\n--\ndrivers/net/wireless/realtek/rtw88/rtw8703b.c=1275=void rtw8703b_iqk_fill_a_matrix(struct rtw_dev *rtwdev, const s32 result[])\n--\ndrivers/net/wireless/realtek/rtw88/rtw8703b.c-1320-\ndrivers/net/wireless/realtek/rtw88/rtw8703b.c:1321:static void rtw8703b_phy_calibration(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8703b.c-1322-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8703b.c=1587=static void rtw8703b_phy_pwrtrack(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8703b.c-1634-\tif (do_iqk)\ndrivers/net/wireless/realtek/rtw88/rtw8703b.c:1635:\t\trtw8703b_phy_calibration(rtwdev);\ndrivers/net/wireless/realtek/rtw88/rtw8703b.c-1636-}\n--\ndrivers/net/wireless/realtek/rtw88/rtw8703b.c=1836=static const struct rtw_chip_ops rtw8703b_ops = {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8703b.c-1854-\t.false_alarm_statistics\t= rtw8723x_false_alarm_statistics,\ndrivers/net/wireless/realtek/rtw88/rtw8703b.c:1855:\t.phy_calibration\t= rtw8703b_phy_calibration,\ndrivers/net/wireless/realtek/rtw88/rtw8703b.c-1856-\t.dpk_track\t\t= NULL,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8723d.c=824=void rtw8723d_iqk_one_round(struct rtw_dev *rtwdev, s32 result[][IQK_NR], u8 t,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8723d.c-924-\ndrivers/net/wireless/realtek/rtw88/rtw8723d.c:925:static void rtw8723d_phy_calibration(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8723d.c-926-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8723d.c=1322=static void rtw8723d_phy_pwrtrack(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8723d.c-1369-\tif (do_iqk)\ndrivers/net/wireless/realtek/rtw88/rtw8723d.c:1370:\t\trtw8723d_phy_calibration(rtwdev);\ndrivers/net/wireless/realtek/rtw88/rtw8723d.c-1371-}\n--\ndrivers/net/wireless/realtek/rtw88/rtw8723d.c=1392=static const struct rtw_chip_ops rtw8723d_ops = {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8723d.c-1409-\t.false_alarm_statistics\t= rtw8723x_false_alarm_statistics,\ndrivers/net/wireless/realtek/rtw88/rtw8723d.c:1410:\t.phy_calibration\t= rtw8723d_phy_calibration,\ndrivers/net/wireless/realtek/rtw88/rtw8723d.c-1411-\t.cck_pd_set\t\t= rtw8723d_phy_cck_pd_set,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8812a.c=788=static void rtw8812a_do_iqk(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8812a.c-839-\ndrivers/net/wireless/realtek/rtw88/rtw8812a.c:840:static void rtw8812a_phy_calibration(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8812a.c-841-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8812a.c=914=static const struct rtw_chip_ops rtw8812a_ops = {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8812a.c-930-\t.false_alarm_statistics\t= rtw88xxa_false_alarm_statistics,\ndrivers/net/wireless/realtek/rtw88/rtw8812a.c:931:\t.phy_calibration\t= rtw8812a_phy_calibration,\ndrivers/net/wireless/realtek/rtw88/rtw8812a.c-932-\t.cck_pd_set\t\t= rtw88xxa_phy_cck_pd_set,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8814a.c=1767=static void rtw8814a_do_iqk(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8814a.c-1791-\ndrivers/net/wireless/realtek/rtw88/rtw8814a.c:1792:static void rtw8814a_phy_calibration(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8814a.c-1793-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8814a.c=2050=static const struct rtw_chip_ops rtw8814a_ops = {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8814a.c-2066-\t.false_alarm_statistics\t= rtw8814a_false_alarm_statistics,\ndrivers/net/wireless/realtek/rtw88/rtw8814a.c:2067:\t.phy_calibration\t= rtw8814a_phy_calibration,\ndrivers/net/wireless/realtek/rtw88/rtw8814a.c-2068-\t.cck_pd_set\t\t= rtw8814a_phy_cck_pd_set,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8821a.c=655=static void rtw8821a_do_iqk(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8821a.c-688-\ndrivers/net/wireless/realtek/rtw88/rtw8821a.c:689:static void rtw8821a_phy_calibration(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8821a.c-690-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8821a.c=860=static const struct rtw_chip_ops rtw8821a_ops = {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8821a.c-876-\t.false_alarm_statistics\t= rtw88xxa_false_alarm_statistics,\ndrivers/net/wireless/realtek/rtw88/rtw8821a.c:877:\t.phy_calibration\t= rtw8821a_phy_calibration,\ndrivers/net/wireless/realtek/rtw88/rtw8821a.c-878-\t.cck_pd_set\t\t= rtw88xxa_phy_cck_pd_set,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8821c.c=774=static void rtw8821c_do_iqk(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8821c.c-801-\ndrivers/net/wireless/realtek/rtw88/rtw8821c.c:802:static void rtw8821c_phy_calibration(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8821c.c-803-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8821c.c=1658=static const struct rtw_chip_ops rtw8821c_ops = {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8821c.c-1673-\t.false_alarm_statistics\t= rtw8821c_false_alarm_statistics,\ndrivers/net/wireless/realtek/rtw88/rtw8821c.c:1674:\t.phy_calibration\t= rtw8821c_phy_calibration,\ndrivers/net/wireless/realtek/rtw88/rtw8821c.c-1675-\t.cck_pd_set\t\t= rtw8821c_phy_cck_pd_set,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822b.c=1071=static void rtw8822b_do_iqk(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822b.c-1095-\ndrivers/net/wireless/realtek/rtw88/rtw8822b.c:1096:static void rtw8822b_phy_calibration(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8822b.c-1097-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822b.c=2150=static const struct rtw_chip_ops rtw8822b_ops = {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822b.c-2165-\t.false_alarm_statistics\t= rtw8822b_false_alarm_statistics,\ndrivers/net/wireless/realtek/rtw88/rtw8822b.c:2166:\t.phy_calibration\t= rtw8822b_phy_calibration,\ndrivers/net/wireless/realtek/rtw88/rtw8822b.c-2167-\t.pwr_track\t\t= rtw8822b_pwr_track,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=4077=static void rtw8822c_do_dpk(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-4118-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4119:static void rtw8822c_phy_calibration(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-4120-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=4899=static const struct rtw_chip_ops rtw8822c_ops = {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-4916-\t.dpk_track\t\t= rtw8822c_dpk_track,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4917:\t.phy_calibration\t= rtw8822c_phy_calibration,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-4918-\t.cck_pd_set\t\t= rtw8822c_phy_cck_pd_set,\n"
}

27/2 2026/08/12 17:25 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 39973
							output: 47
							thoughts: 742
						

Thoughts:
**Analyzing Realtek Driver Entry Points**

Okay, so I'm tracing the execution flow here, trying to pinpoint the critical entry points for this Realtek wireless driver, specifically focusing on the modified code. My initial thought was `rtw_chip_prepare_tx`, since that calls `phy_calibration`, and also `rtw_ops_start_ap` which *also* calls `phy_calibration`. But wait, `rtw_chip_prepare_tx` is part of the MAC80211 packet transmission process, so that's a good place to start but not necessarily the *best* entry point. I'm going to look deeper.

`rtw_power_on` looks promising as an initial entry point. Let me confirm if it's exported and, yep, it is. But, I need to get *deeper* into the code to the actual functions of interest.

Let's look more closely at `phy_calibration` and related functions. I recall that `rtw8822c_phy_calibration` and `rtw8822c_phy_set_param` are both static, but they are assigned to function pointers for `phy_calibration` and `phy_set_param` respectively. Now, this is important. My understanding is that, since these are assigned to function pointers, they won't be inlined by the compiler, and therefore, they are distinct symbols. So, as the prompt directs, I can consider them valid entry points. That simplifies things a bit! Based on the prompt I can list `rtw8822c_phy_calibration` and `rtw8822c_phy_set_param`.

But I remember the modified code is in `rtw8822c_rf_dac_cal`, which is called from `rtw8822c_rf_init`. Let me trace the calls. Okay, `rtw8822c_rf_init` is called by `rtw8822c_phy_set_param` and `rtw8822c_do_gapk`. And `rtw8822c_do_gapk` is called by `rtw8822c_phy_calibration`. Bingo! This confirms that `rtw8822c_phy_set_param` and `rtw8822c_phy_calibration` are the *exact* entry points for the part of the code I'm interested in!

Now I need to ensure they won't be inlined. Let's double-check the static nature of `rtw8822c_rf_init` and `rtw8822c_rf_dac_cal`. Yep, they're both static. And they are only called in a couple of places. This *might* mean the compiler is free to inline them. But, since `rtw8822c_phy_set_param` and `rtw8822c_phy_calibration` are function pointers, I think it's safest to focus on these.

Now, let's verify the configuration. I recall from the config file that `RTW88_8822CU` is needed to enable the USB driver. Wait, wait, `RTW88_8822C` is the config that actually compiles `rtw8822c.c`, which is the file with the code I'm looking at. Hmm, it's a hidden config, selected by `RTW88_8822CE`, `RTW88_8822CS`, and `RTW88_8822CU`. Right, I'll need to check the Kconfig in `drivers/net/wireless/realtek/rtw88/Kconfig` to confirm these dependencies. I'll need to remember that!



28/2 2026/08/12 17:25 tool grepper
0m Args:
{
  "Expression": "config RTW88_8822C",
  "PathPrefix": "drivers/net/wireless/realtek/rtw88/Kconfig"
}

Results:
{
  "Output": "drivers/net/wireless/realtek/rtw88/Kconfig=26=config RTW88_8822B\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-28-\ndrivers/net/wireless/realtek/rtw88/Kconfig:29:config RTW88_8822C\ndrivers/net/wireless/realtek/rtw88/Kconfig-30-\ttristate\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig=82=config RTW88_8822BU\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-92-\ndrivers/net/wireless/realtek/rtw88/Kconfig:93:config RTW88_8822CE\ndrivers/net/wireless/realtek/rtw88/Kconfig-94-\ttristate \"Realtek 8822CE PCI wireless network adapter\"\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-103-\ndrivers/net/wireless/realtek/rtw88/Kconfig:104:config RTW88_8822CS\ndrivers/net/wireless/realtek/rtw88/Kconfig-105-\ttristate \"Realtek 8822CS SDIO wireless network adapter\"\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-114-\ndrivers/net/wireless/realtek/rtw88/Kconfig:115:config RTW88_8822CU\ndrivers/net/wireless/realtek/rtw88/Kconfig-116-\ttristate \"Realtek 8822CU USB wireless network adapter\"\n"
}

29/2 2026/08/12 17:25 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 42058
							output: 41
							thoughts: 92
						

Thoughts:
**Analyzing the RTW88 Wireless Driver Configuration**

Okay, so `RTW88_8822C` is a tristate setting, and importantly, it doesn't have a prompt. That means we need to ensure the USB variant, `RTW88_8822CU`, is compiled in order to test it effectively through USB. Wait a minute… `RTW88_8822CU` is *dependent* on `USB`. That’s good, but it makes me wonder if there are any other underlying requirements. Better to be thorough. I'll need to drill down and examine the dependencies of the broader `RTW88` configuration to be absolutely sure we've covered all the bases.



30/2 2026/08/12 17:25 tool grepper
0m Args:
{
  "Expression": "config RTW88",
  "PathPrefix": "drivers/net/wireless/realtek/rtw88/Kconfig"
}

Results:
{
  "Output": "drivers/net/wireless/realtek/rtw88/Kconfig-1-# SPDX-License-Identifier: GPL-2.0-only\ndrivers/net/wireless/realtek/rtw88/Kconfig:2:menuconfig RTW88\ndrivers/net/wireless/realtek/rtw88/Kconfig-3-\ttristate \"Realtek 802.11ac wireless chips support\"\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig=11=if RTW88\ndrivers/net/wireless/realtek/rtw88/Kconfig-12-\ndrivers/net/wireless/realtek/rtw88/Kconfig:13:config RTW88_CORE\ndrivers/net/wireless/realtek/rtw88/Kconfig-14-\ttristate\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-16-\ndrivers/net/wireless/realtek/rtw88/Kconfig:17:config RTW88_PCI\ndrivers/net/wireless/realtek/rtw88/Kconfig-18-\ttristate\ndrivers/net/wireless/realtek/rtw88/Kconfig-19-\ndrivers/net/wireless/realtek/rtw88/Kconfig:20:config RTW88_SDIO\ndrivers/net/wireless/realtek/rtw88/Kconfig-21-\ttristate\ndrivers/net/wireless/realtek/rtw88/Kconfig-22-\ndrivers/net/wireless/realtek/rtw88/Kconfig:23:config RTW88_USB\ndrivers/net/wireless/realtek/rtw88/Kconfig-24-\ttristate\ndrivers/net/wireless/realtek/rtw88/Kconfig-25-\ndrivers/net/wireless/realtek/rtw88/Kconfig:26:config RTW88_8822B\ndrivers/net/wireless/realtek/rtw88/Kconfig-27-\ttristate\ndrivers/net/wireless/realtek/rtw88/Kconfig-28-\ndrivers/net/wireless/realtek/rtw88/Kconfig:29:config RTW88_8822C\ndrivers/net/wireless/realtek/rtw88/Kconfig-30-\ttristate\ndrivers/net/wireless/realtek/rtw88/Kconfig-31-\ndrivers/net/wireless/realtek/rtw88/Kconfig:32:config RTW88_8723X\ndrivers/net/wireless/realtek/rtw88/Kconfig-33-\ttristate\ndrivers/net/wireless/realtek/rtw88/Kconfig-34-\ndrivers/net/wireless/realtek/rtw88/Kconfig:35:config RTW88_8703B\ndrivers/net/wireless/realtek/rtw88/Kconfig-36-\ttristate\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-38-\ndrivers/net/wireless/realtek/rtw88/Kconfig:39:config RTW88_8723D\ndrivers/net/wireless/realtek/rtw88/Kconfig-40-\ttristate\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-42-\ndrivers/net/wireless/realtek/rtw88/Kconfig:43:config RTW88_8821C\ndrivers/net/wireless/realtek/rtw88/Kconfig-44-\ttristate\ndrivers/net/wireless/realtek/rtw88/Kconfig-45-\ndrivers/net/wireless/realtek/rtw88/Kconfig:46:config RTW88_88XXA\ndrivers/net/wireless/realtek/rtw88/Kconfig-47-\ttristate\ndrivers/net/wireless/realtek/rtw88/Kconfig-48-\ndrivers/net/wireless/realtek/rtw88/Kconfig:49:config RTW88_8821A\ndrivers/net/wireless/realtek/rtw88/Kconfig-50-\ttristate\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-52-\ndrivers/net/wireless/realtek/rtw88/Kconfig:53:config RTW88_8812A\ndrivers/net/wireless/realtek/rtw88/Kconfig-54-\ttristate\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-56-\ndrivers/net/wireless/realtek/rtw88/Kconfig:57:config RTW88_8814A\ndrivers/net/wireless/realtek/rtw88/Kconfig-58-\ttristate\ndrivers/net/wireless/realtek/rtw88/Kconfig-59-\ndrivers/net/wireless/realtek/rtw88/Kconfig:60:config RTW88_8822BE\ndrivers/net/wireless/realtek/rtw88/Kconfig-61-\ttristate \"Realtek 8822BE PCI wireless network adapter\"\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-70-\ndrivers/net/wireless/realtek/rtw88/Kconfig:71:config RTW88_8822BS\ndrivers/net/wireless/realtek/rtw88/Kconfig-72-\ttristate \"Realtek 8822BS SDIO wireless network adapter\"\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-81-\ndrivers/net/wireless/realtek/rtw88/Kconfig:82:config RTW88_8822BU\ndrivers/net/wireless/realtek/rtw88/Kconfig-83-\ttristate \"Realtek 8822BU USB wireless network adapter\"\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-92-\ndrivers/net/wireless/realtek/rtw88/Kconfig:93:config RTW88_8822CE\ndrivers/net/wireless/realtek/rtw88/Kconfig-94-\ttristate \"Realtek 8822CE PCI wireless network adapter\"\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-103-\ndrivers/net/wireless/realtek/rtw88/Kconfig:104:config RTW88_8822CS\ndrivers/net/wireless/realtek/rtw88/Kconfig-105-\ttristate \"Realtek 8822CS SDIO wireless network adapter\"\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-114-\ndrivers/net/wireless/realtek/rtw88/Kconfig:115:config RTW88_8822CU\ndrivers/net/wireless/realtek/rtw88/Kconfig-116-\ttristate \"Realtek 8822CU USB wireless network adapter\"\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-125-\ndrivers/net/wireless/realtek/rtw88/Kconfig:126:config RTW88_8723DE\ndrivers/net/wireless/realtek/rtw88/Kconfig-127-\ttristate \"Realtek 8723DE PCI wireless network adapter\"\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-136-\ndrivers/net/wireless/realtek/rtw88/Kconfig:137:config RTW88_8723DS\ndrivers/net/wireless/realtek/rtw88/Kconfig-138-\ttristate \"Realtek 8723DS SDIO wireless network adapter\"\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-147-\ndrivers/net/wireless/realtek/rtw88/Kconfig:148:config RTW88_8723CS\ndrivers/net/wireless/realtek/rtw88/Kconfig-149-\ttristate \"Realtek 8723CS SDIO wireless network adapter\"\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-161-\ndrivers/net/wireless/realtek/rtw88/Kconfig:162:config RTW88_8723DU\ndrivers/net/wireless/realtek/rtw88/Kconfig-163-\ttristate \"Realtek 8723DU USB wireless network adapter\"\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-172-\ndrivers/net/wireless/realtek/rtw88/Kconfig:173:config RTW88_8821CE\ndrivers/net/wireless/realtek/rtw88/Kconfig-174-\ttristate \"Realtek 8821CE PCI wireless network adapter\"\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-183-\ndrivers/net/wireless/realtek/rtw88/Kconfig:184:config RTW88_8821CS\ndrivers/net/wireless/realtek/rtw88/Kconfig-185-\ttristate \"Realtek 8821CS SDIO wireless network adapter\"\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-194-\ndrivers/net/wireless/realtek/rtw88/Kconfig:195:config RTW88_8821CU\ndrivers/net/wireless/realtek/rtw88/Kconfig-196-\ttristate \"Realtek 8821CU USB wireless network adapter\"\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-205-\ndrivers/net/wireless/realtek/rtw88/Kconfig:206:config RTW88_8821AU\ndrivers/net/wireless/realtek/rtw88/Kconfig-207-\ttristate \"Realtek 8821AU/8811AU USB wireless network adapter\"\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-216-\ndrivers/net/wireless/realtek/rtw88/Kconfig:217:config RTW88_8812AU\ndrivers/net/wireless/realtek/rtw88/Kconfig-218-\ttristate \"Realtek 8812AU USB wireless network adapter\"\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-227-\ndrivers/net/wireless/realtek/rtw88/Kconfig:228:config RTW88_8814AE\ndrivers/net/wireless/realtek/rtw88/Kconfig-229-\ttristate \"Realtek 8814AE PCI wireless network adapter\"\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-238-\ndrivers/net/wireless/realtek/rtw88/Kconfig:239:config RTW88_8814AU\ndrivers/net/wireless/realtek/rtw88/Kconfig-240-\ttristate \"Realtek 8814AU USB wireless network adapter\"\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-249-\ndrivers/net/wireless/realtek/rtw88/Kconfig:250:config RTW88_DEBUG\ndrivers/net/wireless/realtek/rtw88/Kconfig-251-\tbool \"Realtek rtw88 debug support\"\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-257-\ndrivers/net/wireless/realtek/rtw88/Kconfig:258:config RTW88_DEBUGFS\ndrivers/net/wireless/realtek/rtw88/Kconfig-259-\tbool \"Realtek rtw88 debugfs support\"\n--\ndrivers/net/wireless/realtek/rtw88/Kconfig-265-\ndrivers/net/wireless/realtek/rtw88/Kconfig:266:config RTW88_LEDS\ndrivers/net/wireless/realtek/rtw88/Kconfig-267-\tbool\n"
}

31/2 2026/08/12 17:25 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 45472
							output: 42
							thoughts: 65
						

Thoughts:
**Analyzing the Wireless Configuration**

Okay, so the primary configuration we're working with here seems to be `RTW88`. Right, so that means we'll definitely need to include `RTW88`, and also, from what I'm seeing, `RTW88_8822CU`. No surprises there. Hold on... I'm just recalling something; `RTW88` relies on `MAC80211`. That's an important dependency to keep in mind; gotta make sure that's handled correctly in this setup. Let me just quickly check `RTW88`'s dependencies again to be certain everything's in order, just to cross-reference and confirm it all jives.



32/2 2026/08/12 17:25 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/realtek/rtw88/Kconfig",
  "FirstLine": 1,
  "LineCount": 20
}

Results:
{
  "Contents": "   1:\t# SPDX-License-Identifier: GPL-2.0-only\n   2:\tmenuconfig RTW88\n   3:\t\ttristate \"Realtek 802.11ac wireless chips support\"\n   4:\t\tdepends on MAC80211\n   5:\t\thelp\n   6:\t\t  This module adds support for mac80211-based wireless drivers that\n   7:\t\t  enables Realtek IEEE 802.11ac wireless chipsets.\n   8:\t\n   9:\t\t  If you choose to build a module, it'll be called rtw88.\n  10:\t\n  11:\tif RTW88\n  12:\t\n  13:\tconfig RTW88_CORE\n  14:\t\ttristate\n  15:\t\tselect WANT_DEV_COREDUMP\n  16:\t\n  17:\tconfig RTW88_PCI\n  18:\t\ttristate\n  19:\t\n  20:\tconfig RTW88_SDIO\n"
}

33/2 2026/08/12 17:25 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 46003
							output: 222
							thoughts: 1350
						

Thoughts:
**My Analysis of the Realtek rtw8822c Wireless Driver Patch for Fuzzing**

Okay, here's my thought process. I need to figure out the right approach for fuzzing this Realtek driver patch.

First, I see that this modification targets the DAC IQ calibration process within the `rtw8822c` chip. This calibration is performed during PHY parameter setting and calibration. From a configuration standpoint, `MAC80211` is obviously required, as is `RTW88` for the driver itself, and specifically `RTW88_8822CU` to enable the USB variant, which will be useful for virtualized fuzzing. `USB` is also required, but it's a standard config, so I'll include it.

Now, the crucial part: identifying the relevant symbols. The prompt suggests prioritizing non-static, non-inlined entry points. Initially, I considered `rtw_power_on`, but that's too broad; it might trigger functions across various `rtw88` chips. I want to be as precise as possible. The patch specifically modifies functions like `rtw8822c_dac_iq_cmp_s32`, `rtw8822c_dac_iq_sort`, and so on. So, what's the best way to hit that code?

I looked at `rtw8822c_phy_set_param` and `rtw8822c_phy_calibration`. They seem ideal because they are specific to the `rtw8822c` chip. I checked and they are both assigned to function pointers within the `rtw8822c_ops` struct. That means the compiler *cannot* inline them, since their addresses are needed. They're non-static, so the prompt requirements are satisfied. Although `rtw8822c_phy_set_param` *is* static, the prompt is satisfied because it is not inlined and its address is taken.

I also considered `rtw8822c_rf_dac_cal`, as that's the function that *directly* contains the modified code. However, it's called by `rtw8822c_rf_init` and `rtw8822c_dac_cal_restore`, so it might be inlined. It's less likely, but still a possibility. To be safe, I'll stick with `rtw8822c_phy_set_param` and `rtw8822c_phy_calibration`. These should give a good entry point to trigger the code, as the prompt specifies.

To summarize, the patch modifies DAC IQ calibration logic in the Realtek `rtw8822c` wireless driver, specifically simplifying sorting and offset calculations. This can be reached via USB emulation using the `CONFIG_RTW88_8822CU` option. The modified code is accessed during PHY parameter setup and calibration, which is triggered via `rtw8822c_phy_set_param` and `rtw8822c_phy_calibration`, which are non-inlined function pointers within `rtw8822c_ops`. This is functional because the custom sort and offset calculation is replaced by standard `sort` and simplified math, fixing potential bugs or simplifying code. This patch is definitely worth fuzzing.

My chosen configs are:
*   `MAC80211`
*   `RTW88`
*   `RTW88_8822CU`

My chosen symbols are:
*   `rtw8822c_phy_set_param`
*   `rtw8822c_phy_calibration`



34/2 2026/08/12 17:26 tool set-results
0m Args:
{
  "EnableConfigs": [
    "MAC80211",
    "RTW88",
    "RTW88_8822CU"
  ],
  "FocusSymbols": [
    "rtw8822c_phy_set_param",
    "rtw8822c_phy_calibration"
  ],
  "Reasoning": "The patch modifies the DAC IQ calibration logic in the Realtek rtw8822c wireless driver, simplifying sorting and offset calculations. This driver can be reached in virtualized environments via USB emulation (dummy HCD) by enabling the USB variant of the driver (CONFIG_RTW88_8822CU). The modified code is executed during PHY parameter setup and calibration, which are accessible via the `rtw8822c_phy_set_param` and `rtw8822c_phy_calibration` callbacks. These callbacks are not inlined as they are assigned to function pointers in the chip operations struct.",
  "WorthFuzzing": true
}

Results:
{
  "EnableConfigs": [
    "MAC80211",
    "RTW88",
    "RTW88_8822CU"
  ],
  "FocusSymbols": [
    "rtw8822c_phy_set_param",
    "rtw8822c_phy_calibration"
  ],
  "Reasoning": "The patch modifies the DAC IQ calibration logic in the Realtek rtw8822c wireless driver, simplifying sorting and offset calculations. This driver can be reached in virtualized environments via USB emulation (dummy HCD) by enabling the USB variant of the driver (CONFIG_RTW88_8822CU). The modified code is executed during PHY parameter setup and calibration, which are accessible via the `rtw8822c_phy_set_param` and `rtw8822c_phy_calibration` callbacks. These callbacks are not inlined as they are assigned to function pointers in the chip operations struct.",
  "WorthFuzzing": true
}

35/1 2026/08/12 17:26 action If
1m Args:
{
  "WorthFuzzing": true
}

Results:
null

36/2 2026/08/12 17:26 agent kmsan-evaluator
1m Model:
best-expensive

Args:
null

Results:
{
  "KMSANReasoning": "The patch refactors the IQ calibration logic in the rtw88 driver by replacing custom 10-bit sign-magnitude/two's-complement arithmetic and a custom bubble sort with standard `s32` types, `sign_extend32()`, and the kernel's built-in `sort()` function. \n\nWhile the stack-allocated arrays `iv` and `qv` could potentially contain uninitialized memory if the sampling loop in `rtw8822c_dac_cal_iq_sample()` terminates early (due to the `cnt \u003c 10000` condition), this behavior and the subsequent reads of the entire array were already present in the old code. The patch does not introduce any new uninitialized memory allocations, does not expose new data to user space, and does not introduce any new uninitialized memory risks. The changes are purely arithmetic and sorting refactoring. Therefore, a dedicated KMSAN fuzzing session is not required for this patch.",
  "NeedsKMSAN": false
}

Instruction:
You are an expert Linux kernel security engineer specializing in kernel memory
error detectors (KASAN and KMSAN). Your job is to review the provided patch series and
determine if the code changes justify spawning a dedicated KMSAN (KernelMemorySanitizer)
fuzzing session in addition to standard KASAN fuzzing.

CRITICAL DISTINCTION BETWEEN KASAN AND KMSAN:
- Standard KASAN kernel builds (upstream-apparmor-kasan.config) already enable
  a comprehensive suite of debugging tools and sanitizers, including KASAN
  (out-of-bounds accesses, use-after-free, double free, invalid free), LOCKDEP
  (locking bugs and deadlocks), UB-sanitizers, and memory corruption checks.
- KMSAN (KernelMemorySanitizer) detects reads of UNINITIALIZED memory (stack, heap,
  or page allocations) and kernel-to-user memory info-leaks.

Rule: THERE IS NO SENSE IN RUNNING A KMSAN SESSION IF A BUG CAN BE CAUGHT BY KASAN,
LOCKDEP, OR OTHER STANDARD BUG DETECTORS.
A dedicated KMSAN fuzzing session incurs significant resource costs. You must ONLY
set NeedsKMSAN=true if the code changes introduce or expose UNINITIALIZED MEMORY risks
that are detected ONLY by KMSAN.

Look holistically at the patch series and surrounding code. Even if no direct
uninitialized field accesses or new buffer allocations are added in the diff itself,
a patch may alter control flow, bounds checking, or data length calculations in ways
that change how the rest of the code operates on existing buffers (e.g. allowing
uninitialized stack/heap memory to be read, copied to user space, or used in control
flow). Do not hesitate to use your code access tools to inspect the surrounding code,
called functions, and callers.

Set NeedsKMSAN=true ONLY IF the patch introduces or modifies:
1. Kernel structures sent to user space (via copy_to_user, put_user, netlink skb
   attributes, ioctl output arguments, socket options, or BPF buffers) where fields
   or structure padding might not be fully initialized/zeroed.
2. Conditional logic or branching that depends on potentially uninitialized variables
   or struct fields.
3. Allocation or initialization of complex data structures where uninitialized fields
   could be read later in reachable code paths.
4. Bounds checks, lengths, or logic in a way that allows surrounding code to access
   uninitialized bytes of existing buffers.

Set NeedsKMSAN=false IF:
- The code changes primarily risk out-of-bounds access, array overflows, NULL pointer
  dereferences, locking deadlocks, or use-after-free bugs (these are already caught
  by KASAN, LOCKDEP, or standard bug detectors).
- All stack/heap structures touched or introduced by the patch are fully zeroed
  or initialized (e.g. using = {0}, memset, kzalloc) before being read or copied.
- The patch does not introduce any risk of uninitialized memory usage or info-leaks.

Use your code access tools to inspect the surrounding code if necessary, then provide
detailed KMSANReasoning contrasting KASAN vs KMSAN applicability for this patch.
Prefer calling several tools at the same time to save round-trips.


Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.

Prompt:
For your convenience, here is the diff of the changes:
commit ef4677cfbe8646efc8b67245bafbb9abb7cdc864
Author: syz-cluster <triage@syzkaller.com>
Date:   Wed Aug 12 17:24:07 2026 +0000

    syz-cluster: applied patch under review

diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
index 244c8026479c2..6fcdfc64c3b1d 100644
--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c
+++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c
@@ -3,6 +3,8 @@
  */
 
 #include <linux/module.h>
+#include <linux/bitops.h>
+#include <linux/sort.h>
 #include "main.h"
 #include "coex.h"
 #include "fw.h"
@@ -153,84 +155,30 @@ static void rtw8822c_dac_restore_reg(struct rtw_dev *rtwdev,
 	}
 }
 
-static void rtw8822c_rf_minmax_cmp(struct rtw_dev *rtwdev, u32 value,
-				   u32 *min, u32 *max)
+static int rtw8822c_dac_iq_cmp_s32(const void *a, const void *b)
 {
-	if (value >= 0x200) {
-		if (*min >= 0x200) {
-			if (*min > value)
-				*min = value;
-		} else {
-			*min = value;
-		}
-		if (*max >= 0x200) {
-			if (*max < value)
-				*max = value;
-		}
-	} else {
-		if (*min < 0x200) {
-			if (*min > value)
-				*min = value;
-		}
-
-		if (*max  >= 0x200) {
-			*max = value;
-		} else {
-			if (*max < value)
-				*max = value;
-		}
-	}
-}
+	s32 va = *(const s32 *)a;
+	s32 vb = *(const s32 *)b;
 
-static void __rtw8822c_dac_iq_sort(struct rtw_dev *rtwdev, u32 *v1, u32 *v2)
-{
-	if (*v1 >= 0x200 && *v2 >= 0x200) {
-		if (*v1 > *v2)
-			swap(*v1, *v2);
-	} else if (*v1 < 0x200 && *v2 < 0x200) {
-		if (*v1 > *v2)
-			swap(*v1, *v2);
-	} else if (*v1 < 0x200 && *v2 >= 0x200) {
-		swap(*v1, *v2);
-	}
+	return (va > vb) - (va < vb);
 }
 
-static void rtw8822c_dac_iq_sort(struct rtw_dev *rtwdev, u32 *iv, u32 *qv)
+static void rtw8822c_dac_iq_sort(struct rtw_dev *rtwdev, s32 *iv, s32 *qv)
 {
-	u32 i, j;
-
-	for (i = 0; i < DACK_SN_8822C - 1; i++) {
-		for (j = 0; j < (DACK_SN_8822C - 1 - i) ; j++) {
-			__rtw8822c_dac_iq_sort(rtwdev, &iv[j], &iv[j + 1]);
-			__rtw8822c_dac_iq_sort(rtwdev, &qv[j], &qv[j + 1]);
-		}
-	}
+	sort(iv, DACK_SN_8822C, sizeof(s32), rtw8822c_dac_iq_cmp_s32, NULL);
+	sort(qv, DACK_SN_8822C, sizeof(s32), rtw8822c_dac_iq_cmp_s32, NULL);
 }
 
-static void rtw8822c_dac_iq_offset(struct rtw_dev *rtwdev, u32 *vec, u32 *val)
+static s32 rtw8822c_dac_iq_offset(struct rtw_dev *rtwdev, s32 *vec)
 {
-	u32 p, m, t, i;
+	s32 sum = 0;
 
-	m = 0;
-	p = 0;
-	for (i = 10; i < DACK_SN_8822C - 10; i++) {
-		if (vec[i] > 0x200)
-			m = (0x400 - vec[i]) + m;
-		else
-			p = vec[i] + p;
-	}
+	for (u32 i = 10; i < DACK_SN_8822C - 10; i++)
+		sum += vec[i];
 
-	if (p > m) {
-		t = p - m;
-		t = t / (DACK_SN_8822C - 20);
-	} else {
-		t = m - p;
-		t = t / (DACK_SN_8822C - 20);
-		if (t != 0x0)
-			t = 0x400 - t;
-	}
+	s32 avg = sum / (DACK_SN_8822C - 20);
 
-	*val = t;
+	return avg >= 0 ? avg : 0x400 + avg;
 }
 
 static u32 rtw8822c_get_path_write_addr(u8 path)
@@ -271,29 +219,27 @@ static u32 rtw8822c_get_path_read_addr(u8 path)
 	return base_addr;
 }
 
-static bool rtw8822c_dac_iq_check(struct rtw_dev *rtwdev, u32 value)
+static bool rtw8822c_dac_iq_check(struct rtw_dev *rtwdev, s32 value)
 {
-	bool ret = true;
 
-	if ((value >= 0x200 && (0x400 - value) > 0x64) ||
-	    (value < 0x200 && value > 0x64)) {
-		ret = false;
+	if (value > 100 || value < -100) {
 		rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] Error overflow\n");
+		return false;
 	}
 
-	return ret;
+	return true;
 }
 
-static void rtw8822c_dac_cal_iq_sample(struct rtw_dev *rtwdev, u32 *iv, u32 *qv)
+static void rtw8822c_dac_cal_iq_sample(struct rtw_dev *rtwdev, s32 *iv, s32 *qv)
 {
 	u32 temp;
-	int i = 0, cnt = 0;
+	u32 i = 0, cnt = 0;
 
 	while (i < DACK_SN_8822C && cnt < 10000) {
 		cnt++;
 		temp = rtw_read32_mask(rtwdev, 0x2dbc, 0x3fffff);
-		iv[i] = (temp & 0x3ff000) >> 12;
-		qv[i] = temp & 0x3ff;
+		iv[i] = sign_extend32((temp & 0x3ff000) >> 12, 9);
+		qv[i] = sign_extend32(temp & 0x3ff, 9);
 
 		if (rtw8822c_dac_iq_check(rtwdev, iv[i]) &&
 		    rtw8822c_dac_iq_check(rtwdev, qv[i]))
@@ -302,13 +248,12 @@ static void rtw8822c_dac_cal_iq_sample(struct rtw_dev *rtwdev, u32 *iv, u32 *qv)
 }
 
 static void rtw8822c_dac_cal_iq_search(struct rtw_dev *rtwdev,
-				       u32 *iv, u32 *qv,
+				       s32 *iv, s32 *qv,
 				       u32 *i_value, u32 *q_value)
 {
-	u32 i_max = 0, q_max = 0, i_min = 0, q_min = 0;
-	u32 i_delta, q_delta;
+	s32 i_max = 0, q_max = 0, i_min = 0, q_min = 0;
 	u32 temp;
-	int i, cnt = 0;
+	u32 i, cnt = 0;
 
 	do {
 		i_min = iv[0];
@@ -316,23 +261,18 @@ static void rtw8822c_dac_cal_iq_search(struct rtw_dev *rtwdev,
 		q_min = qv[0];
 		q_max = qv[0];
 		for (i = 0; i < DACK_SN_8822C; i++) {
-			rtw8822c_rf_minmax_cmp(rtwdev, iv[i], &i_min, &i_max);
-			rtw8822c_rf_minmax_cmp(rtwdev, qv[i], &q_min, &q_max);
+			if (iv[i] < i_min)
+				i_min = iv[i];
+			if (iv[i] > i_max)
+				i_max = iv[i];
+			if (qv[i] < q_min)
+				q_min = qv[i];
+			if (qv[i] > q_max)
+				q_max = qv[i];
 		}
 
-		if (i_max < 0x200 && i_min < 0x200)
-			i_delta = i_max - i_min;
-		else if (i_max >= 0x200 && i_min >= 0x200)
-			i_delta = i_max - i_min;
-		else
-			i_delta = i_max + (0x400 - i_min);
-
-		if (q_max < 0x200 && q_min < 0x200)
-			q_delta = q_max - q_min;
-		else if (q_max >= 0x200 && q_min >= 0x200)
-			q_delta = q_max - q_min;
-		else
-			q_delta = q_max + (0x400 - q_min);
+		u32 i_delta = (u32)(i_max - i_min);
+		u32 q_delta = (u32)(q_max - q_min);
 
 		rtw_dbg(rtwdev, RTW_DBG_RFK,
 			"[DACK] i: min=0x%08x, max=0x%08x, delta=0x%08x\n",
@@ -345,24 +285,24 @@ static void rtw8822c_dac_cal_iq_search(struct rtw_dev *rtwdev,
 
 		if (i_delta > 5 || q_delta > 5) {
 			temp = rtw_read32_mask(rtwdev, 0x2dbc, 0x3fffff);
-			iv[0] = (temp & 0x3ff000) >> 12;
-			qv[0] = temp & 0x3ff;
+			iv[0] = sign_extend32((temp & 0x3ff000) >> 12, 9);
+			qv[0] = sign_extend32(temp & 0x3ff, 9);
 			temp = rtw_read32_mask(rtwdev, 0x2dbc, 0x3fffff);
-			iv[DACK_SN_8822C - 1] = (temp & 0x3ff000) >> 12;
-			qv[DACK_SN_8822C - 1] = temp & 0x3ff;
+			iv[DACK_SN_8822C - 1] = sign_extend32((temp & 0x3ff000) >> 12, 9);
+			qv[DACK_SN_8822C - 1] = sign_extend32(temp & 0x3ff, 9);
 		} else {
 			break;
 		}
 	} while (cnt++ < 100);
 
-	rtw8822c_dac_iq_offset(rtwdev, iv, i_value);
-	rtw8822c_dac_iq_offset(rtwdev, qv, q_value);
+	*i_value = rtw8822c_dac_iq_offset(rtwdev, iv);
+	*q_value = rtw8822c_dac_iq_offset(rtwdev, qv);
 }
 
 static void rtw8822c_dac_cal_rf_mode(struct rtw_dev *rtwdev,
 				     u32 *i_value, u32 *q_value)
 {
-	u32 iv[DACK_SN_8822C], qv[DACK_SN_8822C];
+	s32 iv[DACK_SN_8822C], qv[DACK_SN_8822C];
 	u32 rf_a, rf_b;
 
 	rf_a = rtw_read_rf(rtwdev, RF_PATH_A, 0x0, RFREG_MASK);

37/3 2026/08/12 17:26 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 5528
							output: 58
							thoughts: 329
						

Thoughts:
**Analyzing the RTW8822C DAC Calibration Patch**

Okay, so I'm looking at this patch for the RTW8822C DAC calibration. My immediate focus is on the changes to `rtw8822c_dac_cal_rf_mode` and the related functions within the `rtw8822c.c` driver. The switch from `u32` to `s32` for the `iv` and `qv` arrays is straightforward, indicating a shift towards signed integer representation, likely to accommodate both positive and negative values in the IQ data. That's a sensible change. Replacing the custom sorting logic with `sort()` from `linux/sort.h` is also good. Using the kernel's built-in sorting function is generally more efficient, reliable, and maintainable. And simplifying the offset calculation, I like that, it would make the code easier to follow.

But hold on a second... the arrays `iv` and `qv` are allocated on the *stack* inside `rtw8822c_dac_cal_rf_mode`:

```c
static void rtw8822c_dac_cal_rf_mode(struct rtw_dev *rtwdev,
				     u32 *i_value, u32 *q_value)
{
	s32 iv[DACK_SN_8822C], qv[DACK_SN_8822C];
...
```

Right, but are `iv` and `qv` fully initialized before they're read? That's my main concern. I need to make sure there's no potential for uninitialized memory being used, which could lead to random behavior and instability. Let's look at `rtw8822c_dac_cal_iq_sample`. That's where I assume they're populated. Wait, does `rtw8822c_dac_cal_rf_mode` actually call `rtw8822c_dac_cal_iq_sample`? I need to double-check the control flow and make sure the arrays are initialized before the algorithm processes them. I'll scan through the rest of `rtw8822c_dac_cal_rf_mode` to confirm. It is important to know if these stack variables are properly populated before being used.



38/3 2026/08/12 17:26 tool grepper
0m Args:
{
  "Expression": "rtw8822c_dac_cal_rf_mode",
  "PathPrefix": "drivers/net/wireless/realtek/rtw88/rtw8822c.c"
}

Results:
{
  "Output": "drivers/net/wireless/realtek/rtw88/rtw8822c.c=250=static void rtw8822c_dac_cal_iq_search(struct rtw_dev *rtwdev,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-301-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:302:static void rtw8822c_dac_cal_rf_mode(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-303-\t\t\t\t     u32 *i_value, u32 *q_value)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=334=static void rtw8822c_dac_cal_adc(struct rtw_dev *rtwdev,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-371-\t\trtw_write32(rtwdev, 0x1c24, 0x00010002);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:372:\t\trtw8822c_dac_cal_rf_mode(rtwdev, \u0026ic, \u0026qc);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-373-\t\trtw_dbg(rtwdev, RTW_DBG_RFK,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-391-\t\trtw_write32(rtwdev, 0x1c3c, path_sel + 0x8103);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:392:\t\trtw8822c_dac_cal_rf_mode(rtwdev, \u0026ic, \u0026qc);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-393-\t\trtw_dbg(rtwdev, RTW_DBG_RFK,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=457=static void rtw8822c_dac_cal_step2(struct rtw_dev *rtwdev,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-474-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:475:\trtw8822c_dac_cal_rf_mode(rtwdev, \u0026ic_in, \u0026qc_in);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-476-\tic = ic_in;\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=506=static void rtw8822c_dac_cal_step3(struct rtw_dev *rtwdev, u8 path,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-556-\trtw_write32(rtwdev, base_addr + 0x60, 0xf0000000);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:557:\trtw8822c_dac_cal_rf_mode(rtwdev, \u0026ic, \u0026qc);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-558-\tif (ic \u003e= 0x10)\n"
}

39/3 2026/08/12 17:26 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 7435
							output: 51
							thoughts: 34
						

Thoughts:
Okay, let's dive into this. Here's my thought process on the matter:

**Analyzing the `rtw8822c_dac_cal_rf_mode` Function**

I need to understand how the `iv` and `qv` variables are populated within this context. My instinct is to examine the `rtw8822c_dac_cal_rf_mode` function directly. It's the logical place to start – it's named in a way that suggests it's involved in calibration and likely deals with RF mode settings, which almost certainly means it touches upon these in-phase (I) and quadrature-phase (Q) components, `iv` and `qv`. Let's get to the code.



40/3 2026/08/12 17:26 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/realtek/rtw88/rtw8822c.c",
  "FirstLine": 302,
  "LineCount": 50
}

Results:
{
  "Contents": " 302:\tstatic void rtw8822c_dac_cal_rf_mode(struct rtw_dev *rtwdev,\n 303:\t\t\t\t\t     u32 *i_value, u32 *q_value)\n 304:\t{\n 305:\t\ts32 iv[DACK_SN_8822C], qv[DACK_SN_8822C];\n 306:\t\tu32 rf_a, rf_b;\n 307:\t\n 308:\t\trf_a = rtw_read_rf(rtwdev, RF_PATH_A, 0x0, RFREG_MASK);\n 309:\t\trf_b = rtw_read_rf(rtwdev, RF_PATH_B, 0x0, RFREG_MASK);\n 310:\t\n 311:\t\trtw_dbg(rtwdev, RTW_DBG_RFK, \"[DACK] RF path-A=0x%05x\\n\", rf_a);\n 312:\t\trtw_dbg(rtwdev, RTW_DBG_RFK, \"[DACK] RF path-B=0x%05x\\n\", rf_b);\n 313:\t\n 314:\t\trtw8822c_dac_cal_iq_sample(rtwdev, iv, qv);\n 315:\t\trtw8822c_dac_cal_iq_search(rtwdev, iv, qv, i_value, q_value);\n 316:\t}\n 317:\t\n 318:\tstatic void rtw8822c_dac_bb_setting(struct rtw_dev *rtwdev)\n 319:\t{\n 320:\t\trtw_write32_mask(rtwdev, 0x1d58, 0xff8, 0x1ff);\n 321:\t\trtw_write32_mask(rtwdev, 0x1a00, 0x3, 0x2);\n 322:\t\trtw_write32_mask(rtwdev, 0x1a14, 0x300, 0x3);\n 323:\t\trtw_write32(rtwdev, 0x1d70, 0x7e7e7e7e);\n 324:\t\trtw_write32_mask(rtwdev, 0x180c, 0x3, 0x0);\n 325:\t\trtw_write32_mask(rtwdev, 0x410c, 0x3, 0x0);\n 326:\t\trtw_write32(rtwdev, 0x1b00, 0x00000008);\n 327:\t\trtw_write8(rtwdev, 0x1bcc, 0x3f);\n 328:\t\trtw_write32(rtwdev, 0x1b00, 0x0000000a);\n 329:\t\trtw_write8(rtwdev, 0x1bcc, 0x3f);\n 330:\t\trtw_write32_mask(rtwdev, 0x1e24, BIT(31), 0x0);\n 331:\t\trtw_write32_mask(rtwdev, 0x1e28, 0xf, 0x3);\n 332:\t}\n 333:\t\n 334:\tstatic void rtw8822c_dac_cal_adc(struct rtw_dev *rtwdev,\n 335:\t\t\t\t\t u8 path, u32 *adc_ic, u32 *adc_qc)\n 336:\t{\n 337:\t\tstruct rtw_dm_info *dm_info = \u0026rtwdev-\u003edm_info;\n 338:\t\tu32 ic = 0, qc = 0, temp = 0;\n 339:\t\tu32 base_addr;\n 340:\t\tu32 path_sel;\n 341:\t\tint i;\n 342:\t\n 343:\t\trtw_dbg(rtwdev, RTW_DBG_RFK, \"[DACK] ADCK path(%d)\\n\", path);\n 344:\t\n 345:\t\tbase_addr = rtw8822c_get_path_write_addr(path);\n 346:\t\tswitch (path) {\n 347:\t\tcase RF_PATH_A:\n 348:\t\t\tpath_sel = 0xa0000;\n 349:\t\t\tbreak;\n 350:\t\tcase RF_PATH_B:\n 351:\t\t\tpath_sel = 0x80000;\n"
}

41/3 2026/08/12 17:26 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 8915
							output: 51
							thoughts: 52
						

Thoughts:
Here's my summary, as if I were thinking it:

**Digging into the Calibration Routine**

Okay, so I see that `rtw8822c_dac_cal_iq_sample` is the function responsible for actually getting those `iv` and `qv` values populated. That's the core of this calibration step. I need to revisit that function. I need to refresh my understanding of *how* exactly this function is acquiring the in-phase (I) and quadrature-phase (Q) samples. What's the signal path? Is it using direct conversion, superheterodyne, or something else? I also want to verify whether I understand how it interfaces with the DAC and ADC within the RFIC architecture. Need to make sure I understand how it interacts with the hardware, the ADC's sampling rate, resolution, and any potential offsets, to properly interpret the values.



42/3 2026/08/12 17:26 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/realtek/rtw88/rtw8822c.c",
  "FirstLine": 232,
  "LineCount": 20
}

Results:
{
  "Contents": " 232:\t\n 233:\tstatic void rtw8822c_dac_cal_iq_sample(struct rtw_dev *rtwdev, s32 *iv, s32 *qv)\n 234:\t{\n 235:\t\tu32 temp;\n 236:\t\tu32 i = 0, cnt = 0;\n 237:\t\n 238:\t\twhile (i \u003c DACK_SN_8822C \u0026\u0026 cnt \u003c 10000) {\n 239:\t\t\tcnt++;\n 240:\t\t\ttemp = rtw_read32_mask(rtwdev, 0x2dbc, 0x3fffff);\n 241:\t\t\tiv[i] = sign_extend32((temp \u0026 0x3ff000) \u003e\u003e 12, 9);\n 242:\t\t\tqv[i] = sign_extend32(temp \u0026 0x3ff, 9);\n 243:\t\n 244:\t\t\tif (rtw8822c_dac_iq_check(rtwdev, iv[i]) \u0026\u0026\n 245:\t\t\t    rtw8822c_dac_iq_check(rtwdev, qv[i]))\n 246:\t\t\t\ti++;\n 247:\t\t}\n 248:\t}\n 249:\t\n 250:\tstatic void rtw8822c_dac_cal_iq_search(struct rtw_dev *rtwdev,\n 251:\t\t\t\t\t       s32 *iv, s32 *qv,\n"
}

43/3 2026/08/12 17:26 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 9620
							output: 58
							thoughts: 728
						

Thoughts:
**Uninitialized Memory Access in DAC Calibration**

Okay, so I'm looking at this `rtw8822c_dac_cal_iq_sample` function and immediately, my attention is drawn to this loop. It's reading IQ samples, and there's a safety check: a `cnt` limit of 10000. That's fine, but the implication is... if `cnt` hits 10000 *before* we've collected the expected number of samples (`DACK_SN_8822C`), the loop breaks. That means the remaining elements of `iv` and `qv` are *uninitialized*!  This is a big red flag.

Then I see that `rtw8822c_dac_cal_iq_search` is called with these potentially incomplete `iv` and `qv` arrays. And here's where it gets dangerous. Inside `rtw8822c_dac_cal_iq_search`, the code iterates *up to* `DACK_SN_8822C` to find min/max values for I and Q. That means it's reading memory *beyond* the initialized part of `iv` and `qv` if the loop in `rtw8822c_dac_cal_iq_sample` terminated prematurely. We're potentially reading garbage from the stack, and this could lead to all sorts of unpredictable behavior.

This is classic uninitialized memory access. I need to figure out if this was introduced in a recent patch, or if it has been lurking here all along. Time to check the old code for `rtw8822c_dac_cal_iq_sample`. I need to figure out if the problem was present *before* the patch.



44/3 2026/08/12 17:26 tool grepper
0m Args:
{
  "Expression": "rtw8822c_dac_cal_iq_sample",
  "PathPrefix": "drivers/net/wireless/realtek/rtw88/rtw8822c.c"
}

Results:
{
  "Output": "drivers/net/wireless/realtek/rtw88/rtw8822c.c=222=static bool rtw8822c_dac_iq_check(struct rtw_dev *rtwdev, s32 value)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-232-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:233:static void rtw8822c_dac_cal_iq_sample(struct rtw_dev *rtwdev, s32 *iv, s32 *qv)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-234-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=302=static void rtw8822c_dac_cal_rf_mode(struct rtw_dev *rtwdev,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-313-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:314:\trtw8822c_dac_cal_iq_sample(rtwdev, iv, qv);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-315-\trtw8822c_dac_cal_iq_search(rtwdev, iv, qv, i_value, q_value);\n"
}

45/3 2026/08/12 17:26 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 11201
							output: 56
							thoughts: 875
						

Thoughts:
**Analyzing the DAC Calibration Code**

Okay, so I'm looking at this diff for the DAC calibration in this `rtw8822c` driver, and my initial thought is that the change from unsigned `u32` to signed `s32` for `iv` and `qv` within `rtw8822c_dac_cal_iq_sample` is important. That's a definite functional change. I see the read mask is used to get the data from the hardware. The code is extracting a 10 bit signed value, which is appropriate for signed integers.

However, I'm more concerned about the implications of the sampling loop. The condition `cnt < 10000` caught my eye because that's an existing loop break condition. It means an early return from the sampling loop is possible. It also means the arrays `iv` and `qv` could have uninitialized elements. If `cnt` hits 10000, then some elements in `iv` and `qv` will not be filled.

Then, there's the change to `rtw8822c_dac_iq_sort`, where the custom sorting implementation has been replaced with the standard `sort()` function. That's where things get interesting. I know `sort()` is an efficient sorting algorithm, but if those `iv` and `qv` arrays *aren't* fully initialized, this is a problem. The old custom sort, and the new sort, both depend on *reading* data from `iv` and `qv`. The new code calls `sort()` which means that `rtw8822c_dac_iq_cmp_s32` is going to read uninitialized memory from the `iv` and `qv` buffers. This is a potential bug. I can't be sure that the old code was better: it also reads uninitialized memory, but it's not clear that the old code has a well-defined comparison function: `__rtw8822c_dac_iq_sort` might have different properties.

So, the critical question becomes: is `rtw8822c_dac_iq_sort` actually *called*? If this sorting function is never invoked, then this becomes a non-issue. I need to trace the call paths to determine the actual impact of this change.



46/3 2026/08/12 17:26 tool grepper
0m Args:
{
  "Expression": "rtw8822c_dac_iq_sort",
  "PathPrefix": "drivers/net/wireless/realtek/rtw88/rtw8822c.c"
}

Results:
{
  "Output": "drivers/net/wireless/realtek/rtw88/rtw8822c.c=158=static int rtw8822c_dac_iq_cmp_s32(const void *a, const void *b)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-165-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:166:static void rtw8822c_dac_iq_sort(struct rtw_dev *rtwdev, s32 *iv, s32 *qv)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-167-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=250=static void rtw8822c_dac_cal_iq_search(struct rtw_dev *rtwdev,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-283-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:284:\t\trtw8822c_dac_iq_sort(rtwdev, iv, qv);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-285-\n"
}

47/3 2026/08/12 17:26 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 13011
							output: 46
							thoughts: 982
						

Thoughts:
**Analyzing DAC Calibration Code Changes**

Okay, so `rtw8822c_dac_cal_iq_search` calls `rtw8822c_dac_iq_sort`, which it always did. Good, no new function calls introduced there. My initial concern was whether the patch introduced any new uninitialized memory usage, so let's dig into the changes in `rtw8822c_dac_cal_iq_search` itself.

Alright, the first diff simplifies the calculation of the deltas for I and Q. The old code had some conditional logic to handle cases where the max and min values wrapped around 0x200 (presumably representing a signed value with 0x200 as the midpoint). The new code just performs a straightforward unsigned subtraction: `u32 i_delta = (u32)(i_max - i_min);` and the same for Q. No obvious problems there. This will be an improvement in efficiency, and likely accuracy since the logic doesn't depend on the compiler's optimizations.

Then, there's a change in how `rtw8822c_dac_iq_offset` is called. The original code was like this:
```c
rtw8822c_dac_iq_offset(rtwdev, iv, i_value);
rtw8822c_dac_iq_offset(rtwdev, qv, q_value);
```
and now it's this:
```c
*i_value = rtw8822c_dac_iq_offset(rtwdev, iv);
*q_value = rtw8822c_dac_iq_offset(rtwdev, qv);
```
Essentially, `rtw8822c_dac_iq_offset` now returns a value. But that means we should see a corresponding change in the implementation of that function, which we do. The original code's signature was:
```c
static void rtw8822c_dac_iq_offset(struct rtw_dev *rtwdev, u32 *vec, u32 *val)
```
and is now:
```c
static s32 rtw8822c_dac_iq_offset(struct rtw_dev *rtwdev, s32 *vec)
```

The old function had a local variable `t` that calculated the average offset of the data. The revised code directly calculates the average of the vector's values in a `sum` variable, and then directly calculates `avg = sum / (DACK_SN_8822C - 20)`. The return value from this function is calculated and returned, now using a ternary operator. The `vec` pointer passed to the function is now a `s32 *` instead of `u32 *`, which is good. The function now correctly returns a signed offset value, whereas before, the offset value was an out parameter.

The loop iterating through `vec` now also uses a `u32 i` as its iterator. The code is much cleaner.

I don't see any obvious uninitialized memory usage problems, but I need to make sure I understand what `DACK_SN_8822C` represents and how this affects the overall calibration process. It's likely a sample count, but I should look into that constant's definition to confirm. I should also test this code against some example datasets to determine if the signed arithmetic introduces any unexpected behavior.



48/3 2026/08/12 17:26 tool grepper
0m Args:
{
  "Expression": "#define DACK_SN_8822C",
  "PathPrefix": "drivers/net/wireless/realtek/rtw88/"
}

Results:
{
  "Output": "drivers/net/wireless/realtek/rtw88/rtw8822c.h=133=const struct rtw_table name ## _tbl = {\t\t\t\\\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.h-141-#define DACK_RF_8822C\t\t1\ndrivers/net/wireless/realtek/rtw88/rtw8822c.h:142:#define DACK_SN_8822C\t\t100\ndrivers/net/wireless/realtek/rtw88/rtw8822c.h-143-\n"
}

49/3 2026/08/12 17:26 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 14986
							output: 231
							thoughts: 3614
						

Thoughts:
**Analysis of the DAC Calibration Code Refactoring**

Okay, so I've been reviewing this patch, and here's my breakdown of what's happening. The core of this patch seems to be a refactoring of the DAC calibration logic within the `rtw8822c` driver.  The critical aspect here is whether this refactoring introduces any *new* uninitialized memory risks that would be exposed by KMSAN.  Let's walk through it.

First, `DACK_SN_8822C` defines the size – it's 100.  We have arrays `iv` and `qv`, both of 100 `s32` elements, used to store samples read from hardware.  The function `rtw8822c_dac_cal_iq_sample` attempts to populate these arrays. The key here is the loop that reads the values and stores them.  Crucially, there's a `cnt` counter to prevent an infinite loop, and if it reaches 10000, `i` could be less than 100, leaving the arrays partially uninitialized. This *was* already the case in the old code.

The original code also had a similar situation, where uninitialized values *could* be read. The patch *replaces* calls to `rtw8822c_rf_minmax_cmp`, and a custom sort with the standard library's `sort()` function and signed integers, specifically `s32`. This `sort()` function uses `rtw8822c_dac_iq_cmp_s32`, which is a standard comparison function.

The previous code had some tricky sign extension logic. The new code does it correctly by calling `sign_extend32` which sign-extends the 10-bit values to 32 bit signed values using bit 9 as the sign bit.

My initial concern was whether the refactoring *exposed* an existing uninitialized read that was not detected before by KMSAN. If the arrays `iv` and `qv` are only partially initialized, using `sort()` *will* read the uninitialized memory, KMSAN should catch this. But this was already true in the old code.

The check for `rtw8822c_dac_iq_check` has been modified, but not in a way that affects whether the arrays are initialized or not. It's essentially the same logic using signed types. The limits are -100 to 100.

The offset calculations are also being refactored, but they still rely on the same potentially uninitialized data.

The arrays within `rtw8822c_dac_cal_rf_mode` are still uninitialized, depending on whether the sample function fails.

The main change is from a custom comparison and sort to standard signed types, standard `sort()`, and a simplified offset calculation. All of this can still read the same memory if it is not properly initialized.

Therefore, since all the potential for reading uninitialized memory was present *before* the patch, and the patch is primarily a refactoring of existing logic and math and does *not* introduce new allocation or copy to user space, KMSAN is not specifically needed here.  Any uninitialized memory issues, like the early loop termination and the arrays being only partially filled, *would* be caught by KMSAN in both the old and new code.  This is a straight refactoring, the uninitialized memory issue, if it exists, is still there. I will set `NeedsKMSAN=false` because it does not introduce new KMSAN-specific problems.



50/3 2026/08/12 17:27 tool set-results
0m Args:
{
  "KMSANReasoning": "The patch refactors the IQ calibration logic in the rtw88 driver by replacing custom 10-bit sign-magnitude/two's-complement arithmetic and a custom bubble sort with standard `s32` types, `sign_extend32()`, and the kernel's built-in `sort()` function. \n\nWhile the stack-allocated arrays `iv` and `qv` could potentially contain uninitialized memory if the sampling loop in `rtw8822c_dac_cal_iq_sample()` terminates early (due to the `cnt \u003c 10000` condition), this behavior and the subsequent reads of the entire array were already present in the old code. The patch does not introduce any new uninitialized memory allocations, does not expose new data to user space, and does not introduce any new uninitialized memory risks. The changes are purely arithmetic and sorting refactoring. Therefore, a dedicated KMSAN fuzzing session is not required for this patch.",
  "NeedsKMSAN": false
}

Results:
{
  "KMSANReasoning": "The patch refactors the IQ calibration logic in the rtw88 driver by replacing custom 10-bit sign-magnitude/two's-complement arithmetic and a custom bubble sort with standard `s32` types, `sign_extend32()`, and the kernel's built-in `sort()` function. \n\nWhile the stack-allocated arrays `iv` and `qv` could potentially contain uninitialized memory if the sampling loop in `rtw8822c_dac_cal_iq_sample()` terminates early (due to the `cnt \u003c 10000` condition), this behavior and the subsequent reads of the entire array were already present in the old code. The patch does not introduce any new uninitialized memory allocations, does not expose new data to user space, and does not introduce any new uninitialized memory risks. The changes are purely arithmetic and sorting refactoring. Therefore, a dedicated KMSAN fuzzing session is not required for this patch.",
  "NeedsKMSAN": false
}

LLM Calls Summary:
Total Calls Total Tokens Avg Tokens Total Duration (Seconds) Avg Duration (Seconds)
Tool Calls Summary:
Total Calls Total Duration (Seconds) Avg Duration (Seconds)