AI Trajectory


Trajectory: (Expand/Collapse All)
Seq Timestamp Type Name Duration
0/0 2026/08/13 07:48 flow patch-triage
2m Args:
null

Results:
{
  "EnableConfigs": [
    "WLAN",
    "WLAN_VENDOR_REALTEK",
    "MAC80211",
    "USB",
    "RTW88",
    "RTW88_8822CU"
  ],
  "FocusSymbols": [
    "rtw_usb_probe",
    "rtw_core_start",
    "rtw_power_on"
  ],
  "KMSANReasoning": "The patch refactors the DAC IQ calibration logic in the rtw88 wireless driver, changing the data types of the `iv` and `qv` arrays from `u32` to `s32` and replacing custom sorting and min/max functions with standard kernel functions (`sort()`, `sign_extend32()`). The arrays `iv` and `qv` are allocated on the stack and populated by reading hardware registers in a loop. While there is a pre-existing theoretical risk that these arrays might not be fully initialized if the hardware fails to provide enough valid samples within a timeout, this patch does not introduce or exacerbate this risk. It merely changes the arithmetic operations performed on the data. Furthermore, these arrays are used strictly internally for hardware calibration and do not leak to userspace. Since no new uninitialized memory risks or info-leaks are introduced, a dedicated KMSAN fuzzing session is not justified. Standard KASAN and other bug detectors are sufficient to catch any out-of-bounds or memory corruption issues.",
  "NeedsKMSAN": false,
  "Reasoning": "The patch modifies the DAC IQ calibration logic in the Realtek rtw8822c wireless driver. This code is reachable in virtualized environments via USB emulation using the rtw8822cu driver variant. The changes are functional (replacing custom sorting/min-max logic with standard library functions and changing types), so they are worth fuzzing. The entry points for this code path include the USB probe function and the mac80211 start/power-on callbacks.",
  "WorthFuzzing": true
}

1/1 2026/08/13 07:48 action read-patch-diff
0m Args:
null

Results:
{
  "PatchDiff": "commit c0cd274bc35551f8f4b4a082e8c1187bc263c70e\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate:   Thu Aug 13 07:48:29 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/13 07:48 agent patch-evaluator
1m Model:
best-expensive

Args:
null

Results:
{
  "EnableConfigs": [
    "WLAN",
    "WLAN_VENDOR_REALTEK",
    "MAC80211",
    "USB",
    "RTW88",
    "RTW88_8822CU"
  ],
  "FocusSymbols": [
    "rtw_usb_probe",
    "rtw_core_start",
    "rtw_power_on"
  ],
  "Reasoning": "The patch modifies the DAC IQ calibration logic in the Realtek rtw8822c wireless driver. This code is reachable in virtualized environments via USB emulation using the rtw8822cu driver variant. The changes are functional (replacing custom sorting/min-max logic with standard library functions and changing types), so they are worth fuzzing. The entry points for this code path include the USB probe function and the mac80211 start/power-on callbacks.",
  "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 c0cd274bc35551f8f4b4a082e8c1187bc263c70e
Author: syz-cluster <triage@syzkaller.com>
Date:   Thu Aug 13 07:48:29 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/13 07:48 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 5538
							output: 41
							thoughts: 274
						

Thoughts:
**Analyzing a Realtek Wireless Driver Patch**

Okay, so I'm looking at a patch that tweaks the DAC IQ calibration routine in the `rtw8822c.c` Realtek wireless driver. Specifically, it's swapping out custom sorting and min/max implementations for the standard `sort()` function and the `sign_extend32()` macro.  The patch also adjusts the data types of the `iv` and `qv` arrays, changing them from `u32` to `s32`.  My immediate concern is, can I actually test this in my setup?  Is this code path even accessible in a virtualized environment?

Let's see… the driver in question is `rtw88`, and specifically targets the `rtw8822c.c` file, so the target is a Realtek 802.11ac chipset connected via PCIe, USB, or SDIO.  Right, so can I get this to trigger in a virtual machine? Forget `mac80211_hwsim` – that's just a software simulator; it won't exercise the hardware.  Hmm… USB emulation might be a possibility, though.  I should check if there's a corresponding USB driver for this specific Realtek chip.

Let's see, does `rtw8822cu.c` even exist? Yes it does.  I'll just grep the kernel source for "rtw8822c" to confirm all the different connection types.



4/2 2026/08/13 07:48 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/13 07:48 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 23509
							output: 41
							thoughts: 79
						

Thoughts:
**Analyzing the `rtw8822c` Driver**

Okay, so I'm looking at this `rtw8822c` driver, and immediately my expert brain kicks in. I know that it has both USB and SDIO implementations, namely `rtw8822cu` and `rtw8822cs`. That's a key distinction. Now, the interesting part is the potential for testing. USB drivers, like this `rtw8822cu` variant, are reachable via things like `dummy_hcd` or other USB emulation techniques, right? That's the go-to approach in environments like syzkaller. So, my next step is clear: I need to explicitly confirm that `rtw8822cu` is, in fact, the USB driver. Then I can start mapping out a more in-depth testing strategy.



6/2 2026/08/13 07:48 tool grepper
0m Args:
{
  "Expression": "rtw8822cu",
  "PathPrefix": "drivers/net/wireless/realtek/rtw88/"
}

Results:
{
  "Output": "drivers/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=28=static void rtw8822ce_efuse_parsing(struct rtw_efuse *efuse,\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)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=46=static int rtw8822c_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)\n--\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;\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.h-9-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.h:10:struct rtw8822cu_efuse {\ndrivers/net/wireless/realtek/rtw88/rtw8822c.h-11-\tu8 res0[0x30];\t\t\t/* 0x120 */\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.h=61=struct rtw8822c_efuse {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.h-102-\t\tstruct rtw8822ce_efuse e;\ndrivers/net/wireless/realtek/rtw88/rtw8822c.h:103:\t\tstruct rtw8822cu_efuse u;\ndrivers/net/wireless/realtek/rtw88/rtw8822c.h-104-\t\tstruct rtw8822cs_efuse s;\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822cu.c=28=MODULE_DEVICE_TABLE(usb, rtw_8822cu_id_table);\ndrivers/net/wireless/realtek/rtw88/rtw8822cu.c-29-\ndrivers/net/wireless/realtek/rtw88/rtw8822cu.c:30:static int rtw8822cu_probe(struct usb_interface *intf,\ndrivers/net/wireless/realtek/rtw88/rtw8822cu.c-31-\t\t\t   const struct usb_device_id *id)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822cu.c=36=static struct usb_driver rtw_8822cu_driver = {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822cu.c-38-\t.id_table = rtw_8822cu_id_table,\ndrivers/net/wireless/realtek/rtw88/rtw8822cu.c:39:\t.probe = rtw8822cu_probe,\ndrivers/net/wireless/realtek/rtw88/rtw8822cu.c-40-\t.disconnect = rtw_usb_disconnect,\n"
}

7/2 2026/08/13 07:48 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 24942
							output: 47
							thoughts: 226
						

Thoughts:
**Analyzing the USB Driver Impact**

Okay, so `rtw8822cu` is definitely a USB driver, and that's key. It means I need to approach this understanding the potential for USB emulation to play a role in how this code is reached.

The patch I'm looking at modifies several functions within `rtw8822c.c` – specifically, I see changes in `rtw8822c_dac_cal_iq_sample`, `rtw8822c_dac_cal_iq_search`, `rtw8822c_dac_iq_sort`, `rtw8822c_dac_iq_offset`, and `rtw8822c_dac_iq_check`. These are the functions being directly impacted.

Now, how are these functions organized? I see that all of these modified functions are called from `rtw8822c_dac_cal_rf_mode`. `rtw8822c_dac_cal_rf_mode` itself is then called from both `rtw8822c_dac_cal_step2` and `rtw8822c_dac_cal_step3`. This suggests a hierarchical structure, likely related to some kind of calibration process, perhaps specific to RF performance or Digital-to-Analog converter (DAC) calibration. Finally, both of those functions are called from `rtw8822c_rf_dac_cal`.

My next step is to trace the call paths to figure out *where* `rtw8822c_rf_dac_cal` is invoked, and how those calls might connect to the USB interface. That’s the critical piece for understanding the actual impact and implications of this patch.



8/2 2026/08/13 07:48 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"
}

9/2 2026/08/13 07:48 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 25968
							output: 45
							thoughts: 52
						

Thoughts:
Here's my summary, as though I'm thinking through this process:

**Diving into the RF Initialization**

Okay, so `rtw8822c_rf_init` is the function we're looking at, and I see it calls `rtw8822c_rf_dac_cal`. That's interesting, usually RF initialization routines have some calibration steps in them. My immediate thought is, let's trace this back. Where is `rtw8822c_rf_init` *actually* being called from? Understanding the call stack is crucial here. Knowing the calling context gives me a solid starting point to understanding why these functions are called, and the assumptions that this process likely makes about the hardware. Let's see if we can find out who's calling the shot.



10/2 2026/08/13 07:48 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"
}

11/2 2026/08/13 07:48 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 26610
							output: 47
							thoughts: 54
						

Thoughts:
**Analyzing the 8822C PHY Parameter Setting**

Okay, so `rtw8822c_phy_set_param` is the function we're interested in. It's calling `rtw8822c_rf_init`, which gives us a good starting point. But I need to understand the larger context. My next step is clear: I need to trace back and determine *where* `rtw8822c_phy_set_param` is being invoked. Understanding its call graph will reveal what's driving the need to set these PHY parameters in the first place. That's how I can begin to grasp the system's intended behavior and identify potential bottlenecks or areas for optimization.



12/2 2026/08/13 07:48 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"
}

13/2 2026/08/13 07:48 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 27256
							output: 45
							thoughts: 254
						

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

Okay, so this patch is clearly touching the DAC IQ calibration process, specifically within the `rtw8822c_ops` structure, which I recognize as part of `struct rtw_chip_ops`. The key here is the `phy_set_param` callback – that’s triggered during driver initialization, meaning this code is *definitely* going to be hit if we're emulating USB. Excellent.

Now, the functional change is focused on the DAC IQ calibration logic itself. I see a suite of modified functions: `rtw8822c_dac_iq_cmp_s32` (this one looks new), `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`. This is a pretty significant update to the calibration sequence.

Alright, let's nail down those config options. I need to be sure this affects the USB driver, and `CONFIG_RTW88_8822CU` is the obvious candidate. Time to double-check `drivers/net/wireless/realtek/rtw88/Kconfig` to confirm.



14/2 2026/08/13 07:48 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"
}

15/2 2026/08/13 07:48 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 28022
							output: 44
							thoughts: 29
						

Thoughts:
Here's my summary, as though I'm reading and processing the `drivers/net/wireless/realtek/rtw88/Kconfig` file:

**Diving into the Realtek Wireless Configuration**

Okay, let's get down to brass tacks. I need to understand how this Realtek wireless driver is configured within the kernel build system. I'm going to jump into the `Kconfig` file, specifically around line 115. My initial goal is to understand the dependencies and options related to the core functionality of this module. This is where the core configuration decisions are made, and that’s what I'm focused on right now. I'll be looking for relevant `config` options, relationships between the options, any dependencies on other kernel subsystems. I'll be looking for things like conditional compilation based on hardware or other configurations and I'll see how these are tied to module parameters. This will tell me what I have control over when integrating with this hardware.



16/2 2026/08/13 07:49 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"
}

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

Args:
null

Results:
null

Tokens:
							input: 28764
							output: 42
							thoughts: 37
						

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

**Checking the Dependencies: RTW88, USB, and 8822CU**

Right, so I'm thinking about integrating a wireless solution. Based on the components mentioned, I'm pretty sure we're looking at something based on a Realtek chipset. The mention of `RTW88_8822CU` is a key indicator; that's the specific driver name for a common Realtek 802.11ac WiFi chip, likely a USB dongle or a module integrated via USB.

My immediate next thought is to investigate `RTW88`. This is the broader Realtek WiFi driver framework, so it makes sense to start there. I'll need to check the dependencies and compatibility within the driver itself. Is it using a mainline version, a specific fork, or a Realtek-provided version? I need to understand how the `RTW88` framework handles USB interfaces generally, and specifically this `8822CU` chip. I'll need to confirm what other USB specific elements will be required, like USB firmware loading, and ensure everything is set up to work together properly.

