| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/06/28 23:20 | flow | patch-triage |
0mArgs:null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch modifies the Atheros ag71xx Ethernet MAC driver, which is a platform driver for on-chip hardware found in specific MIPS SoCs (AR7xxx/AR9xxx). This hardware is not emulated in standard virtualized environments (like GCE or generic QEMU) used for fuzzing. Even if the driver is compiled via COMPILE_TEST, the lack of a corresponding platform device and emulated MMIO/DMA hardware makes the modified code paths unreachable and unfuzzable.",
"WorthFuzzing": false
} |
| 1/1 | 2026/06/28 23:20 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 75022eb23cef1206e95cd58b739d19014edea2da\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Sun Jun 28 23:20:11 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/drivers/net/ethernet/atheros/ag71xx.c b/drivers/net/ethernet/atheros/ag71xx.c\nindex 4e4794c4dfdcea..a78be51a01cc4b 100644\n--- a/drivers/net/ethernet/atheros/ag71xx.c\n+++ b/drivers/net/ethernet/atheros/ag71xx.c\n@@ -40,11 +40,6 @@\n #include \u003clinux/io.h\u003e\n #include \u003cnet/selftests.h\u003e\n \n-/* For our NAPI weight bigger does *NOT* mean better - it means more\n- * D-cache misses and lots more wasted cycles than we'll ever\n- * possibly gain from saving instructions.\n- */\n-#define AG71XX_NAPI_WEIGHT\t32\n #define AG71XX_OOM_REFILL\t(1 + HZ / 10)\n \n #define AG71XX_INT_ERR\t(AG71XX_INT_RX_BE | AG71XX_INT_TX_BE)\n@@ -402,11 +397,13 @@ static bool ag71xx_is(struct ag71xx *ag, enum ag71xx_type type)\n \treturn ag-\u003edcfg-\u003etype == type;\n }\n \n+/* ath79 on-chip MMIO bus is non-posted - iowrite32/iowrite32be completes\n+ * before the next instruction executes. No read-back drain is needed.\n+ */\n+\n static void ag71xx_wr(struct ag71xx *ag, unsigned int reg, u32 value)\n {\n \tiowrite32(value, ag-\u003emac_base + reg);\n-\t/* flush write */\n-\t(void)ioread32(ag-\u003emac_base + reg);\n }\n \n static u32 ag71xx_rr(struct ag71xx *ag, unsigned int reg)\n@@ -416,22 +413,16 @@ static u32 ag71xx_rr(struct ag71xx *ag, unsigned int reg)\n \n static void ag71xx_sb(struct ag71xx *ag, unsigned int reg, u32 mask)\n {\n-\tvoid __iomem *r;\n+\tvoid __iomem *r = ag-\u003emac_base + reg;\n \n-\tr = ag-\u003emac_base + reg;\n \tiowrite32(ioread32(r) | mask, r);\n-\t/* flush write */\n-\t(void)ioread32(r);\n }\n \n static void ag71xx_cb(struct ag71xx *ag, unsigned int reg, u32 mask)\n {\n-\tvoid __iomem *r;\n+\tvoid __iomem *r = ag-\u003emac_base + reg;\n \n-\tr = ag-\u003emac_base + reg;\n \tiowrite32(ioread32(r) \u0026 ~mask, r);\n-\t/* flush write */\n-\t(void)ioread32(r);\n }\n \n static void ag71xx_int_enable(struct ag71xx *ag, u32 ints)\n@@ -1729,6 +1720,7 @@ static int ag71xx_poll(struct napi_struct *napi, int limit)\n \n \tmod_timer(\u0026ag-\u003eoom_timer, jiffies + AG71XX_OOM_REFILL);\n \tnapi_complete(napi);\n+\tag71xx_int_enable(ag, AG71XX_INT_TX);\n \treturn 0;\n }\n \n@@ -1913,8 +1905,7 @@ static int ag71xx_probe(struct platform_device *pdev)\n \t\treturn err;\n \t}\n \n-\tnetif_napi_add_weight(ndev, \u0026ag-\u003enapi, ag71xx_poll,\n-\t\t\t AG71XX_NAPI_WEIGHT);\n+\tnetif_napi_add(ndev, \u0026ag-\u003enapi, ag71xx_poll);\n \n \tag71xx_wr(ag, AG71XX_REG_MAC_CFG1, 0);\n \n"
} |
| 2/1 | 2026/06/28 23:20 | agent | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch modifies the Atheros ag71xx Ethernet MAC driver, which is a platform driver for on-chip hardware found in specific MIPS SoCs (AR7xxx/AR9xxx). This hardware is not emulated in standard virtualized environments (like GCE or generic QEMU) used for fuzzing. Even if the driver is compiled via COMPILE_TEST, the lack of a corresponding platform device and emulated MMIO/DMA hardware makes the modified code paths unreachable and unfuzzable.",
"WorthFuzzing": false
}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). 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. 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. Do not list too generic configs (we already have them enabled). Only list those that specifically cover the modified code. 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 75022eb23cef1206e95cd58b739d19014edea2da
Author: syz-cluster <triage@syzkaller.com>
Date: Sun Jun 28 23:20:11 2026 +0000
syz-cluster: applied patch under review
diff --git a/drivers/net/ethernet/atheros/ag71xx.c b/drivers/net/ethernet/atheros/ag71xx.c
index 4e4794c4dfdcea..a78be51a01cc4b 100644
--- a/drivers/net/ethernet/atheros/ag71xx.c
+++ b/drivers/net/ethernet/atheros/ag71xx.c
@@ -40,11 +40,6 @@
#include <linux/io.h>
#include <net/selftests.h>
-/* For our NAPI weight bigger does *NOT* mean better - it means more
- * D-cache misses and lots more wasted cycles than we'll ever
- * possibly gain from saving instructions.
- */
-#define AG71XX_NAPI_WEIGHT 32
#define AG71XX_OOM_REFILL (1 + HZ / 10)
#define AG71XX_INT_ERR (AG71XX_INT_RX_BE | AG71XX_INT_TX_BE)
@@ -402,11 +397,13 @@ static bool ag71xx_is(struct ag71xx *ag, enum ag71xx_type type)
return ag->dcfg->type == type;
}
+/* ath79 on-chip MMIO bus is non-posted - iowrite32/iowrite32be completes
+ * before the next instruction executes. No read-back drain is needed.
+ */
+
static void ag71xx_wr(struct ag71xx *ag, unsigned int reg, u32 value)
{
iowrite32(value, ag->mac_base + reg);
- /* flush write */
- (void)ioread32(ag->mac_base + reg);
}
static u32 ag71xx_rr(struct ag71xx *ag, unsigned int reg)
@@ -416,22 +413,16 @@ static u32 ag71xx_rr(struct ag71xx *ag, unsigned int reg)
static void ag71xx_sb(struct ag71xx *ag, unsigned int reg, u32 mask)
{
- void __iomem *r;
+ void __iomem *r = ag->mac_base + reg;
- r = ag->mac_base + reg;
iowrite32(ioread32(r) | mask, r);
- /* flush write */
- (void)ioread32(r);
}
static void ag71xx_cb(struct ag71xx *ag, unsigned int reg, u32 mask)
{
- void __iomem *r;
+ void __iomem *r = ag->mac_base + reg;
- r = ag->mac_base + reg;
iowrite32(ioread32(r) & ~mask, r);
- /* flush write */
- (void)ioread32(r);
}
static void ag71xx_int_enable(struct ag71xx *ag, u32 ints)
@@ -1729,6 +1720,7 @@ static int ag71xx_poll(struct napi_struct *napi, int limit)
mod_timer(&ag->oom_timer, jiffies + AG71XX_OOM_REFILL);
napi_complete(napi);
+ ag71xx_int_enable(ag, AG71XX_INT_TX);
return 0;
}
@@ -1913,8 +1905,7 @@ static int ag71xx_probe(struct platform_device *pdev)
return err;
}
- netif_napi_add_weight(ndev, &ag->napi, ag71xx_poll,
- AG71XX_NAPI_WEIGHT);
+ netif_napi_add(ndev, &ag->napi, ag71xx_poll);
ag71xx_wr(ag, AG71XX_REG_MAC_CFG1, 0);
|
| 3/2 | 2026/06/28 23:20 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 2677 output: 37 thoughts: 284 Thoughts: **Analyzing the AG71XX Ethernet Driver Patch** Okay, so I'm looking at this patch for `drivers/net/ethernet/atheros/ag71xx.c`. Seems straightforward enough on the surface. First, they've cleaned up some napi-related code, removing `AG71XX_NAPI_WEIGHT` and opting for `netif_napi_add` which is standard practice now. Good. They've also gotten rid of the read-back drains in those write functions – `ag71xx_wr`, `ag71xx_sb`, `ag71xx_cb`. Probably an optimization, less busy-waiting. And finally, they've added an interrupt enable for TX in `ag71xx_poll`, which is likely about optimizing interrupt handling. Fine, I get the changes. Now, this is an Atheros driver. It's built for those older SoCs: AR71xx, AR724x, AR913x, the whole gang, right through the QCA series. It's a built-in Ethernet MAC, so this is going to be platform-specific, very tightly coupled to the hardware. That's what I'm concerned about. My immediate question is: will it even be *reachable* in a virtualized environment? I doubt it. This isn't a generic NIC driver; it's a direct interface to on-chip hardware. Let's confirm it's using the `platform_device` infrastructure. Yup, it is. As I suspected. Can we emulate this easily? Absolutely not, it's not a standard NIC, it's a specific MAC. We'd have to emulate the entire Atheros SoC! That's a huge undertaking. Alright, let's see what the Kconfig file in the `drivers/net/ethernet/atheros/` directory says about its dependencies. Gotta check for any subtle build options that might influence this. |
| 4/2 | 2026/06/28 23:20 | tool | grepper |
0mArgs:{
"Expression": "config AG71XX",
"PathPrefix": "drivers/net/ethernet/atheros/Kconfig"
}Results: {
"Output": "drivers/net/ethernet/atheros/Kconfig=18=if NET_VENDOR_ATHEROS\ndrivers/net/ethernet/atheros/Kconfig-19-\ndrivers/net/ethernet/atheros/Kconfig:20:config AG71XX\ndrivers/net/ethernet/atheros/Kconfig-21-\ttristate \"Atheros AR7XXX/AR9XXX built-in ethernet mac support\"\n"
} |
| 5/2 | 2026/06/28 23:20 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 3532 output: 39 thoughts: 24 Thoughts: Here's my analysis of the provided text, rendered as a first-person thought process: **Diving into the Atheros Ethernet Kconfig** Okay, let's get down to brass tacks. I need to get a better handle on the Atheros Ethernet driver configuration, so my focus is now on the `drivers/net/ethernet/atheros/Kconfig` file, specifically around line 20. I'm going to have to understand how the Kconfig structure is implemented to see what options are being made available. I'm expecting to see dependencies, default settings, and maybe some help text that will illuminate the relevant configuration parameters. Hopefully, the file is well-commented. I'll be looking for clues on how the driver handles various Atheros Ethernet chipsets, what features are configurable (like VLAN support, jumbo frames, power management, etc.), and how all of this is structured within the overall network stack. The goal here is to get a solid grasp of what settings I can tweak and what their implications are. |
| 6/2 | 2026/06/28 23:20 | tool | read-file |
0mArgs:{
"File": "drivers/net/ethernet/atheros/Kconfig",
"FirstLine": 18,
"LineCount": 20
}Results: {
"Contents": " 18:\tif NET_VENDOR_ATHEROS\n 19:\t\n 20:\tconfig AG71XX\n 21:\t\ttristate \"Atheros AR7XXX/AR9XXX built-in ethernet mac support\"\n 22:\t\tdepends on ATH79 || COMPILE_TEST\n 23:\t\tselect PHYLINK\n 24:\t\timply NET_SELFTESTS\n 25:\t\thelp\n 26:\t\t If you wish to compile a kernel for AR7XXX/91XXX and enable\n 27:\t\t ethernet support, then you should always answer Y to this.\n 28:\t\n 29:\tconfig ATL2\n 30:\t\ttristate \"Atheros L2 Fast Ethernet support\"\n 31:\t\tdepends on PCI\n 32:\t\tselect CRC32\n 33:\t\tselect MII\n 34:\t\thelp\n 35:\t\t This driver supports the Atheros L2 fast ethernet adapter.\n 36:\t\n 37:\t\t To compile this driver as a module, choose M here. The module\n"
} |
| 7/2 | 2026/06/28 23:20 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 4089 output: 26 thoughts: 299 Thoughts: **Fuzzing the `ag71xx` Driver: A Thought Process** Okay, so I'm looking at this `ag71xx` driver, and immediately my mind goes to the conditional compilation: is it `ATH79` or `COMPILE_TEST`? That will dictate a lot. Can I even fuzz this thing in QEMU? I'm pretty sure `ATH79` is MIPS, and while QEMU *does* support MIPS, syzkaller primarily focuses on x86_64 or arm64. Even if I can get it to compile on x86_64 with `COMPILE_TEST`, it's a *platform* driver. Platform drivers are a headache. Platform drivers mean I need a platform device registered, usually through Device Tree or some custom board code. Does syzkaller have a way to handle this automatically? I know it *can* instantiate certain platform devices using things like `syz_dev_create`, but that's typically for pseudo-devices or ones that are explicitly supported. Not a random SoC driver, generally. Wait, I take that back; it *can* inject platform devices if it knows how, but usually it doesn't unless there's a fuzzer specifically for it. Then I remember those `syz_genetlink_get_family_id` etc. calls in syzkaller. Maybe there's a way. But the real question is: is `ag71xx` *reachable*? Because, let's be honest, hardware-specific platform drivers, especially for MIPS SoCs, are rarely reachable in standard x86_64 VMs. The platform device is just never registered. So, the next step is to see if there are any kernel references to `ag71xx` that would register it on x86. |
| 8/2 | 2026/06/28 23:20 | tool | grepper |
0mError:no matches Args: {
"Expression": "ag71xx",
"PathPrefix": "arch/"
}Results: {
"error": "no matches"
} |
| 9/2 | 2026/06/28 23:20 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 4822 output: 26 thoughts: 15 Thoughts: Okay, here's my take on those thoughts, tailored for an expert audience: **Kernel Source Navigation - Where's the Code?** Right, so I'm looking for something specific. No hits in `arch/`, which is as expected, given the nature of the task at hand. That narrows things down a bit, doesn't it? My next logical step is to delve into `drivers/`. It's a vast directory, but typically where I find the bulk of the device drivers and hardware-specific interaction code. Time to start digging there and see if I can unearth what I'm looking for within that structure. Let's see what treasure I can uncover there. |
| 10/2 | 2026/06/28 23:20 | tool | grepper |
0mArgs:{
"Expression": "ag71xx",
"PathPrefix": "drivers/"
}Results: {
"Output": "\nFull output is too long, showing 500 out of 995 lines.\nUse more precise expression if possible.\n\ndrivers/net/ethernet/atheros/Makefile-5-\ndrivers/net/ethernet/atheros/Makefile:6:obj-$(CONFIG_AG71XX) += ag71xx.o\ndrivers/net/ethernet/atheros/Makefile-7-obj-$(CONFIG_ATL1) += atlx/\n--\ndrivers/net/ethernet/atheros/ag71xx.c-232-\ndrivers/net/ethernet/atheros/ag71xx.c:233:struct ag71xx_statistic {\ndrivers/net/ethernet/atheros/ag71xx.c-234-\tunsigned short offset;\n--\ndrivers/net/ethernet/atheros/ag71xx.c-238-\ndrivers/net/ethernet/atheros/ag71xx.c:239:static const struct ag71xx_statistic ag71xx_statistics[] = {\ndrivers/net/ethernet/atheros/ag71xx.c-240-\t{ 0x0080, GENMASK(17, 0), \"Tx/Rx 64 Byte\", },\n--\ndrivers/net/ethernet/atheros/ag71xx.c-288-#define DESC_PKTLEN_M\t\t0xfff\ndrivers/net/ethernet/atheros/ag71xx.c:289:struct ag71xx_desc {\ndrivers/net/ethernet/atheros/ag71xx.c-290-\tu32 data;\n--\ndrivers/net/ethernet/atheros/ag71xx.c-295-\ndrivers/net/ethernet/atheros/ag71xx.c:296:#define AG71XX_DESC_SIZE\troundup(sizeof(struct ag71xx_desc), \\\ndrivers/net/ethernet/atheros/ag71xx.c-297-\t\t\t\t\tL1_CACHE_BYTES)\ndrivers/net/ethernet/atheros/ag71xx.c-298-\ndrivers/net/ethernet/atheros/ag71xx.c:299:struct ag71xx_buf {\ndrivers/net/ethernet/atheros/ag71xx.c-300-\tunion {\n--\ndrivers/net/ethernet/atheros/ag71xx.c-311-\ndrivers/net/ethernet/atheros/ag71xx.c:312:struct ag71xx_ring {\ndrivers/net/ethernet/atheros/ag71xx.c-313-\t/* \"Hot\" fields in the data path. */\n--\ndrivers/net/ethernet/atheros/ag71xx.c-317-\t/* \"Cold\" fields - not used in the data path. */\ndrivers/net/ethernet/atheros/ag71xx.c:318:\tstruct ag71xx_buf *buf;\ndrivers/net/ethernet/atheros/ag71xx.c-319-\tu16 order;\n--\ndrivers/net/ethernet/atheros/ag71xx.c-324-\ndrivers/net/ethernet/atheros/ag71xx.c:325:enum ag71xx_type {\ndrivers/net/ethernet/atheros/ag71xx.c-326-\tAR7100,\n--\ndrivers/net/ethernet/atheros/ag71xx.c-334-\ndrivers/net/ethernet/atheros/ag71xx.c:335:struct ag71xx_dcfg {\ndrivers/net/ethernet/atheros/ag71xx.c-336-\tu32 max_frame_len;\n--\ndrivers/net/ethernet/atheros/ag71xx.c-339-\tbool tx_hang_workaround;\ndrivers/net/ethernet/atheros/ag71xx.c:340:\tenum ag71xx_type type;\ndrivers/net/ethernet/atheros/ag71xx.c-341-};\ndrivers/net/ethernet/atheros/ag71xx.c-342-\ndrivers/net/ethernet/atheros/ag71xx.c:343:struct ag71xx {\ndrivers/net/ethernet/atheros/ag71xx.c-344-\t/* Critical data related to the per-packet data path are clustered\n--\ndrivers/net/ethernet/atheros/ag71xx.c-346-\t */\ndrivers/net/ethernet/atheros/ag71xx.c:347:\tstruct ag71xx_ring rx_ring ____cacheline_aligned;\ndrivers/net/ethernet/atheros/ag71xx.c:348:\tstruct ag71xx_ring tx_ring ____cacheline_aligned;\ndrivers/net/ethernet/atheros/ag71xx.c-349-\n--\ndrivers/net/ethernet/atheros/ag71xx.c-356-\tu32 msg_enable;\ndrivers/net/ethernet/atheros/ag71xx.c:357:\tconst struct ag71xx_dcfg *dcfg;\ndrivers/net/ethernet/atheros/ag71xx.c-358-\n--\ndrivers/net/ethernet/atheros/ag71xx.c-361-\ndrivers/net/ethernet/atheros/ag71xx.c:362:\tstruct ag71xx_desc *stop_desc;\ndrivers/net/ethernet/atheros/ag71xx.c-363-\tdma_addr_t stop_desc_dma;\n--\ndrivers/net/ethernet/atheros/ag71xx.c-379-\ndrivers/net/ethernet/atheros/ag71xx.c:380:static int ag71xx_desc_empty(struct ag71xx_desc *desc)\ndrivers/net/ethernet/atheros/ag71xx.c-381-{\n--\ndrivers/net/ethernet/atheros/ag71xx.c-384-\ndrivers/net/ethernet/atheros/ag71xx.c:385:static struct ag71xx_desc *ag71xx_ring_desc(struct ag71xx_ring *ring, int idx)\ndrivers/net/ethernet/atheros/ag71xx.c-386-{\ndrivers/net/ethernet/atheros/ag71xx.c:387:\treturn (struct ag71xx_desc *)\u0026ring-\u003edescs_cpu[idx * AG71XX_DESC_SIZE];\ndrivers/net/ethernet/atheros/ag71xx.c-388-}\ndrivers/net/ethernet/atheros/ag71xx.c-389-\ndrivers/net/ethernet/atheros/ag71xx.c:390:static int ag71xx_ring_size_order(int size)\ndrivers/net/ethernet/atheros/ag71xx.c-391-{\n--\ndrivers/net/ethernet/atheros/ag71xx.c-394-\ndrivers/net/ethernet/atheros/ag71xx.c:395:static bool ag71xx_is(struct ag71xx *ag, enum ag71xx_type type)\ndrivers/net/ethernet/atheros/ag71xx.c-396-{\n--\ndrivers/net/ethernet/atheros/ag71xx.c-403-\ndrivers/net/ethernet/atheros/ag71xx.c:404:static void ag71xx_wr(struct ag71xx *ag, unsigned int reg, u32 value)\ndrivers/net/ethernet/atheros/ag71xx.c-405-{\n--\ndrivers/net/ethernet/atheros/ag71xx.c-408-\ndrivers/net/ethernet/atheros/ag71xx.c:409:static u32 ag71xx_rr(struct ag71xx *ag, unsigned int reg)\ndrivers/net/ethernet/atheros/ag71xx.c-410-{\n--\ndrivers/net/ethernet/atheros/ag71xx.c-413-\ndrivers/net/ethernet/atheros/ag71xx.c:414:static void ag71xx_sb(struct ag71xx *ag, unsigned int reg, u32 mask)\ndrivers/net/ethernet/atheros/ag71xx.c-415-{\n--\ndrivers/net/ethernet/atheros/ag71xx.c-420-\ndrivers/net/ethernet/atheros/ag71xx.c:421:static void ag71xx_cb(struct ag71xx *ag, unsigned int reg, u32 mask)\ndrivers/net/ethernet/atheros/ag71xx.c-422-{\n--\ndrivers/net/ethernet/atheros/ag71xx.c-427-\ndrivers/net/ethernet/atheros/ag71xx.c:428:static void ag71xx_int_enable(struct ag71xx *ag, u32 ints)\ndrivers/net/ethernet/atheros/ag71xx.c-429-{\ndrivers/net/ethernet/atheros/ag71xx.c:430:\tag71xx_sb(ag, AG71XX_REG_INT_ENABLE, ints);\ndrivers/net/ethernet/atheros/ag71xx.c-431-}\ndrivers/net/ethernet/atheros/ag71xx.c-432-\ndrivers/net/ethernet/atheros/ag71xx.c:433:static void ag71xx_int_disable(struct ag71xx *ag, u32 ints)\ndrivers/net/ethernet/atheros/ag71xx.c-434-{\ndrivers/net/ethernet/atheros/ag71xx.c:435:\tag71xx_cb(ag, AG71XX_REG_INT_ENABLE, ints);\ndrivers/net/ethernet/atheros/ag71xx.c-436-}\ndrivers/net/ethernet/atheros/ag71xx.c-437-\ndrivers/net/ethernet/atheros/ag71xx.c:438:static int ag71xx_do_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd)\ndrivers/net/ethernet/atheros/ag71xx.c-439-{\ndrivers/net/ethernet/atheros/ag71xx.c:440:\tstruct ag71xx *ag = netdev_priv(ndev);\ndrivers/net/ethernet/atheros/ag71xx.c-441-\n--\ndrivers/net/ethernet/atheros/ag71xx.c-444-\ndrivers/net/ethernet/atheros/ag71xx.c:445:static void ag71xx_get_drvinfo(struct net_device *ndev,\ndrivers/net/ethernet/atheros/ag71xx.c-446-\t\t\t struct ethtool_drvinfo *info)\ndrivers/net/ethernet/atheros/ag71xx.c-447-{\ndrivers/net/ethernet/atheros/ag71xx.c:448:\tstruct ag71xx *ag = netdev_priv(ndev);\ndrivers/net/ethernet/atheros/ag71xx.c-449-\ndrivers/net/ethernet/atheros/ag71xx.c:450:\tstrscpy(info-\u003edriver, \"ag71xx\", sizeof(info-\u003edriver));\ndrivers/net/ethernet/atheros/ag71xx.c-451-\tstrscpy(info-\u003ebus_info, of_node_full_name(ag-\u003epdev-\u003edev.of_node),\n--\ndrivers/net/ethernet/atheros/ag71xx.c-454-\ndrivers/net/ethernet/atheros/ag71xx.c:455:static int ag71xx_get_link_ksettings(struct net_device *ndev,\ndrivers/net/ethernet/atheros/ag71xx.c-456-\t\t\t\t struct ethtool_link_ksettings *kset)\ndrivers/net/ethernet/atheros/ag71xx.c-457-{\ndrivers/net/ethernet/atheros/ag71xx.c:458:\tstruct ag71xx *ag = netdev_priv(ndev);\ndrivers/net/ethernet/atheros/ag71xx.c-459-\n--\ndrivers/net/ethernet/atheros/ag71xx.c-462-\ndrivers/net/ethernet/atheros/ag71xx.c:463:static int ag71xx_set_link_ksettings(struct net_device *ndev,\ndrivers/net/ethernet/atheros/ag71xx.c-464-\t\t\t\t const struct ethtool_link_ksettings *kset)\ndrivers/net/ethernet/atheros/ag71xx.c-465-{\ndrivers/net/ethernet/atheros/ag71xx.c:466:\tstruct ag71xx *ag = netdev_priv(ndev);\ndrivers/net/ethernet/atheros/ag71xx.c-467-\n--\ndrivers/net/ethernet/atheros/ag71xx.c-470-\ndrivers/net/ethernet/atheros/ag71xx.c:471:static int ag71xx_ethtool_nway_reset(struct net_device *ndev)\ndrivers/net/ethernet/atheros/ag71xx.c-472-{\ndrivers/net/ethernet/atheros/ag71xx.c:473:\tstruct ag71xx *ag = netdev_priv(ndev);\ndrivers/net/ethernet/atheros/ag71xx.c-474-\n--\ndrivers/net/ethernet/atheros/ag71xx.c-477-\ndrivers/net/ethernet/atheros/ag71xx.c:478:static void ag71xx_ethtool_get_pauseparam(struct net_device *ndev,\ndrivers/net/ethernet/atheros/ag71xx.c-479-\t\t\t\t\t struct ethtool_pauseparam *pause)\ndrivers/net/ethernet/atheros/ag71xx.c-480-{\ndrivers/net/ethernet/atheros/ag71xx.c:481:\tstruct ag71xx *ag = netdev_priv(ndev);\ndrivers/net/ethernet/atheros/ag71xx.c-482-\n--\ndrivers/net/ethernet/atheros/ag71xx.c-485-\ndrivers/net/ethernet/atheros/ag71xx.c:486:static int ag71xx_ethtool_set_pauseparam(struct net_device *ndev,\ndrivers/net/ethernet/atheros/ag71xx.c-487-\t\t\t\t\t struct ethtool_pauseparam *pause)\ndrivers/net/ethernet/atheros/ag71xx.c-488-{\ndrivers/net/ethernet/atheros/ag71xx.c:489:\tstruct ag71xx *ag = netdev_priv(ndev);\ndrivers/net/ethernet/atheros/ag71xx.c-490-\n--\ndrivers/net/ethernet/atheros/ag71xx.c-493-\ndrivers/net/ethernet/atheros/ag71xx.c:494:static void ag71xx_ethtool_get_strings(struct net_device *netdev, u32 sset,\ndrivers/net/ethernet/atheros/ag71xx.c-495-\t\t\t\t u8 *data)\n--\ndrivers/net/ethernet/atheros/ag71xx.c-500-\tcase ETH_SS_STATS:\ndrivers/net/ethernet/atheros/ag71xx.c:501:\t\tfor (i = 0; i \u003c ARRAY_SIZE(ag71xx_statistics); i++)\ndrivers/net/ethernet/atheros/ag71xx.c:502:\t\t\tethtool_puts(\u0026data, ag71xx_statistics[i].name);\ndrivers/net/ethernet/atheros/ag71xx.c-503-\t\tbreak;\n--\ndrivers/net/ethernet/atheros/ag71xx.c-509-\ndrivers/net/ethernet/atheros/ag71xx.c:510:static void ag71xx_ethtool_get_stats(struct net_device *ndev,\ndrivers/net/ethernet/atheros/ag71xx.c-511-\t\t\t\t struct ethtool_stats *stats, u64 *data)\ndrivers/net/ethernet/atheros/ag71xx.c-512-{\ndrivers/net/ethernet/atheros/ag71xx.c:513:\tstruct ag71xx *ag = netdev_priv(ndev);\ndrivers/net/ethernet/atheros/ag71xx.c-514-\tint i;\ndrivers/net/ethernet/atheros/ag71xx.c-515-\ndrivers/net/ethernet/atheros/ag71xx.c:516:\tfor (i = 0; i \u003c ARRAY_SIZE(ag71xx_statistics); i++)\ndrivers/net/ethernet/atheros/ag71xx.c:517:\t\t*data++ = ag71xx_rr(ag, ag71xx_statistics[i].offset)\ndrivers/net/ethernet/atheros/ag71xx.c:518:\t\t\t\t\u0026 ag71xx_statistics[i].mask;\ndrivers/net/ethernet/atheros/ag71xx.c-519-}\ndrivers/net/ethernet/atheros/ag71xx.c-520-\ndrivers/net/ethernet/atheros/ag71xx.c:521:static int ag71xx_ethtool_get_sset_count(struct net_device *ndev, int sset)\ndrivers/net/ethernet/atheros/ag71xx.c-522-{\n--\ndrivers/net/ethernet/atheros/ag71xx.c-524-\tcase ETH_SS_STATS:\ndrivers/net/ethernet/atheros/ag71xx.c:525:\t\treturn ARRAY_SIZE(ag71xx_statistics);\ndrivers/net/ethernet/atheros/ag71xx.c-526-\tcase ETH_SS_TEST:\n--\ndrivers/net/ethernet/atheros/ag71xx.c-532-\ndrivers/net/ethernet/atheros/ag71xx.c:533:static const struct ethtool_ops ag71xx_ethtool_ops = {\ndrivers/net/ethernet/atheros/ag71xx.c:534:\t.get_drvinfo\t\t\t= ag71xx_get_drvinfo,\ndrivers/net/ethernet/atheros/ag71xx.c-535-\t.get_link\t\t\t= ethtool_op_get_link,\ndrivers/net/ethernet/atheros/ag71xx.c-536-\t.get_ts_info\t\t\t= ethtool_op_get_ts_info,\ndrivers/net/ethernet/atheros/ag71xx.c:537:\t.get_link_ksettings\t\t= ag71xx_get_link_ksettings,\ndrivers/net/ethernet/atheros/ag71xx.c:538:\t.set_link_ksettings\t\t= ag71xx_set_link_ksettings,\ndrivers/net/ethernet/atheros/ag71xx.c:539:\t.nway_reset\t\t\t= ag71xx_ethtool_nway_reset,\ndrivers/net/ethernet/atheros/ag71xx.c:540:\t.get_pauseparam\t\t\t= ag71xx_ethtool_get_pauseparam,\ndrivers/net/ethernet/atheros/ag71xx.c:541:\t.set_pauseparam\t\t\t= ag71xx_ethtool_set_pauseparam,\ndrivers/net/ethernet/atheros/ag71xx.c:542:\t.get_strings\t\t\t= ag71xx_ethtool_get_strings,\ndrivers/net/ethernet/atheros/ag71xx.c:543:\t.get_ethtool_stats\t\t= ag71xx_ethtool_get_stats,\ndrivers/net/ethernet/atheros/ag71xx.c:544:\t.get_sset_count\t\t\t= ag71xx_ethtool_get_sset_count,\ndrivers/net/ethernet/atheros/ag71xx.c-545-\t.self_test\t\t\t= net_selftest,\n--\ndrivers/net/ethernet/atheros/ag71xx.c-547-\ndrivers/net/ethernet/atheros/ag71xx.c:548:static int ag71xx_mdio_wait_busy(struct ag71xx *ag)\ndrivers/net/ethernet/atheros/ag71xx.c-549-{\n--\ndrivers/net/ethernet/atheros/ag71xx.c-557-\ndrivers/net/ethernet/atheros/ag71xx.c:558:\t\tbusy = ag71xx_rr(ag, AG71XX_REG_MII_IND);\ndrivers/net/ethernet/atheros/ag71xx.c-559-\t\tif (!busy)\n--\ndrivers/net/ethernet/atheros/ag71xx.c-569-\ndrivers/net/ethernet/atheros/ag71xx.c:570:static int ag71xx_mdio_mii_read(struct mii_bus *bus, int addr, int reg)\ndrivers/net/ethernet/atheros/ag71xx.c-571-{\ndrivers/net/ethernet/atheros/ag71xx.c:572:\tstruct ag71xx *ag = bus-\u003epriv;\ndrivers/net/ethernet/atheros/ag71xx.c-573-\tint err, val;\ndrivers/net/ethernet/atheros/ag71xx.c-574-\ndrivers/net/ethernet/atheros/ag71xx.c:575:\terr = ag71xx_mdio_wait_busy(ag);\ndrivers/net/ethernet/atheros/ag71xx.c-576-\tif (err)\n--\ndrivers/net/ethernet/atheros/ag71xx.c-578-\ndrivers/net/ethernet/atheros/ag71xx.c:579:\tag71xx_wr(ag, AG71XX_REG_MII_ADDR,\ndrivers/net/ethernet/atheros/ag71xx.c-580-\t\t ((addr \u0026 0x1f) \u003c\u003c MII_ADDR_SHIFT) | (reg \u0026 0xff));\ndrivers/net/ethernet/atheros/ag71xx.c-581-\t/* enable read mode */\ndrivers/net/ethernet/atheros/ag71xx.c:582:\tag71xx_wr(ag, AG71XX_REG_MII_CMD, MII_CMD_READ);\ndrivers/net/ethernet/atheros/ag71xx.c-583-\ndrivers/net/ethernet/atheros/ag71xx.c:584:\terr = ag71xx_mdio_wait_busy(ag);\ndrivers/net/ethernet/atheros/ag71xx.c-585-\tif (err)\n--\ndrivers/net/ethernet/atheros/ag71xx.c-587-\ndrivers/net/ethernet/atheros/ag71xx.c:588:\tval = ag71xx_rr(ag, AG71XX_REG_MII_STATUS);\ndrivers/net/ethernet/atheros/ag71xx.c-589-\t/* disable read mode */\ndrivers/net/ethernet/atheros/ag71xx.c:590:\tag71xx_wr(ag, AG71XX_REG_MII_CMD, 0);\ndrivers/net/ethernet/atheros/ag71xx.c-591-\n--\ndrivers/net/ethernet/atheros/ag71xx.c-597-\ndrivers/net/ethernet/atheros/ag71xx.c:598:static int ag71xx_mdio_mii_write(struct mii_bus *bus, int addr, int reg,\ndrivers/net/ethernet/atheros/ag71xx.c-599-\t\t\t\t u16 val)\ndrivers/net/ethernet/atheros/ag71xx.c-600-{\ndrivers/net/ethernet/atheros/ag71xx.c:601:\tstruct ag71xx *ag = bus-\u003epriv;\ndrivers/net/ethernet/atheros/ag71xx.c-602-\n--\ndrivers/net/ethernet/atheros/ag71xx.c-605-\ndrivers/net/ethernet/atheros/ag71xx.c:606:\tag71xx_wr(ag, AG71XX_REG_MII_ADDR,\ndrivers/net/ethernet/atheros/ag71xx.c-607-\t\t ((addr \u0026 0x1f) \u003c\u003c MII_ADDR_SHIFT) | (reg \u0026 0xff));\ndrivers/net/ethernet/atheros/ag71xx.c:608:\tag71xx_wr(ag, AG71XX_REG_MII_CTRL, val);\ndrivers/net/ethernet/atheros/ag71xx.c-609-\ndrivers/net/ethernet/atheros/ag71xx.c:610:\treturn ag71xx_mdio_wait_busy(ag);\ndrivers/net/ethernet/atheros/ag71xx.c-611-}\n--\ndrivers/net/ethernet/atheros/ag71xx.c=621=static const u32 ar933x_mdio_div_table[] = {\n--\ndrivers/net/ethernet/atheros/ag71xx.c-624-\ndrivers/net/ethernet/atheros/ag71xx.c:625:static int ag71xx_mdio_get_divider(struct ag71xx *ag, u32 *div)\ndrivers/net/ethernet/atheros/ag71xx.c-626-{\n--\ndrivers/net/ethernet/atheros/ag71xx.c-634-\ndrivers/net/ethernet/atheros/ag71xx.c:635:\tif (ag71xx_is(ag, AR9330) || ag71xx_is(ag, AR9340)) {\ndrivers/net/ethernet/atheros/ag71xx.c-636-\t\ttable = ar933x_mdio_div_table;\ndrivers/net/ethernet/atheros/ag71xx.c-637-\t\tndivs = ARRAY_SIZE(ar933x_mdio_div_table);\ndrivers/net/ethernet/atheros/ag71xx.c:638:\t} else if (ag71xx_is(ag, AR7240)) {\ndrivers/net/ethernet/atheros/ag71xx.c-639-\t\ttable = ar7240_mdio_div_table;\n--\ndrivers/net/ethernet/atheros/ag71xx.c-658-\ndrivers/net/ethernet/atheros/ag71xx.c:659:static int ag71xx_mdio_reset(struct mii_bus *bus)\ndrivers/net/ethernet/atheros/ag71xx.c-660-{\ndrivers/net/ethernet/atheros/ag71xx.c:661:\tstruct ag71xx *ag = bus-\u003epriv;\ndrivers/net/ethernet/atheros/ag71xx.c-662-\tint err;\n--\ndrivers/net/ethernet/atheros/ag71xx.c-664-\ndrivers/net/ethernet/atheros/ag71xx.c:665:\terr = ag71xx_mdio_get_divider(ag, \u0026t);\ndrivers/net/ethernet/atheros/ag71xx.c-666-\tif (err)\n--\ndrivers/net/ethernet/atheros/ag71xx.c-668-\ndrivers/net/ethernet/atheros/ag71xx.c:669:\tag71xx_wr(ag, AG71XX_REG_MII_CFG, t | MII_CFG_RESET);\ndrivers/net/ethernet/atheros/ag71xx.c-670-\tusleep_range(100, 200);\ndrivers/net/ethernet/atheros/ag71xx.c-671-\ndrivers/net/ethernet/atheros/ag71xx.c:672:\tag71xx_wr(ag, AG71XX_REG_MII_CFG, t);\ndrivers/net/ethernet/atheros/ag71xx.c-673-\tusleep_range(100, 200);\n--\ndrivers/net/ethernet/atheros/ag71xx.c-677-\ndrivers/net/ethernet/atheros/ag71xx.c:678:static int ag71xx_mdio_probe(struct ag71xx *ag)\ndrivers/net/ethernet/atheros/ag71xx.c-679-{\n--\ndrivers/net/ethernet/atheros/ag71xx.c-704-\ndrivers/net/ethernet/atheros/ag71xx.c:705:\tmii_bus-\u003ename = \"ag71xx_mdio\";\ndrivers/net/ethernet/atheros/ag71xx.c:706:\tmii_bus-\u003eread = ag71xx_mdio_mii_read;\ndrivers/net/ethernet/atheros/ag71xx.c:707:\tmii_bus-\u003ewrite = ag71xx_mdio_mii_write;\ndrivers/net/ethernet/atheros/ag71xx.c:708:\tmii_bus-\u003ereset = ag71xx_mdio_reset;\ndrivers/net/ethernet/atheros/ag71xx.c-709-\tmii_bus-\u003epriv = ag;\n--\ndrivers/net/ethernet/atheros/ag71xx.c-726-\ndrivers/net/ethernet/atheros/ag71xx.c:727:static void ag71xx_hw_stop(struct ag71xx *ag)\ndrivers/net/ethernet/atheros/ag71xx.c-728-{\ndrivers/net/ethernet/atheros/ag71xx.c-729-\t/* disable all interrupts and stop the rx/tx engine */\ndrivers/net/ethernet/atheros/ag71xx.c:730:\tag71xx_wr(ag, AG71XX_REG_INT_ENABLE, 0);\ndrivers/net/ethernet/atheros/ag71xx.c:731:\tag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0);\ndrivers/net/ethernet/atheros/ag71xx.c:732:\tag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0);\ndrivers/net/ethernet/atheros/ag71xx.c-733-}\ndrivers/net/ethernet/atheros/ag71xx.c-734-\ndrivers/net/ethernet/atheros/ag71xx.c:735:static bool ag71xx_check_dma_stuck(struct ag71xx *ag)\ndrivers/net/ethernet/atheros/ag71xx.c-736-{\n--\ndrivers/net/ethernet/atheros/ag71xx.c-746-\ndrivers/net/ethernet/atheros/ag71xx.c:747:\trx_sm = ag71xx_rr(ag, AG71XX_REG_RX_SM);\ndrivers/net/ethernet/atheros/ag71xx.c-748-\tif ((rx_sm \u0026 0x7) == 0x3 \u0026\u0026 ((rx_sm \u003e\u003e 4) \u0026 0x7) == 0x6)\n--\ndrivers/net/ethernet/atheros/ag71xx.c-750-\ndrivers/net/ethernet/atheros/ag71xx.c:751:\ttx_sm = ag71xx_rr(ag, AG71XX_REG_TX_SM);\ndrivers/net/ethernet/atheros/ag71xx.c:752:\trx_fd = ag71xx_rr(ag, AG71XX_REG_FIFO_DEPTH);\ndrivers/net/ethernet/atheros/ag71xx.c-753-\tif (((tx_sm \u003e\u003e 4) \u0026 0x7) == 0 \u0026\u0026 ((rx_sm \u0026 0x7) == 0) \u0026\u0026\n--\ndrivers/net/ethernet/atheros/ag71xx.c-759-\ndrivers/net/ethernet/atheros/ag71xx.c:760:static int ag71xx_tx_packets(struct ag71xx *ag, bool flush, int budget)\ndrivers/net/ethernet/atheros/ag71xx.c-761-{\ndrivers/net/ethernet/atheros/ag71xx.c:762:\tstruct ag71xx_ring *ring = \u0026ag-\u003etx_ring;\ndrivers/net/ethernet/atheros/ag71xx.c-763-\tint sent = 0, bytes_compl = 0, n = 0;\n--\ndrivers/net/ethernet/atheros/ag71xx.c-773-\twhile (ring-\u003edirty + n != ring-\u003ecurr) {\ndrivers/net/ethernet/atheros/ag71xx.c:774:\t\tstruct ag71xx_desc *desc;\ndrivers/net/ethernet/atheros/ag71xx.c-775-\t\tstruct sk_buff *skb;\n--\ndrivers/net/ethernet/atheros/ag71xx.c-778-\t\ti = (ring-\u003edirty + n) \u0026 ring_mask;\ndrivers/net/ethernet/atheros/ag71xx.c:779:\t\tdesc = ag71xx_ring_desc(ring, i);\ndrivers/net/ethernet/atheros/ag71xx.c-780-\t\tskb = ring-\u003ebuf[i].tx.skb;\ndrivers/net/ethernet/atheros/ag71xx.c-781-\ndrivers/net/ethernet/atheros/ag71xx.c:782:\t\tif (!flush \u0026\u0026 !ag71xx_desc_empty(desc)) {\ndrivers/net/ethernet/atheros/ag71xx.c-783-\t\t\tif (ag-\u003edcfg-\u003etx_hang_workaround \u0026\u0026\ndrivers/net/ethernet/atheros/ag71xx.c:784:\t\t\t ag71xx_check_dma_stuck(ag)) {\ndrivers/net/ethernet/atheros/ag71xx.c-785-\t\t\t\tschedule_delayed_work(\u0026ag-\u003erestart_work,\n--\ndrivers/net/ethernet/atheros/ag71xx.c-807-\t\twhile (n \u003e 0) {\ndrivers/net/ethernet/atheros/ag71xx.c:808:\t\t\tag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS);\ndrivers/net/ethernet/atheros/ag71xx.c-809-\t\t\tn--;\n--\ndrivers/net/ethernet/atheros/ag71xx.c-830-\ndrivers/net/ethernet/atheros/ag71xx.c:831:static void ag71xx_dma_wait_stop(struct ag71xx *ag)\ndrivers/net/ethernet/atheros/ag71xx.c-832-{\n--\ndrivers/net/ethernet/atheros/ag71xx.c-840-\ndrivers/net/ethernet/atheros/ag71xx.c:841:\t\trx = ag71xx_rr(ag, AG71XX_REG_RX_CTRL) \u0026 RX_CTRL_RXE;\ndrivers/net/ethernet/atheros/ag71xx.c:842:\t\ttx = ag71xx_rr(ag, AG71XX_REG_TX_CTRL) \u0026 TX_CTRL_TXE;\ndrivers/net/ethernet/atheros/ag71xx.c-843-\t\tif (!rx \u0026\u0026 !tx)\n--\ndrivers/net/ethernet/atheros/ag71xx.c-849-\ndrivers/net/ethernet/atheros/ag71xx.c:850:static void ag71xx_dma_reset(struct ag71xx *ag)\ndrivers/net/ethernet/atheros/ag71xx.c-851-{\n--\ndrivers/net/ethernet/atheros/ag71xx.c-856-\t/* stop RX and TX */\ndrivers/net/ethernet/atheros/ag71xx.c:857:\tag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0);\ndrivers/net/ethernet/atheros/ag71xx.c:858:\tag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0);\ndrivers/net/ethernet/atheros/ag71xx.c-859-\n--\ndrivers/net/ethernet/atheros/ag71xx.c-862-\t */\ndrivers/net/ethernet/atheros/ag71xx.c:863:\tag71xx_dma_wait_stop(ag);\ndrivers/net/ethernet/atheros/ag71xx.c-864-\ndrivers/net/ethernet/atheros/ag71xx.c-865-\t/* clear descriptor addresses */\ndrivers/net/ethernet/atheros/ag71xx.c:866:\tag71xx_wr(ag, AG71XX_REG_TX_DESC, ag-\u003estop_desc_dma);\ndrivers/net/ethernet/atheros/ag71xx.c:867:\tag71xx_wr(ag, AG71XX_REG_RX_DESC, ag-\u003estop_desc_dma);\ndrivers/net/ethernet/atheros/ag71xx.c-868-\n--\ndrivers/net/ethernet/atheros/ag71xx.c-870-\tfor (i = 0; i \u003c 256; i++) {\ndrivers/net/ethernet/atheros/ag71xx.c:871:\t\tag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR);\ndrivers/net/ethernet/atheros/ag71xx.c:872:\t\tag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS);\ndrivers/net/ethernet/atheros/ag71xx.c-873-\t}\n--\ndrivers/net/ethernet/atheros/ag71xx.c-875-\t/* clear pending errors */\ndrivers/net/ethernet/atheros/ag71xx.c:876:\tag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_BE | RX_STATUS_OF);\ndrivers/net/ethernet/atheros/ag71xx.c:877:\tag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_BE | TX_STATUS_UR);\ndrivers/net/ethernet/atheros/ag71xx.c-878-\ndrivers/net/ethernet/atheros/ag71xx.c:879:\tval = ag71xx_rr(ag, AG71XX_REG_RX_STATUS);\ndrivers/net/ethernet/atheros/ag71xx.c-880-\tif (val)\n--\ndrivers/net/ethernet/atheros/ag71xx.c-883-\ndrivers/net/ethernet/atheros/ag71xx.c:884:\tval = ag71xx_rr(ag, AG71XX_REG_TX_STATUS);\ndrivers/net/ethernet/atheros/ag71xx.c-885-\n--\ndrivers/net/ethernet/atheros/ag71xx.c-893-\ndrivers/net/ethernet/atheros/ag71xx.c:894:static void ag71xx_hw_setup(struct ag71xx *ag)\ndrivers/net/ethernet/atheros/ag71xx.c-895-{\n--\ndrivers/net/ethernet/atheros/ag71xx.c-898-\t/* setup MAC configuration registers */\ndrivers/net/ethernet/atheros/ag71xx.c:899:\tag71xx_wr(ag, AG71XX_REG_MAC_CFG1, init);\ndrivers/net/ethernet/atheros/ag71xx.c-900-\ndrivers/net/ethernet/atheros/ag71xx.c:901:\tag71xx_sb(ag, AG71XX_REG_MAC_CFG2,\ndrivers/net/ethernet/atheros/ag71xx.c-902-\t\t MAC_CFG2_PAD_CRC_EN | MAC_CFG2_LEN_CHECK);\n--\ndrivers/net/ethernet/atheros/ag71xx.c-904-\t/* setup max frame length to zero */\ndrivers/net/ethernet/atheros/ag71xx.c:905:\tag71xx_wr(ag, AG71XX_REG_MAC_MFL, 0);\ndrivers/net/ethernet/atheros/ag71xx.c-906-\ndrivers/net/ethernet/atheros/ag71xx.c-907-\t/* setup FIFO configuration registers */\ndrivers/net/ethernet/atheros/ag71xx.c:908:\tag71xx_wr(ag, AG71XX_REG_FIFO_CFG0, FIFO_CFG0_INIT);\ndrivers/net/ethernet/atheros/ag71xx.c:909:\tag71xx_wr(ag, AG71XX_REG_FIFO_CFG1, ag-\u003efifodata[0]);\ndrivers/net/ethernet/atheros/ag71xx.c:910:\tag71xx_wr(ag, AG71XX_REG_FIFO_CFG2, ag-\u003efifodata[1]);\ndrivers/net/ethernet/atheros/ag71xx.c:911:\tag71xx_wr(ag, AG71XX_REG_FIFO_CFG4, FIFO_CFG4_INIT);\ndrivers/net/ethernet/atheros/ag71xx.c:912:\tag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, FIFO_CFG5_INIT);\ndrivers/net/ethernet/atheros/ag71xx.c-913-}\ndrivers/net/ethernet/atheros/ag71xx.c-914-\ndrivers/net/ethernet/atheros/ag71xx.c:915:static unsigned int ag71xx_max_frame_len(unsigned int mtu)\ndrivers/net/ethernet/atheros/ag71xx.c-916-{\n--\ndrivers/net/ethernet/atheros/ag71xx.c-919-\ndrivers/net/ethernet/atheros/ag71xx.c:920:static void ag71xx_hw_set_macaddr(struct ag71xx *ag, const unsigned char *mac)\ndrivers/net/ethernet/atheros/ag71xx.c-921-{\n--\ndrivers/net/ethernet/atheros/ag71xx.c-926-\ndrivers/net/ethernet/atheros/ag71xx.c:927:\tag71xx_wr(ag, AG71XX_REG_MAC_ADDR1, t);\ndrivers/net/ethernet/atheros/ag71xx.c-928-\ndrivers/net/ethernet/atheros/ag71xx.c-929-\tt = (((u32)mac[1]) \u003c\u003c 24) | (((u32)mac[0]) \u003c\u003c 16);\ndrivers/net/ethernet/atheros/ag71xx.c:930:\tag71xx_wr(ag, AG71XX_REG_MAC_ADDR2, t);\ndrivers/net/ethernet/atheros/ag71xx.c-931-}\ndrivers/net/ethernet/atheros/ag71xx.c-932-\ndrivers/net/ethernet/atheros/ag71xx.c:933:static void ag71xx_fast_reset(struct ag71xx *ag)\ndrivers/net/ethernet/atheros/ag71xx.c-934-{\n--\ndrivers/net/ethernet/atheros/ag71xx.c-938-\ndrivers/net/ethernet/atheros/ag71xx.c:939:\tag71xx_hw_stop(ag);\ndrivers/net/ethernet/atheros/ag71xx.c-940-\ndrivers/net/ethernet/atheros/ag71xx.c:941:\tmii_reg = ag71xx_rr(ag, AG71XX_REG_MII_CFG);\ndrivers/net/ethernet/atheros/ag71xx.c:942:\trx_ds = ag71xx_rr(ag, AG71XX_REG_RX_DESC);\ndrivers/net/ethernet/atheros/ag71xx.c-943-\ndrivers/net/ethernet/atheros/ag71xx.c:944:\tag71xx_tx_packets(ag, true, 0);\ndrivers/net/ethernet/atheros/ag71xx.c-945-\n--\ndrivers/net/ethernet/atheros/ag71xx.c-950-\ndrivers/net/ethernet/atheros/ag71xx.c:951:\tag71xx_dma_reset(ag);\ndrivers/net/ethernet/atheros/ag71xx.c:952:\tag71xx_hw_setup(ag);\ndrivers/net/ethernet/atheros/ag71xx.c-953-\tag-\u003etx_ring.curr = 0;\n--\ndrivers/net/ethernet/atheros/ag71xx.c-957-\t/* setup max frame length */\ndrivers/net/ethernet/atheros/ag71xx.c:958:\tag71xx_wr(ag, AG71XX_REG_MAC_MFL,\ndrivers/net/ethernet/atheros/ag71xx.c:959:\t\t ag71xx_max_frame_len(ag-\u003endev-\u003emtu));\ndrivers/net/ethernet/atheros/ag71xx.c-960-\ndrivers/net/ethernet/atheros/ag71xx.c:961:\tag71xx_wr(ag, AG71XX_REG_RX_DESC, rx_ds);\ndrivers/net/ethernet/atheros/ag71xx.c:962:\tag71xx_wr(ag, AG71XX_REG_TX_DESC, ag-\u003etx_ring.descs_dma);\ndrivers/net/ethernet/atheros/ag71xx.c:963:\tag71xx_wr(ag, AG71XX_REG_MII_CFG, mii_reg);\ndrivers/net/ethernet/atheros/ag71xx.c-964-\ndrivers/net/ethernet/atheros/ag71xx.c:965:\tag71xx_hw_set_macaddr(ag, dev-\u003edev_addr);\ndrivers/net/ethernet/atheros/ag71xx.c-966-}\ndrivers/net/ethernet/atheros/ag71xx.c-967-\ndrivers/net/ethernet/atheros/ag71xx.c:968:static void ag71xx_hw_start(struct ag71xx *ag)\ndrivers/net/ethernet/atheros/ag71xx.c-969-{\ndrivers/net/ethernet/atheros/ag71xx.c-970-\t/* start RX engine */\ndrivers/net/ethernet/atheros/ag71xx.c:971:\tag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE);\ndrivers/net/ethernet/atheros/ag71xx.c-972-\ndrivers/net/ethernet/atheros/ag71xx.c-973-\t/* enable interrupts */\ndrivers/net/ethernet/atheros/ag71xx.c:974:\tag71xx_wr(ag, AG71XX_REG_INT_ENABLE, AG71XX_INT_INIT);\ndrivers/net/ethernet/atheros/ag71xx.c-975-\n--\ndrivers/net/ethernet/atheros/ag71xx.c-978-\ndrivers/net/ethernet/atheros/ag71xx.c:979:static void ag71xx_mac_config(struct phylink_config *config, unsigned int mode,\ndrivers/net/ethernet/atheros/ag71xx.c-980-\t\t\t const struct phylink_link_state *state)\ndrivers/net/ethernet/atheros/ag71xx.c-981-{\ndrivers/net/ethernet/atheros/ag71xx.c:982:\tstruct ag71xx *ag = netdev_priv(to_net_dev(config-\u003edev));\ndrivers/net/ethernet/atheros/ag71xx.c-983-\n--\ndrivers/net/ethernet/atheros/ag71xx.c-986-\ndrivers/net/ethernet/atheros/ag71xx.c:987:\tif (!ag71xx_is(ag, AR7100) \u0026\u0026 !ag71xx_is(ag, AR9130))\ndrivers/net/ethernet/atheros/ag71xx.c:988:\t\tag71xx_fast_reset(ag);\ndrivers/net/ethernet/atheros/ag71xx.c-989-\n--\ndrivers/net/ethernet/atheros/ag71xx.c-994-\ndrivers/net/ethernet/atheros/ag71xx.c:995:\tag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, ag-\u003efifodata[2]);\ndrivers/net/ethernet/atheros/ag71xx.c-996-}\ndrivers/net/ethernet/atheros/ag71xx.c-997-\ndrivers/net/ethernet/atheros/ag71xx.c:998:static void ag71xx_mac_link_down(struct phylink_config *config,\ndrivers/net/ethernet/atheros/ag71xx.c-999-\t\t\t\t unsigned int mode, phy_interface_t interface)\ndrivers/net/ethernet/atheros/ag71xx.c-1000-{\ndrivers/net/ethernet/atheros/ag71xx.c:1001:\tstruct ag71xx *ag = netdev_priv(to_net_dev(config-\u003edev));\ndrivers/net/ethernet/atheros/ag71xx.c-1002-\ndrivers/net/ethernet/atheros/ag71xx.c:1003:\tag71xx_hw_stop(ag);\ndrivers/net/ethernet/atheros/ag71xx.c-1004-}\ndrivers/net/ethernet/atheros/ag71xx.c-1005-\ndrivers/net/ethernet/atheros/ag71xx.c:1006:static void ag71xx_mac_link_up(struct phylink_config *config,\ndrivers/net/ethernet/atheros/ag71xx.c-1007-\t\t\t struct phy_device *phy,\n--\ndrivers/net/ethernet/atheros/ag71xx.c-1011-{\ndrivers/net/ethernet/atheros/ag71xx.c:1012:\tstruct ag71xx *ag = netdev_priv(to_net_dev(config-\u003edev));\ndrivers/net/ethernet/atheros/ag71xx.c-1013-\tu32 cfg1, cfg2;\n--\ndrivers/net/ethernet/atheros/ag71xx.c-1016-\ndrivers/net/ethernet/atheros/ag71xx.c:1017:\tcfg2 = ag71xx_rr(ag, AG71XX_REG_MAC_CFG2);\ndrivers/net/ethernet/atheros/ag71xx.c-1018-\tcfg2 \u0026= ~(MAC_CFG2_IF_1000 | MAC_CFG2_IF_10_100 | MAC_CFG2_FDX);\n--\ndrivers/net/ethernet/atheros/ag71xx.c-1020-\ndrivers/net/ethernet/atheros/ag71xx.c:1021:\tifctl = ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL);\ndrivers/net/ethernet/atheros/ag71xx.c-1022-\tifctl \u0026= ~(MAC_IFCTL_SPEED);\ndrivers/net/ethernet/atheros/ag71xx.c-1023-\ndrivers/net/ethernet/atheros/ag71xx.c:1024:\tfifo5 = ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5);\ndrivers/net/ethernet/atheros/ag71xx.c-1025-\tfifo5 \u0026= ~FIFO_CFG5_BM;\n--\ndrivers/net/ethernet/atheros/ag71xx.c-1042-\ndrivers/net/ethernet/atheros/ag71xx.c:1043:\tag71xx_wr(ag, AG71XX_REG_MAC_CFG2, cfg2);\ndrivers/net/ethernet/atheros/ag71xx.c:1044:\tag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, fifo5);\ndrivers/net/ethernet/atheros/ag71xx.c:1045:\tag71xx_wr(ag, AG71XX_REG_MAC_IFCTL, ifctl);\ndrivers/net/ethernet/atheros/ag71xx.c-1046-\ndrivers/net/ethernet/atheros/ag71xx.c:1047:\tcfg1 = ag71xx_rr(ag, AG71XX_REG_MAC_CFG1);\ndrivers/net/ethernet/atheros/ag71xx.c-1048-\tcfg1 \u0026= ~(MAC_CFG1_TFC | MAC_CFG1_RFC);\n--\ndrivers/net/ethernet/atheros/ag71xx.c-1053-\t\tcfg1 |= MAC_CFG1_RFC;\ndrivers/net/ethernet/atheros/ag71xx.c:1054:\tag71xx_wr(ag, AG71XX_REG_MAC_CFG1, cfg1);\ndrivers/net/ethernet/atheros/ag71xx.c-1055-\ndrivers/net/ethernet/atheros/ag71xx.c:1056:\tag71xx_hw_start(ag);\ndrivers/net/ethernet/atheros/ag71xx.c-1057-}\ndrivers/net/ethernet/atheros/ag71xx.c-1058-\ndrivers/net/ethernet/atheros/ag71xx.c:1059:static const struct phylink_mac_ops ag71xx_phylink_mac_ops = {\ndrivers/net/ethernet/atheros/ag71xx.c:1060:\t.mac_config = ag71xx_mac_config,\ndrivers/net/ethernet/atheros/ag71xx.c:1061:\t.mac_link_down = ag71xx_mac_link_down,\ndrivers/net/ethernet/atheros/ag71xx.c:1062:\t.mac_link_up = ag71xx_mac_link_up,\n\n"
} |
| 11/2 | 2026/06/28 23:20 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 19405 output: 42 thoughts: 766 Thoughts: **Analyzing the Fuzzability of the ag71xx Platform Driver** Okay, so I'm looking at this `ag71xx_driver`. Seems straightforward; it's a standard platform driver. My initial thought is, can syzkaller fuzz this? The immediate answer is usually no, syzkaller doesn't typically just conjure up platform devices via device tree overlays without some specific setup. My brain jumps to whether there is some `syz_dev_create` equivalent, but nothing comes to mind, just the more specific syzkaller calls for USB, 802.11, etc. Platform drivers need to be *instantiated* to be fuzzed by syzkaller. If it’s a pseudo-device or we have a specific way to load DT overlays, then it won't be probed. But wait, the prompt reminds me about code that’s unreachable in virtualized environments. This driver is for an on-chip Ethernet MAC on Atheros MIPS SoCs. It's directly hitting MMIO registers, doing `iowrite32` and such. If we magically instantiated this, it would try to talk to physical memory addresses which, in a standard QEMU setup, would either crash or do nothing because that hardware isn't there. The question then is, does QEMU emulate the AR71xx SoC? And does syzkaller even *run* on MIPS? I know syzkaller *does* support MIPS. As for QEMU, I'm pretty sure it has a `malta` target and maybe a few other MIPS boards, but I doubt it has full-blown AR71xx support, at least not in a generic machine type. OpenWrt uses QEMU, but for specific Atheros boards. So, let's see if this thing is actually reachable. It’s an architecture-specific hardware driver, right? So unless we're running on that specific hardware, it's generally a dead end. But, the prompt also says that if it modifies *reachable* core kernel logic, drivers, or architectures, it's potentially worth fuzzing. Okay, is there a trigger? It's a platform driver, so it probes when a device with a "qca,ar7100-eth" compatible string (or similar) is present in the device tree. If we're on x86_64, it's a definite no-go. Even if we compile it with COMPILE_TEST on x86_64, the platform device will not be there, so `ag71xx_probe` would never be called. So, in standard virtualized environments, this code is unreachable. There is no software emulation for it, since it's hardware MAC. Let me just double-check the `ag71xx_match` table to be absolutely sure. |
| 12/2 | 2026/06/28 23:20 | tool | grepper |
0mArgs:{
"Expression": "ag71xx_match",
"PathPrefix": "drivers/net/ethernet/atheros/ag71xx.c"
}Results: {
"Output": "drivers/net/ethernet/atheros/ag71xx.c=1996=static const struct ag71xx_dcfg ag71xx_dcfg_qca9550 = {\n--\ndrivers/net/ethernet/atheros/ag71xx.c-2003-\ndrivers/net/ethernet/atheros/ag71xx.c:2004:static const struct of_device_id ag71xx_match[] = {\ndrivers/net/ethernet/atheros/ag71xx.c-2005-\t{ .compatible = \"qca,ar7100-eth\", .data = \u0026ag71xx_dcfg_ar7100 },\n--\ndrivers/net/ethernet/atheros/ag71xx.c-2016-};\ndrivers/net/ethernet/atheros/ag71xx.c:2017:MODULE_DEVICE_TABLE(of, ag71xx_match);\ndrivers/net/ethernet/atheros/ag71xx.c-2018-\ndrivers/net/ethernet/atheros/ag71xx.c=2019=static struct platform_driver ag71xx_driver = {\n--\ndrivers/net/ethernet/atheros/ag71xx.c-2022-\t\t.name\t= \"ag71xx\",\ndrivers/net/ethernet/atheros/ag71xx.c:2023:\t\t.of_match_table = ag71xx_match,\ndrivers/net/ethernet/atheros/ag71xx.c-2024-\t}\n"
} |
| 13/2 | 2026/06/28 23:20 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 21235 output: 135 thoughts: 424 Thoughts: **Unfuzzable Platform Driver** Okay, so this is a standard Open Firmware (OF) platform driver. Straight away, I can tell it's tied to a specific device tree node, something like "qca,ar7100-eth", and it's accessing physical MMIO registers – that's a huge red flag. It's not going to be fuzzable in a generic virtualized environment unless you have very specific hardware emulation, which QEMU *might* have, but Syzkaller typically doesn't even boot that specific machine type for general fuzzing, you know? Hmm, I wonder, what if Syzkaller tries to inject a platform device using `syz_dev_create` or something similar? Even *if* it could, this driver would immediately hit a wall. It would use `ioremap` on some random physical address and try to read or write it. If that physical address isn't actually backed by emulated hardware, it's either going to read all 0xFFs, and be useless, or it'll crash immediately and be unable to perform any meaningful network operations that require DMA or interrupts. So, from a functional perspective, this driver is not going to be fuzzable. Let me go back to the prompt, and see if I have a test. Ah, here it is: "Return WorthFuzzing=false if the patch only contains code paths that are impossible to reach in virtualized environments like GCE or QEMU, even when utilizing software-emulated hardware". Nailed it. This perfectly describes the situation. The driver is for the Atheros AR7xxx/AR9xxx on-chip Ethernet MACs. That hardware isn't emulated in the typical fuzzing environments. I'm returning `WorthFuzzing=false`. The reasoning is pretty solid: This patch modifies the Atheros ag71xx Ethernet MAC driver, which is a platform driver specifically for the on-chip hardware found in AR7xxx/AR9xxx MIPS SoCs. Since this hardware is not emulated in standard virtualized environments, and even if COMPILE_TEST compiles it, the absence of a corresponding platform device and emulated MMIO/DMA hardware makes the changed code paths entirely unreachable and unfuzzable. That's a definite "no go" for fuzzing. |
| 14/2 | 2026/06/28 23:20 | tool | set-results |
0mArgs:{
"EnableConfigs": [],
"FocusSymbols": [],
"Reasoning": "The patch modifies the Atheros ag71xx Ethernet MAC driver, which is a platform driver for on-chip hardware found in specific MIPS SoCs (AR7xxx/AR9xxx). This hardware is not emulated in standard virtualized environments (like GCE or generic QEMU) used for fuzzing. Even if the driver is compiled via COMPILE_TEST, the lack of a corresponding platform device and emulated MMIO/DMA hardware makes the modified code paths unreachable and unfuzzable.",
"WorthFuzzing": false
}Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch modifies the Atheros ag71xx Ethernet MAC driver, which is a platform driver for on-chip hardware found in specific MIPS SoCs (AR7xxx/AR9xxx). This hardware is not emulated in standard virtualized environments (like GCE or generic QEMU) used for fuzzing. Even if the driver is compiled via COMPILE_TEST, the lack of a corresponding platform device and emulated MMIO/DMA hardware makes the modified code paths unreachable and unfuzzable.",
"WorthFuzzing": false
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|