The inclusion of `USB` as a separate mention implies this is a USB-based solution. The architecture should be pretty straightforward, but I have to make sure there are no conflicts or unexpected behaviour.



18/2 2026/08/13 07:49 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/realtek/rtw88/Kconfig",
  "FirstLine": 1,
  "LineCount": 30
}

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  21:\t\ttristate\n  22:\t\n  23:\tconfig RTW88_USB\n  24:\t\ttristate\n  25:\t\n  26:\tconfig RTW88_8822B\n  27:\t\ttristate\n  28:\t\n  29:\tconfig RTW88_8822C\n  30:\t\ttristate\n"
}

19/2 2026/08/13 07:49 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 29513
							output: 56
							thoughts: 410
						

Thoughts:
**Analyzing the RTW88 Wireless Driver Calibration Routine**

Okay, so I'm diving into this `RTW88` driver, specifically the `8822CU` version, dealing with the `MAC80211` and `USB` layers. My initial thought is to zero in on these functions: `rtw8822c_dac_cal_iq_sample`, `rtw8822c_dac_cal_iq_search`, `rtw8822c_dac_cal_rf_mode`, `rtw8822c_dac_iq_sort`, `rtw8822c_dac_iq_offset`, `rtw8822c_dac_iq_check`, and `rtw8822c_dac_iq_cmp_s32`.

Aha, I see that `rtw8822c_dac_iq_cmp_s32` is a comparison function passed to `sort()`, so it's a callback – good to note. Looking for an entry point, `rtw8822c_dac_cal_rf_mode` seems like a likely candidate. Also, `rtw8822c_dac_cal_iq_sample` and `rtw8822c_dac_cal_iq_search` are worth a look.

Now, let me just quickly confirm if `rtw8822c_dac_cal_rf_mode` is static. Yep, it is. Wait a second, the guidance is to favor non-static functions as entry points. Makes sense, they're generally more accessible. It suggests that static functions might be inlined, losing distinct symbols, so they aren't ideal as an entry point. So I'll need to check if there are non-static functions available.

Let's see: `rtw8822c_phy_set_param` is also static, and `rtw8822c_ops` is a static const struct. Time to dig through `rtw8822c.c` to see if there are any non-static functions available in this file. I need to keep in mind, I am trying to identify a good, readily available entry point into this subsystem.



20/2 2026/08/13 07:49 tool grepper
0m Args:
{
  "Expression": "^[^s].* rtw8822c_",
  "PathPrefix": "drivers/net/wireless/realtek/rtw88/rtw8822c.c"
}

Results:
{
  "Output": "drivers/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=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=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=46=static int rtw8822c_read_efuse(struct rtw_dev *rtwdev, u8 *log_map)\n--\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=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-}\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=233=static void rtw8822c_dac_cal_iq_sample(struct rtw_dev *rtwdev, s32 *iv, s32 *qv)\n--\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=250=static void rtw8822c_dac_cal_iq_search(struct rtw_dev *rtwdev,\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-}\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-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=412=static void rtw8822c_dac_cal_step1(struct rtw_dev *rtwdev, u8 path)\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=457=static void rtw8822c_dac_cal_step2(struct rtw_dev *rtwdev,\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=506=static void rtw8822c_dac_cal_step3(struct rtw_dev *rtwdev, u8 path,\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=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=610=static void rtw8822c_dac_cal_backup_path(struct rtw_dev *rtwdev, u8 path)\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);\n--\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);\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=784=static bool rtw8822c_dac_cal_restore_path(struct rtw_dev *rtwdev, u8 path)\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-\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=1594=static void rtw8822c_txgapk_write_tx_gain(struct rtw_dev *rtwdev)\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=3093=struct dpk_cfg_pair {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3098-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:3099:void rtw8822c_parse_tbl_dpk(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3100-\t\t\t    const struct rtw_table *tbl)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=3337=static u8 rtw8822c_dpk_one_shot(struct rtw_dev *rtwdev, u8 path, u8 action)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3357-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:3358:\t\tdpk_cmd = rtw8822c_dpk_get_cmd(rtwdev, action, path);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3359-\t\trtw_write32(rtwdev, REG_NCTL0, dpk_cmd);\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=3464=static u8 rtw8822c_dpk_agc_gain_chk(struct rtw_dev *rtwdev, u8 path,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3470-\trtw8822c_dpk_one_shot(rtwdev, path, RTW_DPK_DAGC);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:3471:\tdgain = rtw8822c_dpk_dgain_read(rtwdev, path);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3472-\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=3481=static u8 rtw8822c_dpk_agc_loss_chk(struct rtw_dev *rtwdev, u8 path)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3484-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:3485:\tloss = rtw8822c_dpk_pas_read(rtwdev, path);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3486-\tif (loss \u003c 0x4000000)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3487-\t\treturn RTW_DPK_GL_LESS;\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:3488:\tloss_db = 3 * rtw8822c_psd_log2base(loss \u003e\u003e 13) - 3870;\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3489-\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=3508=static u8 rtw8822c_gain_check_state(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:3509:\t\t\t\t    struct rtw8822c_dpk_data *data)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3510-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3522-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:3523:\tstate = rtw8822c_dpk_agc_gain_chk(rtwdev, data-\u003epath,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3524-\t\t\t\t\t  data-\u003elimited_pga);\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=3538=static u8 rtw8822c_gain_large_state(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:3539:\t\t\t\t    struct rtw8822c_dpk_data *data)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3540-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=3553=static u8 rtw8822c_gain_less_state(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:3554:\t\t\t\t   struct rtw8822c_dpk_data *data)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3555-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=3568=static u8 rtw8822c_gl_state(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:3569:\t\t\t    struct rtw8822c_dpk_data *data, u8 is_large)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3570-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=3587=static u8 rtw8822c_gl_large_state(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:3588:\t\t\t\t  struct rtw8822c_dpk_data *data)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3589-{\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:3590:\treturn rtw8822c_gl_state(rtwdev, data, 1);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3591-}\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=3593=static u8 rtw8822c_gl_less_state(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:3594:\t\t\t\t struct rtw8822c_dpk_data *data)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3595-{\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:3596:\treturn rtw8822c_gl_state(rtwdev, data, 0);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3597-}\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=3599=static u8 rtw8822c_loss_check_state(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:3600:\t\t\t\t    struct rtw8822c_dpk_data *data)\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3601-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3605-\trtw8822c_dpk_one_shot(rtwdev, path, RTW_DPK_GAIN_LOSS);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:3606:\tstate = rtw8822c_dpk_agc_loss_chk(rtwdev, path);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3607-\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=3611=static u8 (*dpk_state[])(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:3612:\t\t\t  struct rtw8822c_dpk_data *data) = {\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:3613:\trtw8822c_gain_check_state, rtw8822c_gain_large_state,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:3614:\trtw8822c_gain_less_state, rtw8822c_gl_large_state,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:3615:\trtw8822c_gl_less_state, rtw8822c_loss_check_state };\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3616-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=3617=static u8 rtw8822c_dpk_pas_agc(struct rtw_dev *rtwdev, u8 path,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3619-{\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:3620:\tstruct rtw8822c_dpk_data data = {0};\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:3621:\tu8 (*func)(struct rtw_dev *rtwdev, struct rtw8822c_dpk_data *data);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3622-\tu8 state = RTW_DPK_GAIN_CHECK;\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=3672=static void rtw8822c_dpk_coef_tbl_apply(struct rtw_dev *rtwdev, u8 path)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3678-\t\trtw_write32(rtwdev, REG_RXSRAM_CTL,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:3679:\t\t\t    rtw8822c_dpk_get_coef_tbl[i]);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:3680:\t\tdpk_info-\u003ecoef[path][i] = rtw8822c_dpk_coef_transfer(rtwdev);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3681-\t}\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=3758=static u32 rtw8822c_dpk_gainloss(struct rtw_dev *rtwdev, u8 path)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3762-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:3763:\tori_txbb = rtw8822c_dpk_rf_setting(rtwdev, path);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3764-\tori_txagc = (u8)rtw_read_rf(rtwdev, path, RF_MODE_TRXAGC, BIT_TXAGC);\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3775-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:3776:\tt1 = rtw8822c_dpk_thermal_read(rtwdev, path);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:3777:\ttx_bb = rtw8822c_dpk_pas_agc(rtwdev, path, false, true);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:3778:\ttx_agc_search = rtw8822c_dpk_gainloss_result(rtwdev, path);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3779-\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3788-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:3789:\tt2 = rtw8822c_dpk_thermal_read(rtwdev, path);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3790-\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=3796=static u8 rtw8822c_dpk_by_path(struct rtw_dev *rtwdev, u32 tx_agc, u8 path)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3799-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:3800:\tresult = rtw8822c_dpk_one_shot(rtwdev, path, RTW_DPK_DO_DPK);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3801-\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=3949=static void rtw8822c_dpk_result_reset(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3963-\t\tdpk_info-\u003epre_pwsf[path] = 0;\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:3964:\t\tdpk_info-\u003ethermal_dpk[path] = rtw8822c_dpk_thermal_read(rtwdev,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3965-\t\t\t\t\t\t\t\t\tpath);\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=3969=static void rtw8822c_dpk_calibrate(struct rtw_dev *rtwdev, u8 path)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3976-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:3977:\tdpk_txagc = rtw8822c_dpk_gainloss(rtwdev, path);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3978-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:3979:\tdpk_fail = rtw8822c_dpk_by_path(rtwdev, dpk_txagc, path);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-3980-\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=4128=static void rtw8822c_dpk_track(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-4138-\tfor (path = 0; path \u003c DPK_RF_PATH_NUM; path++) {\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4139:\t\tthermal_value[path] = rtw8822c_dpk_thermal_read(rtwdev, path);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-4140-\t\tewma_thermal_add(\u0026dpk_info-\u003eavg_thermal[path],\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=4251=static void rtw8822c_cfo_track(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-4267-\tcfo-\u003epacket_count_pre = cfo-\u003epacket_count;\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4268:\tcfo_avg = rtw8822c_cfo_calc_avg(rtwdev, path_num);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-4269-\trtw8822c_cfo_need_adjust(rtwdev, cfo_avg);\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=4299=rtw8822c_phy_cck_pd_set_reg(struct rtw_dev *rtwdev,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-4307-\tpd = rtw_read32_mask(rtwdev,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4308:\t\t\t     rtw8822c_cck_pd_reg[bw][nrx].reg_pd,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4309:\t\t\t     rtw8822c_cck_pd_reg[bw][nrx].mask_pd);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-4310-\tcs = rtw_read32_mask(rtwdev,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4311:\t\t\t     rtw8822c_cck_pd_reg[bw][nrx].reg_cs,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4312:\t\t\t     rtw8822c_cck_pd_reg[bw][nrx].mask_cs);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-4313-\tpd += pd_diff;\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-4321-\trtw_write32_mask(rtwdev,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4322:\t\t\t rtw8822c_cck_pd_reg[bw][nrx].reg_pd,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4323:\t\t\t rtw8822c_cck_pd_reg[bw][nrx].mask_pd,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-4324-\t\t\t pd);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-4325-\trtw_write32_mask(rtwdev,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4326:\t\t\t rtw8822c_cck_pd_reg[bw][nrx].reg_cs,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4327:\t\t\t rtw8822c_cck_pd_reg[bw][nrx].mask_cs,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-4328-\t\t\t cs);\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,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-4904-\t.query_phy_status\t= query_phy_status,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4905:\t.set_channel\t\t= rtw8822c_set_channel,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4906:\t.mac_init\t\t= rtw8822c_mac_init,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-4907-\t.mac_postinit\t\t= NULL,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4908:\t.dump_fw_crash\t\t= rtw8822c_dump_fw_crash,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-4909-\t.read_rf\t\t= rtw_phy_read_rf,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-4910-\t.write_rf\t\t= rtw_phy_write_rf_reg_mix,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4911:\t.set_tx_power_index\t= rtw8822c_set_tx_power_index,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4912:\t.set_antenna\t\t= rtw8822c_set_antenna,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4913:\t.cfg_ldo25\t\t= rtw8822c_cfg_ldo25,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-4914-\t.set_ampdu_factor\t= NULL,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4915:\t.false_alarm_statistics\t= rtw8822c_false_alarm_statistics,\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,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4919:\t.pwr_track\t\t= rtw8822c_pwr_track,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4920:\t.config_bfee\t\t= rtw8822c_bf_config_bfee,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-4921-\t.set_gid_table\t\t= rtw_bf_set_gid_table,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-4922-\t.cfg_csi_rate\t\t= rtw_bf_cfg_csi_rate,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4923:\t.adaptivity_init\t= rtw8822c_adaptivity_init,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4924:\t.adaptivity\t\t= rtw8822c_adaptivity,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4925:\t.cfo_init\t\t= rtw8822c_cfo_init,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4926:\t.cfo_track\t\t= rtw8822c_cfo_track,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4927:\t.config_tx_path\t\t= rtw8822c_config_tx_path,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4928:\t.config_txrx_mode\t= rtw8822c_config_trx_mode,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4929:\t.led_set\t\t= rtw8822c_led_set,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4930:\t.fill_txdesc_checksum\t= rtw8822c_fill_txdesc_checksum,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-4931-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4932:\t.coex_set_init\t\t= rtw8822c_coex_cfg_init,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-4933-\t.coex_set_ant_switch\t= NULL,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4934:\t.coex_set_gnt_fix\t= rtw8822c_coex_cfg_gnt_fix,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4935:\t.coex_set_gnt_debug\t= rtw8822c_coex_cfg_gnt_debug,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4936:\t.coex_set_rfe_type\t= rtw8822c_coex_cfg_rfe_type,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4937:\t.coex_set_wl_tx_power\t= rtw8822c_coex_cfg_wl_tx_power,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:4938:\t.coex_set_wl_rx_gain\t= rtw8822c_coex_cfg_wl_rx_gain,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-4939-};\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=5197=static const struct rtw_pwr_track_tbl rtw8822c_pwr_track_type0_tbl = {\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:5198:\t.pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_1],\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:5199:\t.pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_2],\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:5200:\t.pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_3],\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:5201:\t.pwrtrk_5gb_p[RTW_PWR_TRK_5G_1] = rtw8822c_pwrtrk_5gb_p[RTW_PWR_TRK_5G_1],\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:5202:\t.pwrtrk_5gb_p[RTW_PWR_TRK_5G_2] = rtw8822c_pwrtrk_5gb_p[RTW_PWR_TRK_5G_2],\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:5203:\t.pwrtrk_5gb_p[RTW_PWR_TRK_5G_3] = rtw8822c_pwrtrk_5gb_p[RTW_PWR_TRK_5G_3],\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:5204:\t.pwrtrk_5ga_n[RTW_PWR_TRK_5G_1] = rtw8822c_pwrtrk_5ga_n[RTW_PWR_TRK_5G_1],\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:5205:\t.pwrtrk_5ga_n[RTW_PWR_TRK_5G_2] = rtw8822c_pwrtrk_5ga_n[RTW_PWR_TRK_5G_2],\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:5206:\t.pwrtrk_5ga_n[RTW_PWR_TRK_5G_3] = rtw8822c_pwrtrk_5ga_n[RTW_PWR_TRK_5G_3],\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:5207:\t.pwrtrk_5ga_p[RTW_PWR_TRK_5G_1] = rtw8822c_pwrtrk_5ga_p[RTW_PWR_TRK_5G_1],\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:5208:\t.pwrtrk_5ga_p[RTW_PWR_TRK_5G_2] = rtw8822c_pwrtrk_5ga_p[RTW_PWR_TRK_5G_2],\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:5209:\t.pwrtrk_5ga_p[RTW_PWR_TRK_5G_3] = rtw8822c_pwrtrk_5ga_p[RTW_PWR_TRK_5G_3],\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:5210:\t.pwrtrk_2gb_n = rtw8822c_pwrtrk_2gb_n,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:5211:\t.pwrtrk_2gb_p = rtw8822c_pwrtrk_2gb_p,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:5212:\t.pwrtrk_2ga_n = rtw8822c_pwrtrk_2ga_n,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:5213:\t.pwrtrk_2ga_p = rtw8822c_pwrtrk_2ga_p,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:5214:\t.pwrtrk_2g_cckb_n = rtw8822c_pwrtrk_2g_cck_b_n,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:5215:\t.pwrtrk_2g_cckb_p = rtw8822c_pwrtrk_2g_cck_b_p,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:5216:\t.pwrtrk_2g_ccka_n = rtw8822c_pwrtrk_2g_cck_a_n,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:5217:\t.pwrtrk_2g_ccka_p = rtw8822c_pwrtrk_2g_cck_a_p,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-5218-};\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c=5251=static const struct rtw_reg_domain coex_info_hw_regs_8822c[] = {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-5275-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:5276:const struct rtw_chip_info rtw8822c_hw_spec = {\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-5277-\t.ops = \u0026rtw8822c_ops,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-5315-\t.intf_table = \u0026phy_para_table_8822c,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:5316:\t.dig = rtw8822c_dig,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-5317-\t.dig_cck = NULL,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-5325-\t.rf_tbl = {\u0026rtw8822c_rf_b_tbl, \u0026rtw8822c_rf_a_tbl},\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:5326:\t.rfe_defs = rtw8822c_rfe_defs,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-5327-\t.rfe_defs_size = ARRAY_SIZE(rtw8822c_rfe_defs),\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-5335-\t.tx_stbc = true,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:5336:\t.edcca_th = rtw8822c_edcca_th,\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-5337-\t.l2h_th_ini_cs = 60,\n"
}

21/2 2026/08/13 07:49 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 43877
							output: 45
							thoughts: 73
						

Thoughts:
**Examining the Static Nature of Functions and a Key Structure**

Okay, so I'm looking through this code and my initial observation is that all the functions I've been working with are static. That's pretty standard, generally indicating they're only meant to be used within the current file or module. However, I've just noticed `rtw8822c_hw_spec`. Wait, that's declared as `const struct rtw_chip_info rtw8822c_hw_spec`. And the fact that it's `const` is interesting. More importantly, I'm thinking, this isn't just a local variable; it's a *global* static variable, meaning it's likely exported, or used, outside of this specific file. This changes the game, it means other parts of the driver probably make use of this piece of information. I should verify that. Let's delve into the definition and usage of `rtw8822c_hw_spec` to understand its role and how it's being accessed.



22/2 2026/08/13 07:49 tool grepper
0m Args:
{
  "Expression": "rtw8822c_hw_spec",
  "PathPrefix": "drivers/net/wireless/realtek/rtw88/"
}

Results:
{
  "Output": "drivers/net/wireless/realtek/rtw88/rtw8822c.c=5251=static const struct rtw_reg_domain coex_info_hw_regs_8822c[] = {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-5275-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:5276:const struct rtw_chip_info rtw8822c_hw_spec = {\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-5277-\t.ops = \u0026rtw8822c_ops,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-5380-};\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c:5381:EXPORT_SYMBOL(rtw8822c_hw_spec);\ndrivers/net/wireless/realtek/rtw88/rtw8822c.c-5382-\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.h=127=void rtw8822c_parse_tbl_dpk(struct rtw_dev *rtwdev,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.h-129-\ndrivers/net/wireless/realtek/rtw88/rtw8822c.h:130:extern const struct rtw_chip_info rtw8822c_hw_spec;\ndrivers/net/wireless/realtek/rtw88/rtw8822c.h-131-\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822ce.c=10=static const struct pci_device_id rtw_8822ce_id_table[] = {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822ce.c-12-\t\tPCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xC822),\ndrivers/net/wireless/realtek/rtw88/rtw8822ce.c:13:\t\t.driver_data = (kernel_ulong_t)\u0026rtw8822c_hw_spec\ndrivers/net/wireless/realtek/rtw88/rtw8822ce.c-14-\t},\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822ce.c-16-\t\tPCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xC82F),\ndrivers/net/wireless/realtek/rtw88/rtw8822ce.c:17:\t\t.driver_data = (kernel_ulong_t)\u0026rtw8822c_hw_spec\ndrivers/net/wireless/realtek/rtw88/rtw8822ce.c-18-\t},\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822cs.c=12=static const struct sdio_device_id rtw_8822cs_id_table[] =  {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822cs.c-15-\t\t\t    SDIO_DEVICE_ID_REALTEK_RTW8822CS),\ndrivers/net/wireless/realtek/rtw88/rtw8822cs.c:16:\t\t.driver_data = (kernel_ulong_t)\u0026rtw8822c_hw_spec,\ndrivers/net/wireless/realtek/rtw88/rtw8822cs.c-17-\t},\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822cu.c=11=static const struct usb_device_id rtw_8822cu_id_table[] = {\ndrivers/net/wireless/realtek/rtw88/rtw8822cu.c-12-\t{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc82c, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822cu.c:13:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822c_hw_spec) },\ndrivers/net/wireless/realtek/rtw88/rtw8822cu.c-14-\t{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc812, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822cu.c:15:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822c_hw_spec) },\ndrivers/net/wireless/realtek/rtw88/rtw8822cu.c-16-\t{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xc82e, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822cu.c:17:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822c_hw_spec) },\ndrivers/net/wireless/realtek/rtw88/rtw8822cu.c-18-\t{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xd820, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822cu.c:19:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822c_hw_spec) },\ndrivers/net/wireless/realtek/rtw88/rtw8822cu.c-20-\t{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xd82b, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822cu.c:21:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822c_hw_spec) },\ndrivers/net/wireless/realtek/rtw88/rtw8822cu.c-22-\t{ USB_DEVICE_AND_INTERFACE_INFO(0x13b1, 0x0043, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822cu.c:23:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822c_hw_spec) }, /* Alpha - Alpha */\ndrivers/net/wireless/realtek/rtw88/rtw8822cu.c-24-\t{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3329, 0xff, 0xff, 0xff),\ndrivers/net/wireless/realtek/rtw88/rtw8822cu.c:25:\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822c_hw_spec) }, /* D-Link AC13U rev. A1 */\ndrivers/net/wireless/realtek/rtw88/rtw8822cu.c-26-\t{},\n"
}

23/2 2026/08/13 07:49 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 46196
							output: 43
							thoughts: 176
						

Thoughts:
**Initial Assessment of the Code**

Okay, so I'm looking at this driver. My initial thought process is: "Where do I even begin?" The obvious entry points seem to be `rtw8822cu_probe`, which handles the USB device registration, and the `rtw8822c_ops` function table. Since this looks like a calibration sequence, it's worth seeing what specific functions are involved.

Right now, it looks like most of the modified functions are static, which makes direct external calls a challenge. They appear to be called from `rtw8822c_rf_dac_cal`. `rtw8822c_rf_dac_cal` is in turn called from `rtw8822c_rf_init`, which then gets called from `rtw8822c_phy_set_param`. And, of course, that function is also static! That's not very helpful for debugging or understanding the flow. My goal is to find a non-static function to give me a wider view.

`rtw8822cu_probe` is at least non-static, so let's check it out – I need to understand what's happening at the device level, so it makes sense to go there first. I know that's in `rtw8822cu.c`, so I'll start with that.



24/2 2026/08/13 07:49 tool grepper
0m Args:
{
  "Expression": "rtw8822cu_probe",
  "PathPrefix": "drivers/net/wireless/realtek/rtw88/"
}

Results:
{
  "Output": "drivers/net/wireless/realtek/rtw88/rtw8822cu.c=28=MODULE_DEVICE_TABLE(usb, rtw_8822cu_id_table);\ndrivers/net/wireless/realtek/rtw88/rtw8822cu.c-29-\ndrivers/net/wireless/realtek/rtw88/rtw8822cu.c:30:static int rtw8822cu_probe(struct usb_interface *intf,\ndrivers/net/wireless/realtek/rtw88/rtw8822cu.c-31-\t\t\t   const struct usb_device_id *id)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822cu.c=36=static struct usb_driver rtw_8822cu_driver = {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822cu.c-38-\t.id_table = rtw_8822cu_id_table,\ndrivers/net/wireless/realtek/rtw88/rtw8822cu.c:39:\t.probe = rtw8822cu_probe,\ndrivers/net/wireless/realtek/rtw88/rtw8822cu.c-40-\t.disconnect = rtw_usb_disconnect,\n"
}

25/2 2026/08/13 07:49 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 47074
							output: 50
							thoughts: 49
						

Thoughts:
Here's my take on the thought process:

**USB Probe Function Analysis**

Okay, so `rtw8822cu_probe` is declared as static too. That makes me think... is `rtw_usb_probe` the more generic, underlying probe function that `rtw8822cu_probe` calls? It would make sense if it's the higher-level USB interface code. I need to verify that; it's likely where the core USB initialization logic resides. Let me go double-check the code paths to confirm my suspicions and make sure I'm not missing anything.



26/2 2026/08/13 07:49 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/realtek/rtw88/rtw8822cu.c",
  "FirstLine": 20,
  "LineCount": 30
}

Results:
{
  "Contents": "  20:\t\t{ USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xd82b, 0xff, 0xff, 0xff),\n  21:\t\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822c_hw_spec) },\n  22:\t\t{ USB_DEVICE_AND_INTERFACE_INFO(0x13b1, 0x0043, 0xff, 0xff, 0xff),\n  23:\t\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822c_hw_spec) }, /* Alpha - Alpha */\n  24:\t\t{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3329, 0xff, 0xff, 0xff),\n  25:\t\t  .driver_info = (kernel_ulong_t)\u0026(rtw8822c_hw_spec) }, /* D-Link AC13U rev. A1 */\n  26:\t\t{},\n  27:\t};\n  28:\tMODULE_DEVICE_TABLE(usb, rtw_8822cu_id_table);\n  29:\t\n  30:\tstatic int rtw8822cu_probe(struct usb_interface *intf,\n  31:\t\t\t\t   const struct usb_device_id *id)\n  32:\t{\n  33:\t\treturn rtw_usb_probe(intf, id);\n  34:\t}\n  35:\t\n  36:\tstatic struct usb_driver rtw_8822cu_driver = {\n  37:\t\t.name = KBUILD_MODNAME,\n  38:\t\t.id_table = rtw_8822cu_id_table,\n  39:\t\t.probe = rtw8822cu_probe,\n  40:\t\t.disconnect = rtw_usb_disconnect,\n  41:\t};\n  42:\tmodule_usb_driver(rtw_8822cu_driver);\n  43:\t\n  44:\tMODULE_AUTHOR(\"Realtek Corporation\");\n  45:\tMODULE_DESCRIPTION(\"Realtek 802.11ac wireless 8822cu driver\");\n  46:\tMODULE_LICENSE(\"Dual BSD/GPL\");\n"
}

27/2 2026/08/13 07:49 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 47892
							output: 39
							thoughts: 31
						

Thoughts:
Here's my thinking process:

**Diving into the Realtek USB Driver**

Okay, so `rtw_usb_probe` isn't static. That immediately tells me it's likely a function intended for external use, perhaps called by the USB core when a Realtek device is detected. Now, given that context, the next logical step is to understand what's happening *inside* the probe function and how it interacts with the physical layer (PHY). I need to see how it's setting up the communication. Since I see `phy_set_param` mentioned, I'm going to track down where *that* function is called. That call is likely where some specific hardware setting or configuration is being passed to the PHY. It would be helpful to know what that specific parameter is.



28/2 2026/08/13 07:49 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"
}

29/2 2026/08/13 07:49 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 51075
							output: 40
							thoughts: 51
						

Thoughts:
Here's my thought process, as if I were analyzing this code:

**Analyzing the rtw88 Driver Initialization**

Okay, so I see `phy_set_param` is being called from `rtw_power_on`. That's interesting, and right where I'd expect to see some PHY configuration happening during driver initialization. Clearly, the power-on sequence in `rtw88/main.c` is going to be crucial. Since `rtw_power_on` is the immediate parent function, it makes sense to dive directly into that function to understand the context. I need to figure out what's happening *before* this `phy_set_param` call and *after* to see the entire initialization flow. What settings are being passed to the PHY? What preconditions are met? I'm anticipating this is where the hardware specific parameters are configured, but I need the broader picture to be certain. Let's dig into `rtw_power_on` and see what's what.



30/2 2026/08/13 07:49 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"
}

31/2 2026/08/13 07:49 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 52607
							output: 40
							thoughts: 117
						

Thoughts:
**Analyzing the Realtek Driver's Power-On Sequence for Fuzzing**

Okay, so `rtw_power_on` is exported, which is good – that means it's accessible. But hang on, it's just a generic function defined in `main.c`. To effectively fuzz the *modified* code, I need to pinpoint the right entry points. `rtw_power_on` is a possibility, sure, but so are `rtw_usb_probe` and `rtw_core_init`. Gotta keep all options open for now.

Wait a second… `rtw_power_on` calls `chip->ops->phy_set_param(rtwdev)`. That's interesting; that's where the real hardware interaction probably is. This could be a good starting point. Right, so now I need to find out where `rtw_power_on` itself is *called* to understand its place within the broader initialization flow. Where are the entry points to test the initialization process, to then test my code changes?



32/2 2026/08/13 07:49 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"
}

33/2 2026/08/13 07:49 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 54215
							output: 37
							thoughts: 36
						

Thoughts:
Okay, let's see. My mind is immediately drawn to this `rtw_power_on` function. I see it's assigned to `chip->ops->power_on`. Now, that's interesting. I need to understand the context. Where in this whole architecture is `chip->ops->power_on` actually invoked? I need to trace the call paths to understand how this power-on sequence is initiated. Gotta dig into the code and find where this function is called.



34/2 2026/08/13 07:49 tool grepper
0m Args:
{
  "Expression": "power_on",
  "PathPrefix": "drivers/net/wireless/realtek/rtw88/"
}

Results:
{
  "Output": "drivers/net/wireless/realtek/rtw88/coex.c=2708=static void __rtw_coex_init_hw_config(struct rtw_dev *rtwdev, bool wifi_only)\n--\ndrivers/net/wireless/realtek/rtw88/coex.c-2762-\ndrivers/net/wireless/realtek/rtw88/coex.c:2763:void rtw_coex_power_on_setting(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/coex.c-2764-{\n--\ndrivers/net/wireless/realtek/rtw88/coex.c-2787-}\ndrivers/net/wireless/realtek/rtw88/coex.c:2788:EXPORT_SYMBOL(rtw_coex_power_on_setting);\ndrivers/net/wireless/realtek/rtw88/coex.c-2789-\n--\ndrivers/net/wireless/realtek/rtw88/coex.h=396=void rtw_coex_wl_ccklock_work(struct work_struct *work);\ndrivers/net/wireless/realtek/rtw88/coex.h-397-\ndrivers/net/wireless/realtek/rtw88/coex.h:398:void rtw_coex_power_on_setting(struct rtw_dev *rtwdev);\ndrivers/net/wireless/realtek/rtw88/coex.h-399-void rtw_coex_power_off_setting(struct rtw_dev *rtwdev);\n--\ndrivers/net/wireless/realtek/rtw88/mac.c=370=static int rtw_mac_init_system_cfg(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/mac.c-377-\ndrivers/net/wireless/realtek/rtw88/mac.c:378:int rtw_mac_power_on(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/mac.c-379-{\n--\ndrivers/net/wireless/realtek/rtw88/mac.h=33=int rtw_pwr_seq_parser(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/mac.h-34-\t\t       const struct rtw_pwr_seq_cmd * const *cmd_seq);\ndrivers/net/wireless/realtek/rtw88/mac.h:35:int rtw_mac_power_on(struct rtw_dev *rtwdev);\ndrivers/net/wireless/realtek/rtw88/mac.h-36-void rtw_mac_power_off(struct rtw_dev *rtwdev);\n--\ndrivers/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-1387-\t/* power on MAC before firmware downloaded */\ndrivers/net/wireless/realtek/rtw88/main.c:1388:\tret = rtw_mac_power_on(rtwdev);\ndrivers/net/wireless/realtek/rtw88/main.c-1389-\tif (ret) {\n--\ndrivers/net/wireless/realtek/rtw88/main.c-1431-\twifi_only = !rtwdev-\u003eefuse.btcoex;\ndrivers/net/wireless/realtek/rtw88/main.c:1432:\trtw_coex_power_on_setting(rtwdev);\ndrivers/net/wireless/realtek/rtw88/main.c-1433-\trtw_coex_init_hw_config(rtwdev, wifi_only);\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.c=1515=int rtw_core_start(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/main.c-1518-\ndrivers/net/wireless/realtek/rtw88/main.c:1519:\tret = rtwdev-\u003echip-\u003eops-\u003epower_on(rtwdev);\ndrivers/net/wireless/realtek/rtw88/main.c-1520-\tif (ret)\n--\ndrivers/net/wireless/realtek/rtw88/main.c=1919=static int rtw_chip_efuse_enable(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/main.c-1929-\ndrivers/net/wireless/realtek/rtw88/main.c:1930:\tret = rtw_mac_power_on(rtwdev);\ndrivers/net/wireless/realtek/rtw88/main.c-1931-\tif (ret) {\n--\ndrivers/net/wireless/realtek/rtw88/main.h=862=struct rtw_chip_ops {\ndrivers/net/wireless/realtek/rtw88/main.h:863:\tint (*power_on)(struct rtw_dev *rtwdev);\ndrivers/net/wireless/realtek/rtw88/main.h-864-\tvoid (*power_off)(struct rtw_dev *rtwdev);\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/rtw8812a.c=914=static const struct rtw_chip_ops rtw8812a_ops = {\ndrivers/net/wireless/realtek/rtw88/rtw8812a.c:915:\t.power_on\t\t= rtw88xxa_power_on,\ndrivers/net/wireless/realtek/rtw88/rtw8812a.c-916-\t.power_off\t\t= rtw8812a_power_off,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8814a.c=739=static void rtw8814a_adc_clk(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/rtw8814a.c-807-\ndrivers/net/wireless/realtek/rtw88/rtw8814a.c:808:\t/* power_on/clk_off */\ndrivers/net/wireless/realtek/rtw88/rtw8814a.c-809-\t/* [19] = 0 to turn on ADC */\n--\ndrivers/net/wireless/realtek/rtw88/rtw8814a.c-814-\ndrivers/net/wireless/realtek/rtw88/rtw8814a.c:815:\t/* power_on/clk_on @ anapar_state=BT mode */\ndrivers/net/wireless/realtek/rtw88/rtw8814a.c-816-\trtw_write32(rtwdev, REG_AFE_PWR1_A, 0x05808032);\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/rtw8814a_table.c=23576=const struct rtw_pwr_track_tbl rtw8814a_rtw_pwrtrk_type8_tbl = {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8814a_table.c-23618-\ndrivers/net/wireless/realtek/rtw88/rtw8814a_table.c:23619:static const struct rtw_pwr_seq_cmd init_power_on_8814a[] = {\ndrivers/net/wireless/realtek/rtw88/rtw8814a_table.c-23620-\t{0x10c2,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8814a_table.c=23919=const struct rtw_pwr_seq_cmd * const card_enable_flow_8814a[] = {\ndrivers/net/wireless/realtek/rtw88/rtw8814a_table.c:23920:\tinit_power_on_8814a,\ndrivers/net/wireless/realtek/rtw88/rtw8814a_table.c-23921-\ttrans_carddis_to_cardemu_8814a,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8821a.c=860=static const struct rtw_chip_ops rtw8821a_ops = {\ndrivers/net/wireless/realtek/rtw88/rtw8821a.c:861:\t.power_on\t\t= rtw88xxa_power_on,\ndrivers/net/wireless/realtek/rtw88/rtw8821a.c-862-\t.power_off\t\t= rtw8821a_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/rtw8821c.h=32=struct rtw8821ce_efuse {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8821c.h-62-\tu8 port_common_mode_restore_time;\ndrivers/net/wireless/realtek/rtw88/rtw8821c.h:63:\tu8 port_t_power_on_scale:2;\ndrivers/net/wireless/realtek/rtw88/rtw8821c.h-64-\tu8 res6:1;\ndrivers/net/wireless/realtek/rtw88/rtw8821c.h:65:\tu8 port_t_power_on_value:5;\ndrivers/net/wireless/realtek/rtw88/rtw8821c.h-66-\tu8 res7;\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/rtw8822b.h=32=struct rtw8822be_efuse {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822b.h-62-\tu8 port_common_mode_restore_time;\ndrivers/net/wireless/realtek/rtw88/rtw8822b.h:63:\tu8 port_t_power_on_scale:2;\ndrivers/net/wireless/realtek/rtw88/rtw8822b.h-64-\tu8 res6:1;\ndrivers/net/wireless/realtek/rtw88/rtw8822b.h:65:\tu8 port_t_power_on_value:5;\ndrivers/net/wireless/realtek/rtw88/rtw8822b.h-66-\tu8 res7;\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--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.h=24=struct rtw8822ce_efuse {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822c.h-54-\tu8 port_common_mode_restore_time;\ndrivers/net/wireless/realtek/rtw88/rtw8822c.h:55:\tu8 port_t_power_on_scale:2;\ndrivers/net/wireless/realtek/rtw88/rtw8822c.h-56-\tu8 res6:1;\ndrivers/net/wireless/realtek/rtw88/rtw8822c.h:57:\tu8 port_t_power_on_value:5;\ndrivers/net/wireless/realtek/rtw88/rtw8822c.h-58-\tu8 res7;\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c=304=static void rtw88xxau_hw_reset(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-343-\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c:344:static int rtw88xxau_init_power_on(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-345-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c=927=static void rtw88xxa_switch_band(struct rtw_dev *rtwdev, u8 new_band, u8 bw)\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-1005-\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c:1006:int rtw88xxa_power_on(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-1007-{\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-1048-\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c:1049:\tret = rtw88xxau_init_power_on(rtwdev);\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-1050-\tif (ret) {\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-1228-\tif (efuse-\u003ebtcoex) {\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c:1229:\t\trtw_coex_power_on_setting(rtwdev);\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-1230-\t\trtw_coex_init_hw_config(rtwdev, false);\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-1242-}\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c:1243:EXPORT_SYMBOL(rtw88xxa_power_on);\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.c-1244-\n--\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.h=144=void rtw88xxa_power_off(struct rtw_dev *rtwdev,\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.h-145-\t\t\tconst struct rtw_pwr_seq_cmd *const *enter_lps_flow);\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.h:146:int rtw88xxa_power_on(struct rtw_dev *rtwdev);\ndrivers/net/wireless/realtek/rtw88/rtw88xxa.h-147-u32 rtw88xxa_phy_read_rf(struct rtw_dev *rtwdev,\n"
}

35/2 2026/08/13 07:49 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 59559
							output: 40
							thoughts: 52
						

Thoughts:
Here's my summary, as though I'm thinking through this code:

**Tracing the Power-On Sequence**

Okay, so `rtw_core_start` kicks things off. It's exported, so that means other parts of the system can call into it. The important part is that `rtw_core_start` calls `chip->ops->power_on(rtwdev)`. That's where the *actual* power-on sequence seems to begin, as defined by the `chip`'s specific operations table. This `chip->ops->power_on` pointer is key. The `rtwdev` is likely my device structure, the container for all the necessary device-specific data. Now I need to figure out *who* is calling `rtw_core_start`. Knowing the calling context will shed light on the system's initialization sequence and identify the triggers for powering up. Time to go hunting for call sites.



36/2 2026/08/13 07:49 tool grepper
0m Args:
{
  "Expression": "rtw_core_start",
  "PathPrefix": "drivers/net/wireless/realtek/rtw88/"
}

Results:
{
  "Output": "drivers/net/wireless/realtek/rtw88/mac80211.c=53=static int rtw_ops_start(struct ieee80211_hw *hw)\n--\ndrivers/net/wireless/realtek/rtw88/mac80211.c-58-\tmutex_lock(\u0026rtwdev-\u003emutex);\ndrivers/net/wireless/realtek/rtw88/mac80211.c:59:\tret = rtw_core_start(rtwdev);\ndrivers/net/wireless/realtek/rtw88/mac80211.c-60-\tmutex_unlock(\u0026rtwdev-\u003emutex);\n--\ndrivers/net/wireless/realtek/rtw88/main.c=1490=void rtw_core_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,\n--\ndrivers/net/wireless/realtek/rtw88/main.c-1514-\ndrivers/net/wireless/realtek/rtw88/main.c:1515:int rtw_core_start(struct rtw_dev *rtwdev)\ndrivers/net/wireless/realtek/rtw88/main.c-1516-{\n--\ndrivers/net/wireless/realtek/rtw88/main.h=2253=void rtw_core_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,\ndrivers/net/wireless/realtek/rtw88/main.h-2254-\t\t\t    bool hw_scan);\ndrivers/net/wireless/realtek/rtw88/main.h:2255:int rtw_core_start(struct rtw_dev *rtwdev);\ndrivers/net/wireless/realtek/rtw88/main.h-2256-void rtw_power_off(struct rtw_dev *rtwdev);\n--\ndrivers/net/wireless/realtek/rtw88/ps.c=13=static int rtw_ips_pwr_up(struct rtw_dev *rtwdev)\n--\ndrivers/net/wireless/realtek/rtw88/ps.c-16-\ndrivers/net/wireless/realtek/rtw88/ps.c:17:\tret = rtw_core_start(rtwdev);\ndrivers/net/wireless/realtek/rtw88/ps.c-18-\tif (ret)\n"
}

37/2 2026/08/13 07:49 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 60496
							output: 40
							thoughts: 448
						

Thoughts:
**My Initial Thoughts on the Initialization Flow**

Okay, so I'm digging into this `mac80211` driver and trying to map the initialization process. Right, `rtw_core_start` gets called from `rtw_ops_start`, which is that `mac80211` `start` callback. Therefore: the flow is `rtw_ops_start` calls `rtw_core_start`, and then that cascades to `rtw_power_on`, which hits `rtw8822c_phy_set_param`, `rtw8822c_rf_init`, then `rtw8822c_rf_dac_cal` and onward to that calibration routine: `rtw8822c_dac_cal_step2/3`, `rtw8822c_dac_cal_rf_mode`, and then some sampling in `rtw8822c_dac_cal_iq_sample`, and finally the check in `rtw8822c_dac_iq_check`.

So, `rtw_core_start` looks like a key symbol to start with. Wait, looking at the code, `rtw_core_start` is in `main.c`, which is generic across the `rtw88` chips. If I fuzz that function, then the code for `rtw8822c` will execute because the functions called are different.

Hmm, let's see, are there any other functions that are non-static? Looks like `rtw_power_on` is a good one to examine as well. And `rtw_usb_probe` looks interesting, it could be a useful one as well.

Okay, let's check `rtw8822c_rf_dac_cal`...nope, it's static. Dang. What about `rtw8822c_hw_spec`? That is a struct, never mind!

Okay, new plan. Using `rtw_core_start` and `rtw_power_on` as focus points. And `rtw_usb_probe` looks like a good one too, it's an initialization entry point when the USB device is probed. Wait, it's defined in `usb.c`! Let's examine `rtw_usb_probe` in detail.



38/2 2026/08/13 07:49 tool grepper
0m Args:
{
  "Expression": "rtw_usb_probe",
  "PathPrefix": "drivers/net/wireless/realtek/rtw88/"
}

Results:
{
  "Output": "drivers/net/wireless/realtek/rtw88/rtw8723du.c=20=static int rtw8723du_probe(struct usb_interface *intf,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8723du.c-22-{\ndrivers/net/wireless/realtek/rtw88/rtw8723du.c:23:\treturn rtw_usb_probe(intf, id);\ndrivers/net/wireless/realtek/rtw88/rtw8723du.c-24-}\n--\ndrivers/net/wireless/realtek/rtw88/rtw8812au.c=84=static struct usb_driver rtw_8812au_driver = {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8812au.c-86-\t.id_table = rtw_8812au_id_table,\ndrivers/net/wireless/realtek/rtw88/rtw8812au.c:87:\t.probe = rtw_usb_probe,\ndrivers/net/wireless/realtek/rtw88/rtw8812au.c-88-\t.disconnect = rtw_usb_disconnect,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8814au.c=44=static struct usb_driver rtw_8814au_driver = {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8814au.c-46-\t.id_table = rtw_8814au_id_table,\ndrivers/net/wireless/realtek/rtw88/rtw8814au.c:47:\t.probe = rtw_usb_probe,\ndrivers/net/wireless/realtek/rtw88/rtw8814au.c-48-\t.disconnect = rtw_usb_disconnect,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8821au.c=68=static struct usb_driver rtw_8821au_driver = {\n--\ndrivers/net/wireless/realtek/rtw88/rtw8821au.c-70-\t.id_table = rtw_8821au_id_table,\ndrivers/net/wireless/realtek/rtw88/rtw8821au.c:71:\t.probe = rtw_usb_probe,\ndrivers/net/wireless/realtek/rtw88/rtw8821au.c-72-\t.disconnect = rtw_usb_disconnect,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8821cu.c=46=static int rtw_8821cu_probe(struct usb_interface *intf,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8821cu.c-48-{\ndrivers/net/wireless/realtek/rtw88/rtw8821cu.c:49:\treturn rtw_usb_probe(intf, id);\ndrivers/net/wireless/realtek/rtw88/rtw8821cu.c-50-}\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c=88=static int rtw8822bu_probe(struct usb_interface *intf,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-90-{\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c:91:\treturn rtw_usb_probe(intf, id);\ndrivers/net/wireless/realtek/rtw88/rtw8822bu.c-92-}\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822cu.c=30=static int rtw8822cu_probe(struct usb_interface *intf,\n--\ndrivers/net/wireless/realtek/rtw88/rtw8822cu.c-32-{\ndrivers/net/wireless/realtek/rtw88/rtw8822cu.c:33:\treturn rtw_usb_probe(intf, id);\ndrivers/net/wireless/realtek/rtw88/rtw8822cu.c-34-}\n--\ndrivers/net/wireless/realtek/rtw88/usb.c=1225=static void rtw_usb_phy_cfg(struct rtw_dev *rtwdev,\n--\ndrivers/net/wireless/realtek/rtw88/usb.c-1262-\ndrivers/net/wireless/realtek/rtw88/usb.c:1263:int rtw_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)\ndrivers/net/wireless/realtek/rtw88/usb.c-1264-{\n--\ndrivers/net/wireless/realtek/rtw88/usb.c-1358-}\ndrivers/net/wireless/realtek/rtw88/usb.c:1359:EXPORT_SYMBOL(rtw_usb_probe);\ndrivers/net/wireless/realtek/rtw88/usb.c-1360-\n--\ndrivers/net/wireless/realtek/rtw88/usb.h=90=static inline struct rtw_usb_tx_data *rtw_usb_get_tx_data(struct sk_buff *skb)\n--\ndrivers/net/wireless/realtek/rtw88/usb.h-99-\ndrivers/net/wireless/realtek/rtw88/usb.h:100:int rtw_usb_probe(struct usb_interface *intf, const struct usb_device_id *id);\ndrivers/net/wireless/realtek/rtw88/usb.h-101-void rtw_usb_disconnect(struct usb_interface *intf);\n"
}

39/2 2026/08/13 07:49 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 63039
							output: 34
							thoughts: 315
						

Thoughts:
**My Analysis of the Realtek USB Driver Configuration**

Okay, so `rtw_usb_probe` is definitely exported, that's good. Which means that `FocusSymbols` can be `rtw_usb_probe`, `rtw_core_start`, and `rtw_power_on`. Ah, I remember, `rtw_core_start` is actually called from the mac80211 `start` callback. And `rtw_usb_probe` gets triggered when the USB device is probed, and it's responsible for registering the mac80211 device. That mac80211 device then calls the `start` function when the interface is brought up. That's the flow.

Now, I need to make sure I've got all the required configurations. Let me see... I'm thinking I'll need `RTW88`, `RTW88_8822CU`, `MAC80211`, and `USB`.

Just to be absolutely certain, I'll go back and check the `drivers/net/wireless/realtek/rtw88/Kconfig` file again, specifically for `RTW88_8822C`. Ah, right, `RTW88_8822CU` *selects* `RTW88_8822C`. That means `RTW88_8822C` will be enabled automatically, so I don't need to list it explicitly. Excellent.

So, the essentials are definitely `RTW88`, `RTW88_8822CU`, `MAC80211`, and `USB`. But hang on a minute... isn't `WLAN` also needed? Let me just confirm that by quickly checking the `drivers/net/wireless/realtek/Kconfig` file.



40/2 2026/08/13 07:50 tool grepper
0m Args:
{
  "Expression": "config RTW88",
  "PathPrefix": "drivers/net/wireless/realtek/"
}

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"
}

41/2 2026/08/13 07:50 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 66919
							output: 37
							thoughts: 34
						

Thoughts:
**Digging into the Realtek WLAN Driver Hierarchy**

Okay, so I'm trying to wrap my head around this driver structure. Hang on... `WLAN` is the overarching category, the parent, and `RTW88` is nestled within it. That makes sense conceptually, but let's just confirm with the Kconfig files. Time to crack open `drivers/net/wireless/realtek/Kconfig` and take a look. This is where the core configuration options are defined, and where I can clarify the dependencies and relationships I'm seeing.



42/2 2026/08/13 07:50 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/realtek/Kconfig",
  "FirstLine": 1,
  "LineCount": 30
}

Results:
{
  "Contents": "   1:\t# SPDX-License-Identifier: GPL-2.0-only\n   2:\tconfig WLAN_VENDOR_REALTEK\n   3:\t\tbool \"Realtek devices\"\n   4:\t\tdefault y\n   5:\t\thelp\n   6:\t\t  If you have a wireless card belonging to this class, say Y.\n   7:\t\n   8:\t\t  Note that the answer to this question doesn't directly affect the\n   9:\t\t  kernel: saying N will just cause the configurator to skip all the\n  10:\t\t  questions about these cards. If you say Y, you will be asked for\n  11:\t\t  your specific card in the following questions.\n  12:\t\n  13:\tif WLAN_VENDOR_REALTEK\n  14:\t\n  15:\tsource \"drivers/net/wireless/realtek/rtl818x/Kconfig\"\n  16:\tsource \"drivers/net/wireless/realtek/rtlwifi/Kconfig\"\n  17:\tsource \"drivers/net/wireless/realtek/rtl8xxxu/Kconfig\"\n  18:\tsource \"drivers/net/wireless/realtek/rtw88/Kconfig\"\n  19:\tsource \"drivers/net/wireless/realtek/rtw89/Kconfig\"\n  20:\t\n  21:\tendif # WLAN_VENDOR_REALTEK\n"
}

43/2 2026/08/13 07:50 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 67451
							output: 28
							thoughts: 98
						

Thoughts:
**My Configuration Workflow**

Okay, so I'm putting together this build, and it's pretty clear I need to enable support for this Realtek WLAN device, specifically `WLAN_VENDOR_REALTEK`.  That's my starting point. And of course, `WLAN` is a prerequisite for that; it's the foundational piece. So, that's already two essential flags: `WLAN` and `WLAN_VENDOR_REALTEK`.

Thinking this through further, and based on experience, I'll need `MAC80211` for the wireless stack, and because this is likely a USB device, `USB` is definitely required. The Realtek driver likely sits under a generic RTW88 umbrella, so `RTW88` is probably needed. And given the specific chipset I'm targeting here, which is the 8822CU, I'll add `RTW88_8822CU` too.

Let me just quickly verify `WLAN` again, make sure I haven't missed anything obvious.



44/2 2026/08/13 07:50 tool grepper
0m Args:
{
  "Expression": "config WLAN",
  "PathPrefix": "drivers/net/wireless/"
}

Results:
{
  "Output": "drivers/net/wireless/Kconfig-5-\ndrivers/net/wireless/Kconfig:6:menuconfig WLAN\ndrivers/net/wireless/Kconfig-7-\tbool \"Wireless LAN\"\n--\ndrivers/net/wireless/admtek/Kconfig-1-# SPDX-License-Identifier: GPL-2.0-only\ndrivers/net/wireless/admtek/Kconfig:2:config WLAN_VENDOR_ADMTEK\ndrivers/net/wireless/admtek/Kconfig-3-\tbool \"ADMtek devices\"\n--\ndrivers/net/wireless/ath/Kconfig=2=config ATH_COMMON\n--\ndrivers/net/wireless/ath/Kconfig-4-\ndrivers/net/wireless/ath/Kconfig:5:config WLAN_VENDOR_ATH\ndrivers/net/wireless/ath/Kconfig-6-\tbool \"Atheros/Qualcomm devices\"\n--\ndrivers/net/wireless/atmel/Kconfig-1-# SPDX-License-Identifier: GPL-2.0-only\ndrivers/net/wireless/atmel/Kconfig:2:config WLAN_VENDOR_ATMEL\ndrivers/net/wireless/atmel/Kconfig-3-\tbool \"Atmel devices\"\n--\ndrivers/net/wireless/broadcom/Kconfig-1-# SPDX-License-Identifier: GPL-2.0-only\ndrivers/net/wireless/broadcom/Kconfig:2:config WLAN_VENDOR_BROADCOM\ndrivers/net/wireless/broadcom/Kconfig-3-\tbool \"Broadcom devices\"\n--\ndrivers/net/wireless/intel/Kconfig-1-# SPDX-License-Identifier: GPL-2.0-only\ndrivers/net/wireless/intel/Kconfig:2:config WLAN_VENDOR_INTEL\ndrivers/net/wireless/intel/Kconfig-3-\tbool \"Intel devices\"\n--\ndrivers/net/wireless/intersil/Kconfig-1-# SPDX-License-Identifier: GPL-2.0-only\ndrivers/net/wireless/intersil/Kconfig:2:config WLAN_VENDOR_INTERSIL\ndrivers/net/wireless/intersil/Kconfig-3-\tbool \"Intersil devices\"\n--\ndrivers/net/wireless/marvell/Kconfig-1-# SPDX-License-Identifier: GPL-2.0-only\ndrivers/net/wireless/marvell/Kconfig:2:config WLAN_VENDOR_MARVELL\ndrivers/net/wireless/marvell/Kconfig-3-\tbool \"Marvell devices\"\n--\ndrivers/net/wireless/mediatek/Kconfig-1-# SPDX-License-Identifier: GPL-2.0-only\ndrivers/net/wireless/mediatek/Kconfig:2:config WLAN_VENDOR_MEDIATEK\ndrivers/net/wireless/mediatek/Kconfig-3-\tbool \"MediaTek devices\"\n--\ndrivers/net/wireless/microchip/Kconfig-1-# SPDX-License-Identifier: GPL-2.0\ndrivers/net/wireless/microchip/Kconfig:2:config WLAN_VENDOR_MICROCHIP\ndrivers/net/wireless/microchip/Kconfig-3-\tbool \"Microchip devices\"\n--\ndrivers/net/wireless/purelifi/Kconfig-1-# SPDX-License-Identifier: GPL-2.0-only\ndrivers/net/wireless/purelifi/Kconfig:2:config WLAN_VENDOR_PURELIFI\ndrivers/net/wireless/purelifi/Kconfig-3-\tbool \"pureLiFi devices\"\n--\ndrivers/net/wireless/quantenna/Kconfig-1-# SPDX-License-Identifier: GPL-2.0-only\ndrivers/net/wireless/quantenna/Kconfig:2:config WLAN_VENDOR_QUANTENNA\ndrivers/net/wireless/quantenna/Kconfig-3-\tbool \"Quantenna wireless cards support\"\n--\ndrivers/net/wireless/ralink/Kconfig-1-# SPDX-License-Identifier: GPL-2.0-only\ndrivers/net/wireless/ralink/Kconfig:2:config WLAN_VENDOR_RALINK\ndrivers/net/wireless/ralink/Kconfig-3-\tbool \"Ralink devices\"\n--\ndrivers/net/wireless/realtek/Kconfig-1-# SPDX-License-Identifier: GPL-2.0-only\ndrivers/net/wireless/realtek/Kconfig:2:config WLAN_VENDOR_REALTEK\ndrivers/net/wireless/realtek/Kconfig-3-\tbool \"Realtek devices\"\n--\ndrivers/net/wireless/rsi/Kconfig-1-# SPDX-License-Identifier: GPL-2.0-only\ndrivers/net/wireless/rsi/Kconfig:2:config WLAN_VENDOR_RSI\ndrivers/net/wireless/rsi/Kconfig-3-\tbool \"Redpine Signals Inc devices\"\n--\ndrivers/net/wireless/silabs/Kconfig-2-\ndrivers/net/wireless/silabs/Kconfig:3:config WLAN_VENDOR_SILABS\ndrivers/net/wireless/silabs/Kconfig-4-\tbool \"Silicon Laboratories devices\"\n--\ndrivers/net/wireless/st/Kconfig-1-# SPDX-License-Identifier: GPL-2.0-only\ndrivers/net/wireless/st/Kconfig:2:config WLAN_VENDOR_ST\ndrivers/net/wireless/st/Kconfig-3-\tbool \"STMicroelectronics devices\"\n--\ndrivers/net/wireless/ti/Kconfig-1-# SPDX-License-Identifier: GPL-2.0-only\ndrivers/net/wireless/ti/Kconfig:2:config WLAN_VENDOR_TI\ndrivers/net/wireless/ti/Kconfig-3-\tbool \"Texas Instrument devices\"\n--\ndrivers/net/wireless/zydas/Kconfig-1-# SPDX-License-Identifier: GPL-2.0-only\ndrivers/net/wireless/zydas/Kconfig:2:config WLAN_VENDOR_ZYDAS\ndrivers/net/wireless/zydas/Kconfig-3-\tbool \"ZyDAS devices\"\n"
}

45/2 2026/08/13 07:50 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 69195
							output: 206
							thoughts: 180
						

Thoughts:
**Analyzing the Realtek WLAN Configuration**

Alright, let's break this down. The key configurations we're dealing with are centered around Realtek WLAN and specifically target the `RTW88` driver, likely for a `RTW8822CU` chipset, which is great. I can see the core elements: `WLAN`, `WLAN_VENDOR_REALTEK`, `MAC80211`, `USB`, `RTW88`, and `RTW88_8822CU`. We're obviously working with a USB-connected Realtek Wi-Fi device.

Now, I need to confirm the critical function names. I've flagged `rtw_usb_probe`, `rtw_core_start`, and `rtw_power_on` as areas of interest. Quickly verifying each function call, `rtw_usb_probe` is, as expected, within `usb.c`. `rtw_core_start` and `rtw_power_on` are correctly situated within `main.c`. Makes perfect sense.

I'm satisfied with the function name verification; that confirms the foundation is solid, now I can set up the remaining analysis results.



46/2 2026/08/13 07:50 tool set-results
0m Args:
{
  "EnableConfigs": [
    "WLAN",
    "WLAN_VENDOR_REALTEK",
    "MAC80211",
    "USB",
    "RTW88",
    "RTW88_8822CU"
  ],
  "FocusSymbols": [
    "rtw_usb_probe",
    "rtw_core_start",
    "rtw_power_on"
  ],
  "Reasoning": "The patch modifies the DAC IQ calibration logic in the Realtek rtw8822c wireless driver. This code is reachable in virtualized environments via USB emulation using the rtw8822cu driver variant. The changes are functional (replacing custom sorting/min-max logic with standard library functions and changing types), so they are worth fuzzing. The entry points for this code path include the USB probe function and the mac80211 start/power-on callbacks.",
  "WorthFuzzing": true
}

Results:
{
  "EnableConfigs": [
    "WLAN",
    "WLAN_VENDOR_REALTEK",
    "MAC80211",
    "USB",
    "RTW88",
    "RTW88_8822CU"
  ],
  "FocusSymbols": [
    "rtw_usb_probe",
    "rtw_core_start",
    "rtw_power_on"
  ],
  "Reasoning": "The patch modifies the DAC IQ calibration logic in the Realtek rtw8822c wireless driver. This code is reachable in virtualized environments via USB emulation using the rtw8822cu driver variant. The changes are functional (replacing custom sorting/min-max logic with standard library functions and changing types), so they are worth fuzzing. The entry points for this code path include the USB probe function and the mac80211 start/power-on callbacks.",
  "WorthFuzzing": true
}

47/1 2026/08/13 07:50 action If
1m Args:
{
  "WorthFuzzing": true
}

Results:
null

48/2 2026/08/13 07:50 agent kmsan-evaluator
1m Model:
best-expensive

Args:
null

Results:
{
  "KMSANReasoning": "The patch refactors the DAC IQ calibration logic in the rtw88 wireless driver, changing the data types of the `iv` and `qv` arrays from `u32` to `s32` and replacing custom sorting and min/max functions with standard kernel functions (`sort()`, `sign_extend32()`). The arrays `iv` and `qv` are allocated on the stack and populated by reading hardware registers in a loop. While there is a pre-existing theoretical risk that these arrays might not be fully initialized if the hardware fails to provide enough valid samples within a timeout, this patch does not introduce or exacerbate this risk. It merely changes the arithmetic operations performed on the data. Furthermore, these arrays are used strictly internally for hardware calibration and do not leak to userspace. Since no new uninitialized memory risks or info-leaks are introduced, a dedicated KMSAN fuzzing session is not justified. Standard KASAN and other bug detectors are sufficient to catch any out-of-bounds or memory corruption issues.",
  "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 c0cd274bc35551f8f4b4a082e8c1187bc263c70e
Author: syz-cluster <triage@syzkaller.com>
Date:   Thu Aug 13 07:48:29 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);

49/3 2026/08/13 07:50 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 5535
							output: 26
							thoughts: 1751
						

Thoughts:
**KMSAN Fuzzing Session Justification**

Okay, so I'm looking at this patch modifying `drivers/net/wireless/realtek/rtw88/rtw8822c.c`, and I need to decide if it warrants a dedicated KMSAN fuzzing session. The core of the change appears to be in the DAC IQ calibration routine. It's swapped `u32` arrays for `s32` arrays (`iv`, `qv`) within `rtw8822c_dac_cal_rf_mode`, which affects how DAC IQ calibration happens. This includes changing the sorting function to the standard `sort()`, using `rtw8822c_dac_iq_cmp_s32`, and some value type conversions within functions like `rtw8822c_dac_iq_offset`, and `rtw8822c_dac_cal_iq_sample`.

My immediate concern, given these types of changes, is whether this introduces any uninitialized memory read vulnerabilities, particularly since it changes array data types, and alters the sorting logic.  The `iv` and `qv` arrays are allocated on the stack in `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];
```

They are then passed to `rtw8822c_dac_cal_iq_sample` for population:

```c
static void rtw8822c_dac_cal_iq_sample(struct rtw_dev *rtwdev, s32 *iv, s32 *qv)
{
	u32 temp;
	u32 i = 0, cnt = 0;

	while (i < DACK_SN_8822C && cnt < 10000) {
		cnt++;
		temp = rtw_read32_mask(rtwdev, 0x2dbc, 0x3fffff);
		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]))
			i++;
	}
}
```

The issue here is the `cnt < 10000` condition within the `while` loop. If this count hits 10000 before `i` reaches `DACK_SN_8822C`, the remaining elements of `iv` and `qv` will be uninitialized. Crucially, I have to check if this is *new* to the patch or was present before. Looks like it was there before, so the root cause of the problem is in a different commit.

However, the patch *does* change the sorting of these arrays. Previously, `rtw8822c_dac_iq_sort` used a custom sort function; now it uses `sort()`.  If `iv` and `qv` are only *partially* initialized (due to that `cnt < 10000` condition), then `sort()` will read uninitialized memory, which could lead to a crash or unexpected behavior. Note that this would have also been a problem with the old code, so the patch didn't introduce a regression.

Then, there's `rtw8822c_dac_iq_offset`:

```c
static s32 rtw8822c_dac_iq_offset(struct rtw_dev *rtwdev, s32 *vec)
{
	s32 sum = 0;

	for (u32 i = 10; i < DACK_SN_8822C - 10; i++)
		sum += vec[i];
...
```

This will also read uninitialized memory if the loop in `rtw8822c_dac_cal_iq_sample` didn't fully initialize `vec`.

The question now is the size of `D


50/3 2026/08/13 07:50 tool grepper
0m Args:
{
  "Expression": "#define DACK_SN_8822C"
}

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"
}

51/3 2026/08/13 07:50 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 8509
							output: 52
							thoughts: 3294
						

Thoughts:
**Analysis of DAC Calibration Patch and Potential Uninitialized Memory Issues**

Okay, let's break this down. We're dealing with a patch that touches DAC (Digital-to-Analog Converter) calibration code, specifically for the `rtw8822c` wireless driver. The core concern is uninitialized memory – something KMSAN (Kernel Memory Sanitizer) is designed to catch.

My initial thought is that `DACK_SN_8822C` is 100, and the `rtw8822c_dac_cal_iq_sample` function attempts to gather 100 valid samples, reading values into `iv` and `qv` arrays. If this process fails within 10000 iterations, those arrays could remain partially uninitialized. This is an existing flaw, not something *new* introduced by the patch. The patch changes the data type of the arrays from `u32` to `s32` and leverages standard `sort()` function, but doesn't *create* a new uninitialized memory risk.

The patch modifies the `rtw8822c_dac_cal_iq_search` function, which reads these arrays. If they are uninitialized, it constitutes an uninitialized memory read, but it's internal to the driver. This does not leak to userspace, it's used for DAC IQ calibration. Crucially, the code reads these values within the driver to determine DAC offset values, and write those into hardware registers. Using values derived from uninitialized memory is a bug, but not a kernel-to-user information leak.

The rules for `NeedsKMSAN` are clear: we only set it if the patch introduces or modifies code that depends on potentially uninitialized variables. This patch changes the logic and conditional branching, and also modifies how these arrays are read and processed, *even though the root issue of potential uninitialization existed before the patch*.

Now, the `rtw8822c_dac_cal_rf_mode` function is a concern. It *also* declares `iv` and `qv` arrays, *without* initialization. If `rtw8822c_dac_cal_iq_sample` fails, the arrays remain uninitialized, and the patch modifies the code that *reads* these arrays (e.g. now using `sort()` instead of a custom sorting method, and simplified min/max searches). KMSAN would be perfect to catch this if the arrays are uninitialized. The core question is: does the patch *introduce* the issue, or merely *modify* code that is already susceptible? The issue existed prior to the patch, so the patch isn't introducing this issue. However, the patch *modifies* this area. The patch changes the logic that *relies* on the potentially uninitialized values.

The `rtw8822c_dac_cal_iq_search` function has a loop that tries to overwrite elements of the `iv` and `qv` arrays, so this also has to be analyzed. The important thing is that, if the loop does *not* write values to the arrays, the arrays could still contain uninitialized values. The patch is changing how they are processed.

KASAN (Kernel Address Sanitizer) isn't relevant here; we're not dealing with out-of-bounds accesses. KMSAN, however, is on point: if the array isn't fully initialized, using uninitialized memory in `sort()` or other functions will be flagged. Since the patch modifies *these exact functions*, and changes the datatypes, it's relevant to a KMSAN run. It's not a new *risk* being introduced, but the *existing* risk is being refactored.

A further note, both the old and the new versions of the code read `vec[i]` or `iv[i]`. So, the patch has changed how the values are used, rather than how the data is handled.

The conclusion then comes down to the question: does the patch *expose* the uninitialized memory issue more clearly? While the patch doesn't *create* it, the changes might make the uninitialized memory usage more prominent or change the behavior when uninitialized memory is present. The old code had a manual processing, where the new code uses standard calls. This suggests it's not worth a full KMSAN run, because the same logic existed before, only the implementation has been refactored.

In sum, it seems that there is no new allocation, or new uninitialized memory risk introduced. The arrays `iv` and `qv` were present before, and the patch does not change how they are populated. Therefore, even though the data processing logic changes, a dedicated KMSAN run is probably not justified as the patch does not *introduce* uninitialized memory risks


52/3 2026/08/13 07:51 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/realtek/rtw88/rtw8822c.c",
  "FirstLine": 350,
  "LineCount": 100
}

Results:
{
  "Contents": " 350:\t\tcase RF_PATH_B:\n 351:\t\t\tpath_sel = 0x80000;\n 352:\t\t\tbreak;\n 353:\t\tdefault:\n 354:\t\t\tWARN_ON(1);\n 355:\t\t\treturn;\n 356:\t\t}\n 357:\t\n 358:\t\t/* ADCK step1 */\n 359:\t\trtw_write32_mask(rtwdev, base_addr + 0x30, BIT(30), 0x0);\n 360:\t\tif (path == RF_PATH_B)\n 361:\t\t\trtw_write32(rtwdev, base_addr + 0x30, 0x30db8041);\n 362:\t\trtw_write32(rtwdev, base_addr + 0x60, 0xf0040ff0);\n 363:\t\trtw_write32(rtwdev, base_addr + 0x0c, 0xdff00220);\n 364:\t\trtw_write32(rtwdev, base_addr + 0x10, 0x02dd08c4);\n 365:\t\trtw_write32(rtwdev, base_addr + 0x0c, 0x10000260);\n 366:\t\trtw_write_rf(rtwdev, RF_PATH_A, 0x0, RFREG_MASK, 0x10000);\n 367:\t\trtw_write_rf(rtwdev, RF_PATH_B, 0x0, RFREG_MASK, 0x10000);\n 368:\t\tfor (i = 0; i \u003c 10; i++) {\n 369:\t\t\trtw_dbg(rtwdev, RTW_DBG_RFK, \"[DACK] ADCK count=%d\\n\", i);\n 370:\t\t\trtw_write32(rtwdev, 0x1c3c, path_sel + 0x8003);\n 371:\t\t\trtw_write32(rtwdev, 0x1c24, 0x00010002);\n 372:\t\t\trtw8822c_dac_cal_rf_mode(rtwdev, \u0026ic, \u0026qc);\n 373:\t\t\trtw_dbg(rtwdev, RTW_DBG_RFK,\n 374:\t\t\t\t\"[DACK] before: i=0x%x, q=0x%x\\n\", ic, qc);\n 375:\t\n 376:\t\t\t/* compensation value */\n 377:\t\t\tif (ic != 0x0) {\n 378:\t\t\t\tic = 0x400 - ic;\n 379:\t\t\t\t*adc_ic = ic;\n 380:\t\t\t}\n 381:\t\t\tif (qc != 0x0) {\n 382:\t\t\t\tqc = 0x400 - qc;\n 383:\t\t\t\t*adc_qc = qc;\n 384:\t\t\t}\n 385:\t\t\ttemp = (ic \u0026 0x3ff) | ((qc \u0026 0x3ff) \u003c\u003c 10);\n 386:\t\t\trtw_write32(rtwdev, base_addr + 0x68, temp);\n 387:\t\t\tdm_info-\u003edack_adck[path] = temp;\n 388:\t\t\trtw_dbg(rtwdev, RTW_DBG_RFK, \"[DACK] ADCK 0x%08x=0x08%x\\n\",\n 389:\t\t\t\tbase_addr + 0x68, temp);\n 390:\t\t\t/* check ADC DC offset */\n 391:\t\t\trtw_write32(rtwdev, 0x1c3c, path_sel + 0x8103);\n 392:\t\t\trtw8822c_dac_cal_rf_mode(rtwdev, \u0026ic, \u0026qc);\n 393:\t\t\trtw_dbg(rtwdev, RTW_DBG_RFK,\n 394:\t\t\t\t\"[DACK] after:  i=0x%08x, q=0x%08x\\n\", ic, qc);\n 395:\t\t\tif (ic \u003e= 0x200)\n 396:\t\t\t\tic = 0x400 - ic;\n 397:\t\t\tif (qc \u003e= 0x200)\n 398:\t\t\t\tqc = 0x400 - qc;\n 399:\t\t\tif (ic \u003c 5 \u0026\u0026 qc \u003c 5)\n 400:\t\t\t\tbreak;\n 401:\t\t}\n 402:\t\n 403:\t\t/* ADCK step2 */\n 404:\t\trtw_write32(rtwdev, 0x1c3c, 0x00000003);\n 405:\t\trtw_write32(rtwdev, base_addr + 0x0c, 0x10000260);\n 406:\t\trtw_write32(rtwdev, base_addr + 0x10, 0x02d508c4);\n 407:\t\n 408:\t\t/* release pull low switch on IQ path */\n 409:\t\trtw_write_rf(rtwdev, path, 0x8f, BIT(13), 0x1);\n 410:\t}\n 411:\t\n 412:\tstatic void rtw8822c_dac_cal_step1(struct rtw_dev *rtwdev, u8 path)\n 413:\t{\n 414:\t\tstruct rtw_dm_info *dm_info = \u0026rtwdev-\u003edm_info;\n 415:\t\tu32 base_addr;\n 416:\t\tu32 read_addr;\n 417:\t\n 418:\t\tbase_addr = rtw8822c_get_path_write_addr(path);\n 419:\t\tread_addr = rtw8822c_get_path_read_addr(path);\n 420:\t\n 421:\t\trtw_write32(rtwdev, base_addr + 0x68, dm_info-\u003edack_adck[path]);\n 422:\t\trtw_write32(rtwdev, base_addr + 0x0c, 0xdff00220);\n 423:\t\tif (path == RF_PATH_A) {\n 424:\t\t\trtw_write32(rtwdev, base_addr + 0x60, 0xf0040ff0);\n 425:\t\t\trtw_write32(rtwdev, 0x1c38, 0xffffffff);\n 426:\t\t}\n 427:\t\trtw_write32(rtwdev, base_addr + 0x10, 0x02d508c5);\n 428:\t\trtw_write32(rtwdev, 0x9b4, 0xdb66db00);\n 429:\t\trtw_write32(rtwdev, base_addr + 0xb0, 0x0a11fb88);\n 430:\t\trtw_write32(rtwdev, base_addr + 0xbc, 0x0008ff81);\n 431:\t\trtw_write32(rtwdev, base_addr + 0xc0, 0x0003d208);\n 432:\t\trtw_write32(rtwdev, base_addr + 0xcc, 0x0a11fb88);\n 433:\t\trtw_write32(rtwdev, base_addr + 0xd8, 0x0008ff81);\n 434:\t\trtw_write32(rtwdev, base_addr + 0xdc, 0x0003d208);\n 435:\t\trtw_write32(rtwdev, base_addr + 0xb8, 0x60000000);\n 436:\t\tmdelay(2);\n 437:\t\trtw_write32(rtwdev, base_addr + 0xbc, 0x000aff8d);\n 438:\t\tmdelay(2);\n 439:\t\trtw_write32(rtwdev, base_addr + 0xb0, 0x0a11fb89);\n 440:\t\trtw_write32(rtwdev, base_addr + 0xcc, 0x0a11fb89);\n 441:\t\tmdelay(1);\n 442:\t\trtw_write32(rtwdev, base_addr + 0xb8, 0x62000000);\n 443:\t\trtw_write32(rtwdev, base_addr + 0xd4, 0x62000000);\n 444:\t\tmdelay(20);\n 445:\t\tif (!check_hw_ready(rtwdev, read_addr + 0x08, 0x7fff80, 0xffff) ||\n 446:\t\t    !check_hw_ready(rtwdev, read_addr + 0x34, 0x7fff80, 0xffff))\n 447:\t\t\trtw_err(rtwdev, \"failed to wait for dack ready\\n\");\n 448:\t\trtw_write32(rtwdev, base_addr + 0xb8, 0x02000000);\n 449:\t\tmdelay(1);\n"
}

53/3 2026/08/13 07:51 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 15405
							output: 52
							thoughts: 32
						

Thoughts:
Here's my attempt at summarizing the thought process, tailored for an expert audience:

**Analyzing the Calibration Routine**

Okay, hold on a second. I need to get back into that calibration routine, specifically `rtw8822c_dac_cal_rf_mode`. Wasn't that function call around line 300, give or take? I'm trying to recall the exact flow of the calibration process, and that particular function is crucial for understanding how the RF mode is set during the DAC calibration phase. I need to refresh my memory on that section before I go any further in my analysis. It's the lynchpin for understanding the interaction between the DAC and RF components at that stage.



54/3 2026/08/13 07:51 tool read-file
0m Args:
{
  "File": "drivers/net/wireless/realtek/rtw88/rtw8822c.c",
  "FirstLine": 250,
  "LineCount": 100
}

Results:
{
  "Contents": " 250:\tstatic void rtw8822c_dac_cal_iq_search(struct rtw_dev *rtwdev,\n 251:\t\t\t\t\t       s32 *iv, s32 *qv,\n 252:\t\t\t\t\t       u32 *i_value, u32 *q_value)\n 253:\t{\n 254:\t\ts32 i_max = 0, q_max = 0, i_min = 0, q_min = 0;\n 255:\t\tu32 temp;\n 256:\t\tu32 i, cnt = 0;\n 257:\t\n 258:\t\tdo {\n 259:\t\t\ti_min = iv[0];\n 260:\t\t\ti_max = iv[0];\n 261:\t\t\tq_min = qv[0];\n 262:\t\t\tq_max = qv[0];\n 263:\t\t\tfor (i = 0; i \u003c DACK_SN_8822C; i++) {\n 264:\t\t\t\tif (iv[i] \u003c i_min)\n 265:\t\t\t\t\ti_min = iv[i];\n 266:\t\t\t\tif (iv[i] \u003e i_max)\n 267:\t\t\t\t\ti_max = iv[i];\n 268:\t\t\t\tif (qv[i] \u003c q_min)\n 269:\t\t\t\t\tq_min = qv[i];\n 270:\t\t\t\tif (qv[i] \u003e q_max)\n 271:\t\t\t\t\tq_max = qv[i];\n 272:\t\t\t}\n 273:\t\n 274:\t\t\tu32 i_delta = (u32)(i_max - i_min);\n 275:\t\t\tu32 q_delta = (u32)(q_max - q_min);\n 276:\t\n 277:\t\t\trtw_dbg(rtwdev, RTW_DBG_RFK,\n 278:\t\t\t\t\"[DACK] i: min=0x%08x, max=0x%08x, delta=0x%08x\\n\",\n 279:\t\t\t\ti_min, i_max, i_delta);\n 280:\t\t\trtw_dbg(rtwdev, RTW_DBG_RFK,\n 281:\t\t\t\t\"[DACK] q: min=0x%08x, max=0x%08x, delta=0x%08x\\n\",\n 282:\t\t\t\tq_min, q_max, q_delta);\n 283:\t\n 284:\t\t\trtw8822c_dac_iq_sort(rtwdev, iv, qv);\n 285:\t\n 286:\t\t\tif (i_delta \u003e 5 || q_delta \u003e 5) {\n 287:\t\t\t\ttemp = rtw_read32_mask(rtwdev, 0x2dbc, 0x3fffff);\n 288:\t\t\t\tiv[0] = sign_extend32((temp \u0026 0x3ff000) \u003e\u003e 12, 9);\n 289:\t\t\t\tqv[0] = sign_extend32(temp \u0026 0x3ff, 9);\n 290:\t\t\t\ttemp = rtw_read32_mask(rtwdev, 0x2dbc, 0x3fffff);\n 291:\t\t\t\tiv[DACK_SN_8822C - 1] = sign_extend32((temp \u0026 0x3ff000) \u003e\u003e 12, 9);\n 292:\t\t\t\tqv[DACK_SN_8822C - 1] = sign_extend32(temp \u0026 0x3ff, 9);\n 293:\t\t\t} else {\n 294:\t\t\t\tbreak;\n 295:\t\t\t}\n 296:\t\t} while (cnt++ \u003c 100);\n 297:\t\n 298:\t\t*i_value = rtw8822c_dac_iq_offset(rtwdev, iv);\n 299:\t\t*q_value = rtw8822c_dac_iq_offset(rtwdev, qv);\n 300:\t}\n 301:\t\n 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"
}

55/3 2026/08/13 07:51 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 17909
							output: 238
							thoughts: 1435
						

Thoughts:
**KMSAN Assessment of DAC IQ Calibration Patch**

Okay, let's break this down. I'm looking at a patch that's refactoring the DAC IQ calibration logic in the rtw88 driver. Specifically, it changes the type of the `iv` and `qv` arrays, which are used to store calibration samples, from `u32` to `s32`. It also swaps out custom sorting and min/max functions with standard kernel functions (`sort()`, and a simplified loop).

My initial thought is, are we introducing a KMSAN risk here? Let's go through the prompt's criteria. It's a refactoring, so I have to be extremely careful.

First, I recall these `iv` and `qv` arrays are uninitialized stack arrays initially. The `rtw8822c_dac_cal_iq_sample` function reads data into them from hardware, but it has a counter (`cnt`) to prevent an infinite loop. If the hardware doesn't provide enough data, the arrays might be partially uninitialized. This is a potential risk that exists regardless of this patch.

The patch modifies *how* those arrays are processed, specifically the sorting and arithmetic logic. The `sort()` function and the replacement loop are new. This means *modifying* conditional logic and branching that depends on the contents of these arrays. I need to be sure the modified logic doesn't amplify the uninitialized state.

My immediate instinct is, "Yes, we should KMSAN this! The patch changes the logic that *operates* on potentially uninitialized data." But is it *introducing* an uninitialized memory risk? Let me think through the implications. The patch doesn't change how we *populate* the arrays (the `rtw8822c_dac_cal_iq_sample` function), only how we handle them *afterward*. The underlying issue, the risk of uninitialized data, was present before this patch.

I check the prompt again, "You must ONLY set NeedsKMSAN=true if the code changes introduce or expose UNINITIALIZED MEMORY risks that are detected ONLY by KMSAN."

So, is KMSAN the *only* tool that will find this potential issue? If the arrays are *fully* initialized in practice, KMSAN won't catch anything. If they're not fully initialized, KMSAN *would* find the bug, but it is a pre-existing issue. The patch doesn't make it better or worse (except perhaps making the code cleaner).

Does the patch *expose* the uninitialized memory to a new part of the code? Does `sort()` or the new arithmetic functions behave in a way that *causes* a new problem in the uninitialized state? No. The new `sort()` is just a comparison. The new logic does not depend on the specific initial values of the array. It is purely mathematical manipulation.

I re-examine the code, stepping through all the changes:
- Check `rtw8822c_dac_cal_iq_search`. It's just a loop with a comparison; fundamentally the same logic as before.
- Check `rtw8822c_dac_iq_offset`. No uninitialized memory concerns here either, since it is a simple loop.

Therefore, this patch is refactoring. It does *not* introduce a new uninitialized memory risk, or expose an existing one in a way that would be uniquely detected by KMSAN. The uninitialized memory risk is a pre-existing condition, and this patch doesn't affect it.

I'll set `NeedsKMSAN=false`. Standard KASAN and other bug detectors should be sufficient. The arrays are internal to the driver and not leaked to user space. It is a local stack buffer and the patch is a mathematical refactoring.



56/3 2026/08/13 07:51 tool set-results
0m Args:
{
  "KMSANReasoning": "The patch refactors the DAC IQ calibration logic in the rtw88 wireless driver, changing the data types of the `iv` and `qv` arrays from `u32` to `s32` and replacing custom sorting and min/max functions with standard kernel functions (`sort()`, `sign_extend32()`). The arrays `iv` and `qv` are allocated on the stack and populated by reading hardware registers in a loop. While there is a pre-existing theoretical risk that these arrays might not be fully initialized if the hardware fails to provide enough valid samples within a timeout, this patch does not introduce or exacerbate this risk. It merely changes the arithmetic operations performed on the data. Furthermore, these arrays are used strictly internally for hardware calibration and do not leak to userspace. Since no new uninitialized memory risks or info-leaks are introduced, a dedicated KMSAN fuzzing session is not justified. Standard KASAN and other bug detectors are sufficient to catch any out-of-bounds or memory corruption issues.",
  "NeedsKMSAN": false
}

Results:
{
  "KMSANReasoning": "The patch refactors the DAC IQ calibration logic in the rtw88 wireless driver, changing the data types of the `iv` and `qv` arrays from `u32` to `s32` and replacing custom sorting and min/max functions with standard kernel functions (`sort()`, `sign_extend32()`). The arrays `iv` and `qv` are allocated on the stack and populated by reading hardware registers in a loop. While there is a pre-existing theoretical risk that these arrays might not be fully initialized if the hardware fails to provide enough valid samples within a timeout, this patch does not introduce or exacerbate this risk. It merely changes the arithmetic operations performed on the data. Furthermore, these arrays are used strictly internally for hardware calibration and do not leak to userspace. Since no new uninitialized memory risks or info-leaks are introduced, a dedicated KMSAN fuzzing session is not justified. Standard KASAN and other bug detectors are sufficient to catch any out-of-bounds or memory corruption issues.",
  "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)