| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/07/21 07:03 | flow | patch-triage |
1mArgs:null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch modifies the Airoha ethernet driver (airoha_eth), which is a hardware-specific platform driver for Airoha SoCs. Since there is no software emulator for this hardware in the kernel or QEMU, the driver cannot successfully probe (it will fail on MMIO polling loops like read_poll_timeout), making the modified code paths unreachable in virtualized environments.",
"WorthFuzzing": false
} |
| 1/1 | 2026/07/21 07:03 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 6c35c0719ba87bb741b6077482eaece9759c9813\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Tue Jul 21 07:03:57 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c\nindex 59001fd4b6f740..fe2e2af67173e5 100644\n--- a/drivers/net/ethernet/airoha/airoha_eth.c\n+++ b/drivers/net/ethernet/airoha/airoha_eth.c\n@@ -934,7 +934,7 @@ static void airoha_qdma_wake_netdev_txqs(struct airoha_queue *q)\n \t\t\tif (!dev)\n \t\t\t\tcontinue;\n \n-\t\t\tif (dev-\u003eqdma != qdma)\n+\t\t\tif (rcu_access_pointer(dev-\u003eqdma) != qdma)\n \t\t\t\tcontinue;\n \n \t\t\tnetdev = netdev_from_priv(dev);\n@@ -1866,8 +1866,8 @@ static int airoha_dev_open(struct net_device *netdev)\n {\n \tstruct airoha_gdm_dev *dev = netdev_priv(netdev);\n \tstruct airoha_gdm_port *port = dev-\u003eport;\n-\tstruct airoha_qdma *qdma = dev-\u003eqdma;\n \tu32 pse_port = FE_PSE_PORT_PPE1;\n+\tstruct airoha_qdma *qdma;\n \tint err;\n \n \tnetif_tx_start_all_queues(netdev);\n@@ -1875,6 +1875,7 @@ static int airoha_dev_open(struct net_device *netdev)\n \tif (err)\n \t\treturn err;\n \n+\tqdma = airoha_qdma_deref(dev);\n \tif (netdev_uses_dsa(netdev))\n \t\tairoha_fe_set(qdma-\u003eeth, REG_GDM_INGRESS_CFG(port-\u003eid),\n \t\t\t GDM_STAG_EN_MASK);\n@@ -1898,7 +1899,6 @@ static int airoha_dev_stop(struct net_device *netdev)\n {\n \tstruct airoha_gdm_dev *dev = netdev_priv(netdev);\n \tstruct airoha_gdm_port *port = dev-\u003eport;\n-\tstruct airoha_qdma *qdma = dev-\u003eqdma;\n \n \tnetif_tx_disable(netdev);\n \tairoha_set_vip_for_gdm_port(dev, false);\n@@ -1906,7 +1906,7 @@ static int airoha_dev_stop(struct net_device *netdev)\n \tif (--port-\u003eusers)\n \t\tairoha_ppe_set_xmit_frame_size(dev);\n \telse\n-\t\tairoha_set_gdm_port_fwd_cfg(qdma-\u003eeth,\n+\t\tairoha_set_gdm_port_fwd_cfg(dev-\u003eeth,\n \t\t\t\t\t REG_GDM_FWD_CFG(port-\u003eid),\n \t\t\t\t\t FE_PSE_PORT_DROP);\n \treturn 0;\n@@ -1989,6 +1989,53 @@ static int airoha_enable_gdm2_loopback(struct airoha_gdm_dev *dev)\n \treturn 0;\n }\n \n+static int airoha_disable_gdm2_loopback(struct airoha_gdm_dev *dev)\n+{\n+\tstruct airoha_gdm_port *port = dev-\u003eport;\n+\tstruct airoha_eth *eth = dev-\u003eeth;\n+\tint i, src_port;\n+\tu32 pse_port;\n+\n+\tsrc_port = eth-\u003esoc-\u003eops.get_sport(dev-\u003eport, dev-\u003enbq);\n+\tif (src_port \u003c 0)\n+\t\treturn src_port;\n+\n+\tairoha_fe_clear(eth,\n+\t\t\tREG_SP_DFT_CPORT(src_port \u003e\u003e fls(SP_CPORT_DFT_MASK)),\n+\t\t\tSP_CPORT_MASK(src_port \u0026 SP_CPORT_DFT_MASK));\n+\n+\tairoha_fe_set(eth, REG_GDM_FWD_CFG(AIROHA_GDM2_IDX),\n+\t\t GDM_STRIP_CRC_MASK);\n+\tairoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(AIROHA_GDM2_IDX),\n+\t\t\t\t FE_PSE_PORT_DROP);\n+\tairoha_fe_clear(eth, REG_GDM_LPBK_CFG(AIROHA_GDM2_IDX),\n+\t\t\tLPBK_CHAN_MASK | LPBK_MODE_MASK | LPBK_EN_MASK);\n+\tpse_port = airoha_ppe_is_enabled(eth, 1) ? FE_PSE_PORT_PPE2\n+\t\t\t\t\t\t : FE_PSE_PORT_PPE1;\n+\tairoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(AIROHA_GDM2_IDX),\n+\t\t\t\t pse_port);\n+\n+\tairoha_fe_rmw(eth, REG_FE_WAN_PORT, WAN0_MASK,\n+\t\t FIELD_PREP(WAN0_MASK, AIROHA_GDM2_IDX));\n+\n+\tfor (i = 0; i \u003c eth-\u003esoc-\u003enum_ppe; i++)\n+\t\tairoha_fe_clear(eth, REG_PPE_DFT_CPORT(i, AIROHA_GDM2_IDX),\n+\t\t\t\tDFT_CPORT_MASK(AIROHA_GDM2_IDX));\n+\n+\t/* Enable VIP and IFC for GDM2 */\n+\tairoha_fe_set(eth, REG_FE_VIP_PORT_EN, BIT(AIROHA_GDM2_IDX));\n+\tairoha_fe_set(eth, REG_FE_IFC_PORT_EN, BIT(AIROHA_GDM2_IDX));\n+\n+\tif (port-\u003eid == AIROHA_GDM4_IDX \u0026\u0026 airoha_is_7581(eth)) {\n+\t\tu32 mask = FC_ID_OF_SRC_PORT_MASK(dev-\u003enbq);\n+\n+\t\tairoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6, mask,\n+\t\t\t FC_MAP6_DEF_VALUE \u0026 mask);\n+\t}\n+\n+\treturn 0;\n+}\n+\n static struct airoha_gdm_dev *\n airoha_get_wan_gdm_dev(struct airoha_eth *eth)\n {\n@@ -2015,15 +2062,35 @@ airoha_get_wan_gdm_dev(struct airoha_eth *eth)\n static void airoha_dev_set_qdma(struct airoha_gdm_dev *dev)\n {\n \tstruct net_device *netdev = netdev_from_priv(dev);\n+\tstruct airoha_qdma *cur_qdma, *qdma;\n \tstruct airoha_eth *eth = dev-\u003eeth;\n-\tint ppe_id;\n+\tint i, ppe_id;\n \n \t/* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */\n-\tdev-\u003eqdma = \u0026eth-\u003eqdma[!airoha_is_lan_gdm_dev(dev)];\n-\tnetdev-\u003eirq = dev-\u003eqdma-\u003eirq_banks[0].irq;\n+\tqdma = \u0026eth-\u003eqdma[!airoha_is_lan_gdm_dev(dev)];\n+\tcur_qdma = airoha_qdma_deref(dev);\n+\n+\trcu_assign_pointer(dev-\u003eqdma, qdma);\n+\tnetdev-\u003eirq = qdma-\u003eirq_banks[0].irq;\n \n \tppe_id = !airoha_is_lan_gdm_dev(dev) \u0026\u0026 airoha_ppe_is_enabled(eth, 1);\n \tairoha_ppe_set_cpu_port(dev, ppe_id, airoha_get_fe_port(dev));\n+\n+\tif (!cur_qdma)\n+\t\treturn;\n+\n+\t/* Seed qos_stats baselines with the new QDMA block's current\n+\t * counter values to avoid a spurious spike on the first stats\n+\t * query after migration.\n+\t */\n+\tfor (i = 0; i \u003c ARRAY_SIZE(dev-\u003eqos_stats); i++) {\n+\t\tdev-\u003eqos_stats[i].cpu_tx_packets =\n+\t\t\tairoha_qdma_rr(qdma, REG_CNTR_VAL(i \u003c\u003c 1));\n+\t\tdev-\u003eqos_stats[i].fwd_tx_packets =\n+\t\t\tairoha_qdma_rr(qdma, REG_CNTR_VAL((i \u003c\u003c 1) + 1));\n+\t}\n+\tsynchronize_rcu();\n+\tnetif_tx_wake_all_queues(netdev);\n }\n \n static int airoha_dev_init(struct net_device *netdev)\n@@ -2039,7 +2106,7 @@ static int airoha_dev_init(struct net_device *netdev)\n \t\tfallthrough;\n \tcase AIROHA_GDM2_IDX:\n \t\t/* GDM2 is always used as wan */\n-\t\tdev-\u003eflags |= AIROHA_PRIV_F_WAN;\n+\t\tdev-\u003eflags |= AIROHA_DEV_F_WAN;\n \t\tbreak;\n \tdefault:\n \t\tbreak;\n@@ -2178,9 +2245,9 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,\n \t\t\t\t struct net_device *netdev)\n {\n \tstruct airoha_gdm_dev *dev = netdev_priv(netdev);\n-\tstruct airoha_qdma *qdma = dev-\u003eqdma;\n \tu32 nr_frags, tag, msg0, msg1, len;\n \tstruct airoha_queue_entry *e;\n+\tstruct airoha_qdma *qdma;\n \tstruct netdev_queue *txq;\n \tstruct airoha_queue *q;\n \tLIST_HEAD(tx_list);\n@@ -2189,6 +2256,8 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,\n \tu16 index;\n \tu8 fport;\n \n+\trcu_read_lock();\n+\tqdma = rcu_dereference(dev-\u003eqdma);\n \tqid = airoha_qdma_get_txq(qdma, skb_get_queue_mapping(skb));\n \ttag = airoha_get_dsa_tag(skb, netdev);\n \n@@ -2238,6 +2307,8 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,\n \t\tnetif_tx_stop_queue(txq);\n \t\tq-\u003etxq_stopped = true;\n \t\tspin_unlock_bh(\u0026q-\u003elock);\n+\t\trcu_read_unlock();\n+\n \t\treturn NETDEV_TX_BUSY;\n \t}\n \n@@ -2303,6 +2374,7 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,\n \t\t\t\tFIELD_PREP(TX_RING_CPU_IDX_MASK, index));\n \n \tspin_unlock_bh(\u0026q-\u003elock);\n+\trcu_read_unlock();\n \n \treturn NETDEV_TX_OK;\n \n@@ -2315,6 +2387,7 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,\n error:\n \tdev_kfree_skb_any(skb);\n \tnetdev-\u003estats.tx_dropped++;\n+\trcu_read_unlock();\n \n \treturn NETDEV_TX_OK;\n }\n@@ -2394,17 +2467,19 @@ static int airoha_qdma_set_chan_tx_sched(struct net_device *netdev,\n \t\t\t\t\t const u16 *weights, u8 n_weights)\n {\n \tstruct airoha_gdm_dev *dev = netdev_priv(netdev);\n+\tstruct airoha_qdma *qdma;\n \tint i;\n \n+\tqdma = airoha_qdma_deref(dev);\n \tfor (i = 0; i \u003c AIROHA_NUM_QOS_QUEUES; i++)\n-\t\tairoha_qdma_clear(dev-\u003eqdma, REG_QUEUE_CLOSE_CFG(channel),\n+\t\tairoha_qdma_clear(qdma, REG_QUEUE_CLOSE_CFG(channel),\n \t\t\t\t TXQ_DISABLE_CHAN_QUEUE_MASK(channel, i));\n \n \tfor (i = 0; i \u003c n_weights; i++) {\n \t\tu32 status;\n \t\tint err;\n \n-\t\tairoha_qdma_wr(dev-\u003eqdma, REG_TXWRR_WEIGHT_CFG,\n+\t\tairoha_qdma_wr(qdma, REG_TXWRR_WEIGHT_CFG,\n \t\t\t TWRR_RW_CMD_MASK |\n \t\t\t FIELD_PREP(TWRR_CHAN_IDX_MASK, channel) |\n \t\t\t FIELD_PREP(TWRR_QUEUE_IDX_MASK, i) |\n@@ -2412,12 +2487,12 @@ static int airoha_qdma_set_chan_tx_sched(struct net_device *netdev,\n \t\terr = read_poll_timeout(airoha_qdma_rr, status,\n \t\t\t\t\tstatus \u0026 TWRR_RW_CMD_DONE,\n \t\t\t\t\tUSEC_PER_MSEC, 10 * USEC_PER_MSEC,\n-\t\t\t\t\ttrue, dev-\u003eqdma, REG_TXWRR_WEIGHT_CFG);\n+\t\t\t\t\ttrue, qdma, REG_TXWRR_WEIGHT_CFG);\n \t\tif (err)\n \t\t\treturn err;\n \t}\n \n-\tairoha_qdma_rmw(dev-\u003eqdma, REG_CHAN_QOS_MODE(channel \u003e\u003e 3),\n+\tairoha_qdma_rmw(qdma, REG_CHAN_QOS_MODE(channel \u003e\u003e 3),\n \t\t\tCHAN_QOS_MODE_MASK(channel),\n \t\t\t__field_prep(CHAN_QOS_MODE_MASK(channel), mode));\n \n@@ -2481,17 +2556,22 @@ static int airoha_qdma_get_tx_ets_stats(struct net_device *netdev, int channel,\n \t\t\t\t\tstruct tc_ets_qopt_offload *opt)\n {\n \tstruct airoha_gdm_dev *dev = netdev_priv(netdev);\n-\tstruct airoha_qdma *qdma = dev-\u003eqdma;\n+\tu32 cpu_tx_packets, fwd_tx_packets;\n+\tstruct airoha_qdma *qdma;\n+\tu64 tx_packets;\n \n-\tu64 cpu_tx_packets = airoha_qdma_rr(qdma, REG_CNTR_VAL(channel \u003c\u003c 1));\n-\tu64 fwd_tx_packets = airoha_qdma_rr(qdma,\n-\t\t\t\t\t REG_CNTR_VAL((channel \u003c\u003c 1) + 1));\n-\tu64 tx_packets = (cpu_tx_packets - dev-\u003ecpu_tx_packets) +\n-\t\t\t (fwd_tx_packets - dev-\u003efwd_tx_packets);\n+\tqdma = airoha_qdma_deref(dev);\n+\tcpu_tx_packets = airoha_qdma_rr(qdma, REG_CNTR_VAL(channel \u003c\u003c 1));\n+\tfwd_tx_packets = airoha_qdma_rr(qdma,\n+\t\t\t\t\tREG_CNTR_VAL((channel \u003c\u003c 1) + 1));\n+\ttx_packets = (u32)(cpu_tx_packets -\n+\t\t\t dev-\u003eqos_stats[channel].cpu_tx_packets);\n+\ttx_packets += (u32)(fwd_tx_packets -\n+\t\t\t dev-\u003eqos_stats[channel].fwd_tx_packets);\n \n \t_bstats_update(opt-\u003estats.bstats, 0, tx_packets);\n-\tdev-\u003ecpu_tx_packets = cpu_tx_packets;\n-\tdev-\u003efwd_tx_packets = fwd_tx_packets;\n+\tdev-\u003eqos_stats[channel].cpu_tx_packets = cpu_tx_packets;\n+\tdev-\u003eqos_stats[channel].fwd_tx_packets = fwd_tx_packets;\n \n \treturn 0;\n }\n@@ -2747,16 +2827,18 @@ static int airoha_qdma_set_tx_rate_limit(struct net_device *netdev,\n \t\t\t\t\t u32 bucket_size)\n {\n \tstruct airoha_gdm_dev *dev = netdev_priv(netdev);\n+\tstruct airoha_qdma *qdma;\n \tint i, err;\n \n+\tqdma = airoha_qdma_deref(dev);\n \tfor (i = 0; i \u003c= TRTCM_PEAK_MODE; i++) {\n-\t\terr = airoha_qdma_set_trtcm_config(dev-\u003eqdma, channel,\n+\t\terr = airoha_qdma_set_trtcm_config(qdma, channel,\n \t\t\t\t\t\t REG_EGRESS_TRTCM_CFG, i,\n \t\t\t\t\t\t !!rate, TRTCM_METER_MODE);\n \t\tif (err)\n \t\t\treturn err;\n \n-\t\terr = airoha_qdma_set_trtcm_token_bucket(dev-\u003eqdma, channel,\n+\t\terr = airoha_qdma_set_trtcm_token_bucket(qdma, channel,\n \t\t\t\t\t\t\t REG_EGRESS_TRTCM_CFG,\n \t\t\t\t\t\t\t i, rate, bucket_size);\n \t\tif (err)\n@@ -2792,11 +2874,12 @@ static int airoha_tc_htb_alloc_leaf_queue(struct net_device *netdev,\n \tu32 channel = TC_H_MIN(opt-\u003eclassid) % AIROHA_NUM_QOS_CHANNELS;\n \tint err, num_tx_queues = AIROHA_NUM_TX_RING + channel + 1;\n \tstruct airoha_gdm_dev *dev = netdev_priv(netdev);\n-\tstruct airoha_qdma *qdma = dev-\u003eqdma;\n+\tstruct airoha_qdma *qdma;\n \n \t/* Here we need to check the requested QDMA channel is not already\n \t * in use by another net_device running on the same QDMA block.\n \t */\n+\tqdma = airoha_qdma_deref(dev);\n \tif (test_and_set_bit(channel, qdma-\u003eqos_channel_map)) {\n \t\tNL_SET_ERR_MSG_MOD(opt-\u003eextack,\n \t\t\t\t \"qdma qos channel already in use\");\n@@ -2832,7 +2915,7 @@ static int airoha_qdma_set_rx_meter(struct airoha_gdm_dev *dev,\n \t\t\t\t u32 rate, u32 bucket_size,\n \t\t\t\t enum trtcm_unit_type unit_type)\n {\n-\tstruct airoha_qdma *qdma = dev-\u003eqdma;\n+\tstruct airoha_qdma *qdma = airoha_qdma_deref(dev);\n \tint i;\n \n \tfor (i = 0; i \u003c ARRAY_SIZE(qdma-\u003eq_rx); i++) {\n@@ -3007,10 +3090,11 @@ static void airoha_tc_remove_htb_queue(struct net_device *netdev, int queue)\n {\n \tstruct airoha_gdm_dev *dev = netdev_priv(netdev);\n \tint num_tx_queues = AIROHA_NUM_TX_RING;\n-\tstruct airoha_qdma *qdma = dev-\u003eqdma;\n+\tstruct airoha_qdma *qdma;\n \n \tairoha_qdma_set_tx_rate_limit(netdev, queue, 0, 0);\n \n+\tqdma = airoha_qdma_deref(dev);\n \tclear_bit(queue, qdma-\u003eqos_channel_map);\n \tclear_bit(queue, dev-\u003eqos_sq_bmap);\n \n@@ -3036,6 +3120,98 @@ static int airoha_tc_htb_delete_leaf_queue(struct net_device *netdev,\n \treturn 0;\n }\n \n+static void airoha_disable_qos_for_gdm34(struct net_device *netdev)\n+{\n+\tstruct airoha_gdm_dev *dev = netdev_priv(netdev);\n+\tstruct airoha_gdm_port *port = dev-\u003eport;\n+\tint err;\n+\n+\tif (port-\u003eid != AIROHA_GDM3_IDX \u0026\u0026\n+\t port-\u003eid != AIROHA_GDM4_IDX)\n+\t\treturn;\n+\n+\terr = airoha_disable_gdm2_loopback(dev);\n+\tif (err)\n+\t\tnetdev_warn(netdev,\n+\t\t\t \"failed disabling GDM2 loopback: %d\\n\", err);\n+\n+\tdev-\u003eflags \u0026= ~AIROHA_DEV_F_WAN;\n+\tairoha_dev_set_qdma(dev);\n+\n+\tairoha_set_macaddr(dev, netdev-\u003edev_addr);\n+\tairoha_ppe_set_xmit_frame_size(dev);\n+\n+\tif (netif_running(netdev))\n+\t\tairoha_set_gdm_port_fwd_cfg(dev-\u003eeth,\n+\t\t\t\t\t REG_GDM_FWD_CFG(port-\u003eid),\n+\t\t\t\t\t FE_PSE_PORT_PPE1);\n+}\n+\n+static int airoha_enable_qos_for_gdm34(struct net_device *netdev,\n+\t\t\t\t struct netlink_ext_ack *extack)\n+{\n+\tstruct airoha_gdm_dev *wan_dev, *dev = netdev_priv(netdev);\n+\tstruct airoha_gdm_port *port = dev-\u003eport;\n+\tstruct airoha_eth *eth = dev-\u003eeth;\n+\tint err = -EBUSY;\n+\n+\tif (port-\u003eid != AIROHA_GDM3_IDX \u0026\u0026\n+\t port-\u003eid != AIROHA_GDM4_IDX) {\n+\t\t/* HW QoS is always supported by GDM1 and GDM2 */\n+\t\treturn 0;\n+\t}\n+\n+\tif (!airoha_is_lan_gdm_dev(dev)) /* Already enabled */\n+\t\treturn 0;\n+\n+\tmutex_lock(\u0026flow_offload_mutex);\n+\n+\twan_dev = airoha_get_wan_gdm_dev(eth);\n+\tif (wan_dev) {\n+\t\tif ((wan_dev-\u003eflags \u0026 AIROHA_DEV_F_QOS) ||\n+\t\t wan_dev-\u003eport-\u003eid == AIROHA_GDM2_IDX) {\n+\t\t\tNL_SET_ERR_MSG_MOD(extack,\n+\t\t\t\t\t \"QoS configured for WAN device\");\n+\t\t\tgoto error_unlock;\n+\t\t}\n+\t\tairoha_disable_qos_for_gdm34(netdev_from_priv(wan_dev));\n+\t}\n+\n+\tdev-\u003eflags |= AIROHA_DEV_F_WAN;\n+\tairoha_dev_set_qdma(dev);\n+\terr = airoha_enable_gdm2_loopback(dev);\n+\tif (err)\n+\t\tgoto error_disable_wan;\n+\n+\terr = airoha_set_macaddr(dev, netdev-\u003edev_addr);\n+\tif (err)\n+\t\tgoto error_disable_loopback;\n+\n+\tairoha_dev_set_xmit_frame_size(netdev);\n+\tif (netif_running(netdev)) {\n+\t\tu32 pse_port;\n+\n+\t\tpse_port = airoha_ppe_is_enabled(eth, 1) ? FE_PSE_PORT_PPE2\n+\t\t\t\t\t\t\t : FE_PSE_PORT_PPE1;\n+\t\tairoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(port-\u003eid),\n+\t\t\t\t\t pse_port);\n+\t}\n+\n+\tmutex_unlock(\u0026flow_offload_mutex);\n+\n+\treturn 0;\n+\n+error_disable_loopback:\n+\tairoha_disable_gdm2_loopback(dev);\n+error_disable_wan:\n+\tdev-\u003eflags \u0026= ~AIROHA_DEV_F_WAN;\n+\tairoha_dev_set_qdma(dev);\n+error_unlock:\n+\tmutex_unlock(\u0026flow_offload_mutex);\n+\n+\treturn err;\n+}\n+\n static int airoha_tc_htb_destroy(struct net_device *netdev)\n {\n \tstruct airoha_gdm_dev *dev = netdev_priv(netdev);\n@@ -3044,6 +3220,8 @@ static int airoha_tc_htb_destroy(struct net_device *netdev)\n \tfor_each_set_bit(q, dev-\u003eqos_sq_bmap, AIROHA_NUM_QOS_CHANNELS)\n \t\tairoha_tc_remove_htb_queue(netdev, q);\n \n+\tdev-\u003eflags \u0026= ~AIROHA_DEV_F_QOS;\n+\n \treturn 0;\n }\n \n@@ -3063,24 +3241,33 @@ static int airoha_tc_get_htb_get_leaf_queue(struct net_device *netdev,\n \treturn 0;\n }\n \n-static int airoha_tc_setup_qdisc_htb(struct net_device *dev,\n+static int airoha_tc_setup_qdisc_htb(struct net_device *netdev,\n \t\t\t\t struct tc_htb_qopt_offload *opt)\n {\n \tswitch (opt-\u003ecommand) {\n-\tcase TC_HTB_CREATE:\n+\tcase TC_HTB_CREATE: {\n+\t\tstruct airoha_gdm_dev *dev = netdev_priv(netdev);\n+\t\tint err;\n+\n+\t\terr = airoha_enable_qos_for_gdm34(netdev, opt-\u003eextack);\n+\t\tif (err)\n+\t\t\treturn err;\n+\n+\t\tdev-\u003eflags |= AIROHA_DEV_F_QOS;\n \t\tbreak;\n+\t}\n \tcase TC_HTB_DESTROY:\n-\t\treturn airoha_tc_htb_destroy(dev);\n+\t\treturn airoha_tc_htb_destroy(netdev);\n \tcase TC_HTB_NODE_MODIFY:\n-\t\treturn airoha_tc_htb_modify_queue(dev, opt);\n+\t\treturn airoha_tc_htb_modify_queue(netdev, opt);\n \tcase TC_HTB_LEAF_ALLOC_QUEUE:\n-\t\treturn airoha_tc_htb_alloc_leaf_queue(dev, opt);\n+\t\treturn airoha_tc_htb_alloc_leaf_queue(netdev, opt);\n \tcase TC_HTB_LEAF_DEL:\n \tcase TC_HTB_LEAF_DEL_LAST:\n \tcase TC_HTB_LEAF_DEL_LAST_FORCE:\n-\t\treturn airoha_tc_htb_delete_leaf_queue(dev, opt);\n+\t\treturn airoha_tc_htb_delete_leaf_queue(netdev, opt);\n \tcase TC_HTB_LEAF_QUERY_QUEUE:\n-\t\treturn airoha_tc_get_htb_get_leaf_queue(dev, opt);\n+\t\treturn airoha_tc_get_htb_get_leaf_queue(netdev, opt);\n \tdefault:\n \t\treturn -EOPNOTSUPP;\n \t}\ndiff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h\nindex f6d01a8e8da139..4d03ebae1a2d71 100644\n--- a/drivers/net/ethernet/airoha/airoha_eth.h\n+++ b/drivers/net/ethernet/airoha/airoha_eth.h\n@@ -543,19 +543,21 @@ struct airoha_qdma {\n \tDECLARE_BITMAP(qos_channel_map, AIROHA_NUM_QOS_CHANNELS);\n };\n \n-enum airoha_priv_flags {\n-\tAIROHA_PRIV_F_WAN = BIT(0),\n+enum airoha_dev_flags {\n+\tAIROHA_DEV_F_WAN = BIT(0),\n+\tAIROHA_DEV_F_QOS = BIT(1),\n };\n \n struct airoha_gdm_dev {\n+\tstruct airoha_qdma __rcu *qdma;\n \tstruct airoha_gdm_port *port;\n-\tstruct airoha_qdma *qdma;\n \tstruct airoha_eth *eth;\n \n \tDECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS);\n-\t/* qos stats counters */\n-\tu64 cpu_tx_packets;\n-\tu64 fwd_tx_packets;\n+\tstruct {\n+\t\tu32 cpu_tx_packets;\n+\t\tu32 fwd_tx_packets;\n+\t} qos_stats[AIROHA_NUM_QOS_CHANNELS];\n \n \tu32 flags;\n \tint nbq;\n@@ -667,7 +669,7 @@ static inline u16 airoha_qdma_get_txq(struct airoha_qdma *qdma, u16 qid)\n \n static inline bool airoha_is_lan_gdm_dev(struct airoha_gdm_dev *dev)\n {\n-\treturn !(dev-\u003eflags \u0026 AIROHA_PRIV_F_WAN);\n+\treturn !(dev-\u003eflags \u0026 AIROHA_DEV_F_WAN);\n }\n \n static inline bool airoha_is_7581(struct airoha_eth *eth)\n@@ -684,6 +686,16 @@ int airoha_get_fe_port(struct airoha_gdm_dev *dev);\n bool airoha_is_valid_gdm_dev(struct airoha_eth *eth,\n \t\t\t struct airoha_gdm_dev *dev);\n \n+extern struct mutex flow_offload_mutex;\n+\n+static inline struct airoha_qdma *\n+airoha_qdma_deref(struct airoha_gdm_dev *dev)\n+{\n+\treturn rcu_dereference_protected(dev-\u003eqdma,\n+\t\t\t\t\t lockdep_rtnl_is_held() ||\n+\t\t\t\t\t lockdep_is_held(\u0026flow_offload_mutex));\n+}\n+\n void airoha_ppe_set_xmit_frame_size(struct airoha_gdm_dev *dev);\n void airoha_ppe_set_cpu_port(struct airoha_gdm_dev *dev, u8 ppe_id, u8 fport);\n bool airoha_ppe_is_enabled(struct airoha_eth *eth, int index);\ndiff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c\nindex fdb973fc779c83..3ccdf9fccb4a12 100644\n--- a/drivers/net/ethernet/airoha/airoha_ppe.c\n+++ b/drivers/net/ethernet/airoha/airoha_ppe.c\n@@ -15,7 +15,10 @@\n #include \"airoha_regs.h\"\n #include \"airoha_eth.h\"\n \n-static DEFINE_MUTEX(flow_offload_mutex);\n+/* Serialize airoha_gdm_dev flags, QDMA pointer and PPE CPU port\n+ * configuration.\n+ */\n+DEFINE_MUTEX(flow_offload_mutex);\n static DEFINE_SPINLOCK(ppe_lock);\n \n static const struct rhashtable_params airoha_flow_table_params = {\n@@ -86,8 +89,8 @@ static u32 airoha_ppe_get_timestamp(struct airoha_ppe *ppe)\n \n void airoha_ppe_set_cpu_port(struct airoha_gdm_dev *dev, u8 ppe_id, u8 fport)\n {\n-\tstruct airoha_qdma *qdma = dev-\u003eqdma;\n-\tstruct airoha_eth *eth = qdma-\u003eeth;\n+\tstruct airoha_qdma *qdma = airoha_qdma_deref(dev);\n+\tstruct airoha_eth *eth = dev-\u003eeth;\n \tu8 qdma_id = qdma - \u0026eth-\u003eqdma[0];\n \tu32 fe_cpu_port;\n \ndiff --git a/drivers/net/ethernet/airoha/airoha_regs.h b/drivers/net/ethernet/airoha/airoha_regs.h\nindex 6fed63d013b412..442b48c9b991ef 100644\n--- a/drivers/net/ethernet/airoha/airoha_regs.h\n+++ b/drivers/net/ethernet/airoha/airoha_regs.h\n@@ -375,6 +375,7 @@\n \n #define REG_SRC_PORT_FC_MAP6\t\t0x2298\n #define FC_ID_OF_SRC_PORT_MASK(_n)\tGENMASK(4 + ((_n) \u003c\u003c 3), ((_n) \u003c\u003c 3))\n+#define FC_MAP6_DEF_VALUE\t\t0x1b1a1918\n \n #define REG_WAN_MTU0\t\t\t0x2300\n #define WAN_MTU1_MASK\t\t\tGENMASK(29, 16)\n"
} |
| 2/1 | 2026/07/21 07:03 | agent | patch-evaluator |
1mModel:best-expensive Args: null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch modifies the Airoha ethernet driver (airoha_eth), which is a hardware-specific platform driver for Airoha SoCs. Since there is no software emulator for this hardware in the kernel or QEMU, the driver cannot successfully probe (it will fail on MMIO polling loops like read_poll_timeout), making the modified code paths unreachable in virtualized environments.",
"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 6c35c0719ba87bb741b6077482eaece9759c9813
Author: syz-cluster <triage@syzkaller.com>
Date: Tue Jul 21 07:03:57 2026 +0000
syz-cluster: applied patch under review
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 59001fd4b6f740..fe2e2af67173e5 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -934,7 +934,7 @@ static void airoha_qdma_wake_netdev_txqs(struct airoha_queue *q)
if (!dev)
continue;
- if (dev->qdma != qdma)
+ if (rcu_access_pointer(dev->qdma) != qdma)
continue;
netdev = netdev_from_priv(dev);
@@ -1866,8 +1866,8 @@ static int airoha_dev_open(struct net_device *netdev)
{
struct airoha_gdm_dev *dev = netdev_priv(netdev);
struct airoha_gdm_port *port = dev->port;
- struct airoha_qdma *qdma = dev->qdma;
u32 pse_port = FE_PSE_PORT_PPE1;
+ struct airoha_qdma *qdma;
int err;
netif_tx_start_all_queues(netdev);
@@ -1875,6 +1875,7 @@ static int airoha_dev_open(struct net_device *netdev)
if (err)
return err;
+ qdma = airoha_qdma_deref(dev);
if (netdev_uses_dsa(netdev))
airoha_fe_set(qdma->eth, REG_GDM_INGRESS_CFG(port->id),
GDM_STAG_EN_MASK);
@@ -1898,7 +1899,6 @@ static int airoha_dev_stop(struct net_device *netdev)
{
struct airoha_gdm_dev *dev = netdev_priv(netdev);
struct airoha_gdm_port *port = dev->port;
- struct airoha_qdma *qdma = dev->qdma;
netif_tx_disable(netdev);
airoha_set_vip_for_gdm_port(dev, false);
@@ -1906,7 +1906,7 @@ static int airoha_dev_stop(struct net_device *netdev)
if (--port->users)
airoha_ppe_set_xmit_frame_size(dev);
else
- airoha_set_gdm_port_fwd_cfg(qdma->eth,
+ airoha_set_gdm_port_fwd_cfg(dev->eth,
REG_GDM_FWD_CFG(port->id),
FE_PSE_PORT_DROP);
return 0;
@@ -1989,6 +1989,53 @@ static int airoha_enable_gdm2_loopback(struct airoha_gdm_dev *dev)
return 0;
}
+static int airoha_disable_gdm2_loopback(struct airoha_gdm_dev *dev)
+{
+ struct airoha_gdm_port *port = dev->port;
+ struct airoha_eth *eth = dev->eth;
+ int i, src_port;
+ u32 pse_port;
+
+ src_port = eth->soc->ops.get_sport(dev->port, dev->nbq);
+ if (src_port < 0)
+ return src_port;
+
+ airoha_fe_clear(eth,
+ REG_SP_DFT_CPORT(src_port >> fls(SP_CPORT_DFT_MASK)),
+ SP_CPORT_MASK(src_port & SP_CPORT_DFT_MASK));
+
+ airoha_fe_set(eth, REG_GDM_FWD_CFG(AIROHA_GDM2_IDX),
+ GDM_STRIP_CRC_MASK);
+ airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(AIROHA_GDM2_IDX),
+ FE_PSE_PORT_DROP);
+ airoha_fe_clear(eth, REG_GDM_LPBK_CFG(AIROHA_GDM2_IDX),
+ LPBK_CHAN_MASK | LPBK_MODE_MASK | LPBK_EN_MASK);
+ pse_port = airoha_ppe_is_enabled(eth, 1) ? FE_PSE_PORT_PPE2
+ : FE_PSE_PORT_PPE1;
+ airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(AIROHA_GDM2_IDX),
+ pse_port);
+
+ airoha_fe_rmw(eth, REG_FE_WAN_PORT, WAN0_MASK,
+ FIELD_PREP(WAN0_MASK, AIROHA_GDM2_IDX));
+
+ for (i = 0; i < eth->soc->num_ppe; i++)
+ airoha_fe_clear(eth, REG_PPE_DFT_CPORT(i, AIROHA_GDM2_IDX),
+ DFT_CPORT_MASK(AIROHA_GDM2_IDX));
+
+ /* Enable VIP and IFC for GDM2 */
+ airoha_fe_set(eth, REG_FE_VIP_PORT_EN, BIT(AIROHA_GDM2_IDX));
+ airoha_fe_set(eth, REG_FE_IFC_PORT_EN, BIT(AIROHA_GDM2_IDX));
+
+ if (port->id == AIROHA_GDM4_IDX && airoha_is_7581(eth)) {
+ u32 mask = FC_ID_OF_SRC_PORT_MASK(dev->nbq);
+
+ airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6, mask,
+ FC_MAP6_DEF_VALUE & mask);
+ }
+
+ return 0;
+}
+
static struct airoha_gdm_dev *
airoha_get_wan_gdm_dev(struct airoha_eth *eth)
{
@@ -2015,15 +2062,35 @@ airoha_get_wan_gdm_dev(struct airoha_eth *eth)
static void airoha_dev_set_qdma(struct airoha_gdm_dev *dev)
{
struct net_device *netdev = netdev_from_priv(dev);
+ struct airoha_qdma *cur_qdma, *qdma;
struct airoha_eth *eth = dev->eth;
- int ppe_id;
+ int i, ppe_id;
/* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */
- dev->qdma = ð->qdma[!airoha_is_lan_gdm_dev(dev)];
- netdev->irq = dev->qdma->irq_banks[0].irq;
+ qdma = ð->qdma[!airoha_is_lan_gdm_dev(dev)];
+ cur_qdma = airoha_qdma_deref(dev);
+
+ rcu_assign_pointer(dev->qdma, qdma);
+ netdev->irq = qdma->irq_banks[0].irq;
ppe_id = !airoha_is_lan_gdm_dev(dev) && airoha_ppe_is_enabled(eth, 1);
airoha_ppe_set_cpu_port(dev, ppe_id, airoha_get_fe_port(dev));
+
+ if (!cur_qdma)
+ return;
+
+ /* Seed qos_stats baselines with the new QDMA block's current
+ * counter values to avoid a spurious spike on the first stats
+ * query after migration.
+ */
+ for (i = 0; i < ARRAY_SIZE(dev->qos_stats); i++) {
+ dev->qos_stats[i].cpu_tx_packets =
+ airoha_qdma_rr(qdma, REG_CNTR_VAL(i << 1));
+ dev->qos_stats[i].fwd_tx_packets =
+ airoha_qdma_rr(qdma, REG_CNTR_VAL((i << 1) + 1));
+ }
+ synchronize_rcu();
+ netif_tx_wake_all_queues(netdev);
}
static int airoha_dev_init(struct net_device *netdev)
@@ -2039,7 +2106,7 @@ static int airoha_dev_init(struct net_device *netdev)
fallthrough;
case AIROHA_GDM2_IDX:
/* GDM2 is always used as wan */
- dev->flags |= AIROHA_PRIV_F_WAN;
+ dev->flags |= AIROHA_DEV_F_WAN;
break;
default:
break;
@@ -2178,9 +2245,9 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
struct net_device *netdev)
{
struct airoha_gdm_dev *dev = netdev_priv(netdev);
- struct airoha_qdma *qdma = dev->qdma;
u32 nr_frags, tag, msg0, msg1, len;
struct airoha_queue_entry *e;
+ struct airoha_qdma *qdma;
struct netdev_queue *txq;
struct airoha_queue *q;
LIST_HEAD(tx_list);
@@ -2189,6 +2256,8 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
u16 index;
u8 fport;
+ rcu_read_lock();
+ qdma = rcu_dereference(dev->qdma);
qid = airoha_qdma_get_txq(qdma, skb_get_queue_mapping(skb));
tag = airoha_get_dsa_tag(skb, netdev);
@@ -2238,6 +2307,8 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
netif_tx_stop_queue(txq);
q->txq_stopped = true;
spin_unlock_bh(&q->lock);
+ rcu_read_unlock();
+
return NETDEV_TX_BUSY;
}
@@ -2303,6 +2374,7 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
FIELD_PREP(TX_RING_CPU_IDX_MASK, index));
spin_unlock_bh(&q->lock);
+ rcu_read_unlock();
return NETDEV_TX_OK;
@@ -2315,6 +2387,7 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
error:
dev_kfree_skb_any(skb);
netdev->stats.tx_dropped++;
+ rcu_read_unlock();
return NETDEV_TX_OK;
}
@@ -2394,17 +2467,19 @@ static int airoha_qdma_set_chan_tx_sched(struct net_device *netdev,
const u16 *weights, u8 n_weights)
{
struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_qdma *qdma;
int i;
+ qdma = airoha_qdma_deref(dev);
for (i = 0; i < AIROHA_NUM_QOS_QUEUES; i++)
- airoha_qdma_clear(dev->qdma, REG_QUEUE_CLOSE_CFG(channel),
+ airoha_qdma_clear(qdma, REG_QUEUE_CLOSE_CFG(channel),
TXQ_DISABLE_CHAN_QUEUE_MASK(channel, i));
for (i = 0; i < n_weights; i++) {
u32 status;
int err;
- airoha_qdma_wr(dev->qdma, REG_TXWRR_WEIGHT_CFG,
+ airoha_qdma_wr(qdma, REG_TXWRR_WEIGHT_CFG,
TWRR_RW_CMD_MASK |
FIELD_PREP(TWRR_CHAN_IDX_MASK, channel) |
FIELD_PREP(TWRR_QUEUE_IDX_MASK, i) |
@@ -2412,12 +2487,12 @@ static int airoha_qdma_set_chan_tx_sched(struct net_device *netdev,
err = read_poll_timeout(airoha_qdma_rr, status,
status & TWRR_RW_CMD_DONE,
USEC_PER_MSEC, 10 * USEC_PER_MSEC,
- true, dev->qdma, REG_TXWRR_WEIGHT_CFG);
+ true, qdma, REG_TXWRR_WEIGHT_CFG);
if (err)
return err;
}
- airoha_qdma_rmw(dev->qdma, REG_CHAN_QOS_MODE(channel >> 3),
+ airoha_qdma_rmw(qdma, REG_CHAN_QOS_MODE(channel >> 3),
CHAN_QOS_MODE_MASK(channel),
__field_prep(CHAN_QOS_MODE_MASK(channel), mode));
@@ -2481,17 +2556,22 @@ static int airoha_qdma_get_tx_ets_stats(struct net_device *netdev, int channel,
struct tc_ets_qopt_offload *opt)
{
struct airoha_gdm_dev *dev = netdev_priv(netdev);
- struct airoha_qdma *qdma = dev->qdma;
+ u32 cpu_tx_packets, fwd_tx_packets;
+ struct airoha_qdma *qdma;
+ u64 tx_packets;
- u64 cpu_tx_packets = airoha_qdma_rr(qdma, REG_CNTR_VAL(channel << 1));
- u64 fwd_tx_packets = airoha_qdma_rr(qdma,
- REG_CNTR_VAL((channel << 1) + 1));
- u64 tx_packets = (cpu_tx_packets - dev->cpu_tx_packets) +
- (fwd_tx_packets - dev->fwd_tx_packets);
+ qdma = airoha_qdma_deref(dev);
+ cpu_tx_packets = airoha_qdma_rr(qdma, REG_CNTR_VAL(channel << 1));
+ fwd_tx_packets = airoha_qdma_rr(qdma,
+ REG_CNTR_VAL((channel << 1) + 1));
+ tx_packets = (u32)(cpu_tx_packets -
+ dev->qos_stats[channel].cpu_tx_packets);
+ tx_packets += (u32)(fwd_tx_packets -
+ dev->qos_stats[channel].fwd_tx_packets);
_bstats_update(opt->stats.bstats, 0, tx_packets);
- dev->cpu_tx_packets = cpu_tx_packets;
- dev->fwd_tx_packets = fwd_tx_packets;
+ dev->qos_stats[channel].cpu_tx_packets = cpu_tx_packets;
+ dev->qos_stats[channel].fwd_tx_packets = fwd_tx_packets;
return 0;
}
@@ -2747,16 +2827,18 @@ static int airoha_qdma_set_tx_rate_limit(struct net_device *netdev,
u32 bucket_size)
{
struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_qdma *qdma;
int i, err;
+ qdma = airoha_qdma_deref(dev);
for (i = 0; i <= TRTCM_PEAK_MODE; i++) {
- err = airoha_qdma_set_trtcm_config(dev->qdma, channel,
+ err = airoha_qdma_set_trtcm_config(qdma, channel,
REG_EGRESS_TRTCM_CFG, i,
!!rate, TRTCM_METER_MODE);
if (err)
return err;
- err = airoha_qdma_set_trtcm_token_bucket(dev->qdma, channel,
+ err = airoha_qdma_set_trtcm_token_bucket(qdma, channel,
REG_EGRESS_TRTCM_CFG,
i, rate, bucket_size);
if (err)
@@ -2792,11 +2874,12 @@ static int airoha_tc_htb_alloc_leaf_queue(struct net_device *netdev,
u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
int err, num_tx_queues = AIROHA_NUM_TX_RING + channel + 1;
struct airoha_gdm_dev *dev = netdev_priv(netdev);
- struct airoha_qdma *qdma = dev->qdma;
+ struct airoha_qdma *qdma;
/* Here we need to check the requested QDMA channel is not already
* in use by another net_device running on the same QDMA block.
*/
+ qdma = airoha_qdma_deref(dev);
if (test_and_set_bit(channel, qdma->qos_channel_map)) {
NL_SET_ERR_MSG_MOD(opt->extack,
"qdma qos channel already in use");
@@ -2832,7 +2915,7 @@ static int airoha_qdma_set_rx_meter(struct airoha_gdm_dev *dev,
u32 rate, u32 bucket_size,
enum trtcm_unit_type unit_type)
{
- struct airoha_qdma *qdma = dev->qdma;
+ struct airoha_qdma *qdma = airoha_qdma_deref(dev);
int i;
for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
@@ -3007,10 +3090,11 @@ static void airoha_tc_remove_htb_queue(struct net_device *netdev, int queue)
{
struct airoha_gdm_dev *dev = netdev_priv(netdev);
int num_tx_queues = AIROHA_NUM_TX_RING;
- struct airoha_qdma *qdma = dev->qdma;
+ struct airoha_qdma *qdma;
airoha_qdma_set_tx_rate_limit(netdev, queue, 0, 0);
+ qdma = airoha_qdma_deref(dev);
clear_bit(queue, qdma->qos_channel_map);
clear_bit(queue, dev->qos_sq_bmap);
@@ -3036,6 +3120,98 @@ static int airoha_tc_htb_delete_leaf_queue(struct net_device *netdev,
return 0;
}
+static void airoha_disable_qos_for_gdm34(struct net_device *netdev)
+{
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
+ int err;
+
+ if (port->id != AIROHA_GDM3_IDX &&
+ port->id != AIROHA_GDM4_IDX)
+ return;
+
+ err = airoha_disable_gdm2_loopback(dev);
+ if (err)
+ netdev_warn(netdev,
+ "failed disabling GDM2 loopback: %d\n", err);
+
+ dev->flags &= ~AIROHA_DEV_F_WAN;
+ airoha_dev_set_qdma(dev);
+
+ airoha_set_macaddr(dev, netdev->dev_addr);
+ airoha_ppe_set_xmit_frame_size(dev);
+
+ if (netif_running(netdev))
+ airoha_set_gdm_port_fwd_cfg(dev->eth,
+ REG_GDM_FWD_CFG(port->id),
+ FE_PSE_PORT_PPE1);
+}
+
+static int airoha_enable_qos_for_gdm34(struct net_device *netdev,
+ struct netlink_ext_ack *extack)
+{
+ struct airoha_gdm_dev *wan_dev, *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
+ struct airoha_eth *eth = dev->eth;
+ int err = -EBUSY;
+
+ if (port->id != AIROHA_GDM3_IDX &&
+ port->id != AIROHA_GDM4_IDX) {
+ /* HW QoS is always supported by GDM1 and GDM2 */
+ return 0;
+ }
+
+ if (!airoha_is_lan_gdm_dev(dev)) /* Already enabled */
+ return 0;
+
+ mutex_lock(&flow_offload_mutex);
+
+ wan_dev = airoha_get_wan_gdm_dev(eth);
+ if (wan_dev) {
+ if ((wan_dev->flags & AIROHA_DEV_F_QOS) ||
+ wan_dev->port->id == AIROHA_GDM2_IDX) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "QoS configured for WAN device");
+ goto error_unlock;
+ }
+ airoha_disable_qos_for_gdm34(netdev_from_priv(wan_dev));
+ }
+
+ dev->flags |= AIROHA_DEV_F_WAN;
+ airoha_dev_set_qdma(dev);
+ err = airoha_enable_gdm2_loopback(dev);
+ if (err)
+ goto error_disable_wan;
+
+ err = airoha_set_macaddr(dev, netdev->dev_addr);
+ if (err)
+ goto error_disable_loopback;
+
+ airoha_dev_set_xmit_frame_size(netdev);
+ if (netif_running(netdev)) {
+ u32 pse_port;
+
+ pse_port = airoha_ppe_is_enabled(eth, 1) ? FE_PSE_PORT_PPE2
+ : FE_PSE_PORT_PPE1;
+ airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(port->id),
+ pse_port);
+ }
+
+ mutex_unlock(&flow_offload_mutex);
+
+ return 0;
+
+error_disable_loopback:
+ airoha_disable_gdm2_loopback(dev);
+error_disable_wan:
+ dev->flags &= ~AIROHA_DEV_F_WAN;
+ airoha_dev_set_qdma(dev);
+error_unlock:
+ mutex_unlock(&flow_offload_mutex);
+
+ return err;
+}
+
static int airoha_tc_htb_destroy(struct net_device *netdev)
{
struct airoha_gdm_dev *dev = netdev_priv(netdev);
@@ -3044,6 +3220,8 @@ static int airoha_tc_htb_destroy(struct net_device *netdev)
for_each_set_bit(q, dev->qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS)
airoha_tc_remove_htb_queue(netdev, q);
+ dev->flags &= ~AIROHA_DEV_F_QOS;
+
return 0;
}
@@ -3063,24 +3241,33 @@ static int airoha_tc_get_htb_get_leaf_queue(struct net_device *netdev,
return 0;
}
-static int airoha_tc_setup_qdisc_htb(struct net_device *dev,
+static int airoha_tc_setup_qdisc_htb(struct net_device *netdev,
struct tc_htb_qopt_offload *opt)
{
switch (opt->command) {
- case TC_HTB_CREATE:
+ case TC_HTB_CREATE: {
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ int err;
+
+ err = airoha_enable_qos_for_gdm34(netdev, opt->extack);
+ if (err)
+ return err;
+
+ dev->flags |= AIROHA_DEV_F_QOS;
break;
+ }
case TC_HTB_DESTROY:
- return airoha_tc_htb_destroy(dev);
+ return airoha_tc_htb_destroy(netdev);
case TC_HTB_NODE_MODIFY:
- return airoha_tc_htb_modify_queue(dev, opt);
+ return airoha_tc_htb_modify_queue(netdev, opt);
case TC_HTB_LEAF_ALLOC_QUEUE:
- return airoha_tc_htb_alloc_leaf_queue(dev, opt);
+ return airoha_tc_htb_alloc_leaf_queue(netdev, opt);
case TC_HTB_LEAF_DEL:
case TC_HTB_LEAF_DEL_LAST:
case TC_HTB_LEAF_DEL_LAST_FORCE:
- return airoha_tc_htb_delete_leaf_queue(dev, opt);
+ return airoha_tc_htb_delete_leaf_queue(netdev, opt);
case TC_HTB_LEAF_QUERY_QUEUE:
- return airoha_tc_get_htb_get_leaf_queue(dev, opt);
+ return airoha_tc_get_htb_get_leaf_queue(netdev, opt);
default:
return -EOPNOTSUPP;
}
diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
index f6d01a8e8da139..4d03ebae1a2d71 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -543,19 +543,21 @@ struct airoha_qdma {
DECLARE_BITMAP(qos_channel_map, AIROHA_NUM_QOS_CHANNELS);
};
-enum airoha_priv_flags {
- AIROHA_PRIV_F_WAN = BIT(0),
+enum airoha_dev_flags {
+ AIROHA_DEV_F_WAN = BIT(0),
+ AIROHA_DEV_F_QOS = BIT(1),
};
struct airoha_gdm_dev {
+ struct airoha_qdma __rcu *qdma;
struct airoha_gdm_port *port;
- struct airoha_qdma *qdma;
struct airoha_eth *eth;
DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS);
- /* qos stats counters */
- u64 cpu_tx_packets;
- u64 fwd_tx_packets;
+ struct {
+ u32 cpu_tx_packets;
+ u32 fwd_tx_packets;
+ } qos_stats[AIROHA_NUM_QOS_CHANNELS];
u32 flags;
int nbq;
@@ -667,7 +669,7 @@ static inline u16 airoha_qdma_get_txq(struct airoha_qdma *qdma, u16 qid)
static inline bool airoha_is_lan_gdm_dev(struct airoha_gdm_dev *dev)
{
- return !(dev->flags & AIROHA_PRIV_F_WAN);
+ return !(dev->flags & AIROHA_DEV_F_WAN);
}
static inline bool airoha_is_7581(struct airoha_eth *eth)
@@ -684,6 +686,16 @@ int airoha_get_fe_port(struct airoha_gdm_dev *dev);
bool airoha_is_valid_gdm_dev(struct airoha_eth *eth,
struct airoha_gdm_dev *dev);
+extern struct mutex flow_offload_mutex;
+
+static inline struct airoha_qdma *
+airoha_qdma_deref(struct airoha_gdm_dev *dev)
+{
+ return rcu_dereference_protected(dev->qdma,
+ lockdep_rtnl_is_held() ||
+ lockdep_is_held(&flow_offload_mutex));
+}
+
void airoha_ppe_set_xmit_frame_size(struct airoha_gdm_dev *dev);
void airoha_ppe_set_cpu_port(struct airoha_gdm_dev *dev, u8 ppe_id, u8 fport);
bool airoha_ppe_is_enabled(struct airoha_eth *eth, int index);
diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c
index fdb973fc779c83..3ccdf9fccb4a12 100644
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
@@ -15,7 +15,10 @@
#include "airoha_regs.h"
#include "airoha_eth.h"
-static DEFINE_MUTEX(flow_offload_mutex);
+/* Serialize airoha_gdm_dev flags, QDMA pointer and PPE CPU port
+ * configuration.
+ */
+DEFINE_MUTEX(flow_offload_mutex);
static DEFINE_SPINLOCK(ppe_lock);
static const struct rhashtable_params airoha_flow_table_params = {
@@ -86,8 +89,8 @@ static u32 airoha_ppe_get_timestamp(struct airoha_ppe *ppe)
void airoha_ppe_set_cpu_port(struct airoha_gdm_dev *dev, u8 ppe_id, u8 fport)
{
- struct airoha_qdma *qdma = dev->qdma;
- struct airoha_eth *eth = qdma->eth;
+ struct airoha_qdma *qdma = airoha_qdma_deref(dev);
+ struct airoha_eth *eth = dev->eth;
u8 qdma_id = qdma - ð->qdma[0];
u32 fe_cpu_port;
diff --git a/drivers/net/ethernet/airoha/airoha_regs.h b/drivers/net/ethernet/airoha/airoha_regs.h
index 6fed63d013b412..442b48c9b991ef 100644
--- a/drivers/net/ethernet/airoha/airoha_regs.h
+++ b/drivers/net/ethernet/airoha/airoha_regs.h
@@ -375,6 +375,7 @@
#define REG_SRC_PORT_FC_MAP6 0x2298
#define FC_ID_OF_SRC_PORT_MASK(_n) GENMASK(4 + ((_n) << 3), ((_n) << 3))
+#define FC_MAP6_DEF_VALUE 0x1b1a1918
#define REG_WAN_MTU0 0x2300
#define WAN_MTU1_MASK GENMASK(29, 16)
|
| 3/2 | 2026/07/21 07:03 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 10382 output: 34 thoughts: 262 Thoughts: **My Assessment of the Airoha Ethernet Driver Patch** Okay, so I'm looking at this patch for the `airoha` ethernet driver, specifically `drivers/net/ethernet/airoha/airoha_eth.c`. It's pretty clear this isn't just a minor tweak; this is a functional change. They're making some substantial modifications. I see they're using RCU now for `dev->qdma` access, which is good for concurrency, using the typical RCU primitives. That's a solid addition for safety. Beyond that, I see some new functions being introduced: `airoha_disable_gdm2_loopback`, and some QoS enablement and disablement functions, `airoha_enable_qos_for_gdm34` and `airoha_disable_qos_for_gdm34`. These seem tied to QoS configuration, and modifying `airoha_tc_setup_qdisc_htb` to call `airoha_enable_qos_for_gdm34` suggests these QoS features are now integrated with the traffic control setup. The change to `dev->qos_stats` from two `u64` values to an array of structs looks significant. That suggests more detailed QoS statistics are being collected now. Finally, the introduction of `flow_offload_mutex` and its export from `airoha_ppe.c` shows potential changes to how flow offloading is managed. This might be a consequence of the QoS changes. My first thought is, is this even reachable code? I need to figure out if the `airoha_eth` driver is enabled and if it's actually getting built into the kernel or as a module. I need to find the relevant Kconfig entry to check that. From there, I'll need to assess the fuzzability of this new code. If it's something we can fuzz, that'll be a key test. |
| 4/2 | 2026/07/21 07:04 | tool | grepper |
0mArgs:{
"Expression": "airoha_eth",
"PathPrefix": "drivers/net/ethernet/airoha/"
}Results: {
"Output": "drivers/net/ethernet/airoha/Makefile=6=obj-$(CONFIG_NET_AIROHA) += airoha-eth.o\ndrivers/net/ethernet/airoha/Makefile:7:airoha-eth-y := airoha_eth.o airoha_ppe.o\ndrivers/net/ethernet/airoha/Makefile-8-airoha-eth-$(CONFIG_DEBUG_FS) += airoha_ppe_debugfs.o\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-17-#include \"airoha_regs.h\"\ndrivers/net/ethernet/airoha/airoha_eth.c:18:#include \"airoha_eth.h\"\ndrivers/net/ethernet/airoha/airoha_eth.c-19-\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=74=static int airoha_set_macaddr(struct airoha_gdm_dev *dev, const u8 *addr)\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-76-\tu8 ref_addr[ETH_ALEN] __aligned(2);\ndrivers/net/ethernet/airoha/airoha_eth.c:77:\tstruct airoha_eth *eth = dev-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_eth.c-78-\tu32 reg, val, lmin, lmax;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-145-\ndrivers/net/ethernet/airoha/airoha_eth.c:146:static void airoha_set_gdm_port_fwd_cfg(struct airoha_eth *eth, u32 addr,\ndrivers/net/ethernet/airoha/airoha_eth.c-147-\t\t\t\t\tu32 val)\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=159=static int airoha_set_vip_for_gdm_port(struct airoha_gdm_dev *dev, bool enable)\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-161-\tstruct airoha_gdm_port *port = dev-\u003eport;\ndrivers/net/ethernet/airoha/airoha_eth.c:162:\tstruct airoha_eth *eth = dev-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_eth.c-163-\tu32 vip_port;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-176-\ndrivers/net/ethernet/airoha/airoha_eth.c:177:static void airoha_fe_maccr_init(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_eth.c-178-{\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-196-\ndrivers/net/ethernet/airoha/airoha_eth.c:197:static void airoha_fe_vip_setup(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_eth.c-198-{\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-260-\ndrivers/net/ethernet/airoha/airoha_eth.c:261:static u32 airoha_fe_get_pse_queue_rsv_pages(struct airoha_eth *eth,\ndrivers/net/ethernet/airoha/airoha_eth.c-262-\t\t\t\t\t u32 port, u32 queue)\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-272-\ndrivers/net/ethernet/airoha/airoha_eth.c:273:static void airoha_fe_set_pse_queue_rsv_pages(struct airoha_eth *eth,\ndrivers/net/ethernet/airoha/airoha_eth.c-274-\t\t\t\t\t u32 port, u32 queue, u32 val)\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-285-\ndrivers/net/ethernet/airoha/airoha_eth.c:286:static u32 airoha_fe_get_pse_all_rsv(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_eth.c-287-{\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-290-\ndrivers/net/ethernet/airoha/airoha_eth.c:291:static int airoha_fe_set_pse_oq_rsv(struct airoha_eth *eth,\ndrivers/net/ethernet/airoha/airoha_eth.c-292-\t\t\t\t u32 port, u32 queue, u32 val)\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-323-\ndrivers/net/ethernet/airoha/airoha_eth.c:324:static void airoha_fe_pse_ports_init(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_eth.c-325-{\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-407-\ndrivers/net/ethernet/airoha/airoha_eth.c:408:static int airoha_fe_mc_vlan_clear(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_eth.c-409-{\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-447-\ndrivers/net/ethernet/airoha/airoha_eth.c:448:static void airoha_fe_crsn_qsel_init(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_eth.c-449-{\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-493-\ndrivers/net/ethernet/airoha/airoha_eth.c:494:static int airoha_fe_init(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_eth.c-495-{\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=638=static struct airoha_gdm_dev *\ndrivers/net/ethernet/airoha/airoha_eth.c:639:airoha_qdma_get_gdm_dev(struct airoha_eth *eth, struct airoha_qdma_desc *desc)\ndrivers/net/ethernet/airoha/airoha_eth.c-640-{\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=660=static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-663-\tstruct airoha_qdma *qdma = q-\u003eqdma;\ndrivers/net/ethernet/airoha/airoha_eth.c:664:\tstruct airoha_eth *eth = qdma-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_eth.c-665-\tint qid = q - \u0026qdma-\u003eq_rx[0];\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=800=static int airoha_qdma_init_rx_queue(struct airoha_queue *q,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-812-\t};\ndrivers/net/ethernet/airoha/airoha_eth.c:813:\tstruct airoha_eth *eth = qdma-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_eth.c-814-\tint qid = q - \u0026qdma-\u003eq_rx[0], thr;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=858=static void airoha_qdma_cleanup_rx_queue(struct airoha_queue *q)\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-860-\tstruct airoha_qdma *qdma = q-\u003eqdma;\ndrivers/net/ethernet/airoha/airoha_eth.c:861:\tstruct airoha_eth *eth = qdma-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_eth.c-862-\tint qid = q - \u0026qdma-\u003eq_rx[0];\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=916=static void airoha_qdma_wake_netdev_txqs(struct airoha_queue *q)\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-918-\tstruct airoha_qdma *qdma = q-\u003eqdma;\ndrivers/net/ethernet/airoha/airoha_eth.c:919:\tstruct airoha_eth *eth = qdma-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_eth.c-920-\tint i, qid = q - \u0026qdma-\u003eq_tx[0];\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-951-\ndrivers/net/ethernet/airoha/airoha_eth.c:952:static void airoha_unmap_xmit_buf(struct airoha_eth *eth,\ndrivers/net/ethernet/airoha/airoha_eth.c-953-\t\t\t\t struct airoha_queue_entry *e)\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=971=static int airoha_qdma_tx_napi_poll(struct napi_struct *napi, int budget)\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-975-\tstruct airoha_qdma *qdma;\ndrivers/net/ethernet/airoha/airoha_eth.c:976:\tstruct airoha_eth *eth;\ndrivers/net/ethernet/airoha/airoha_eth.c-977-\tu32 status, head;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=1081=static int airoha_qdma_init_tx_queue(struct airoha_queue *q,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-1083-{\ndrivers/net/ethernet/airoha/airoha_eth.c:1084:\tstruct airoha_eth *eth = qdma-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_eth.c-1085-\tint i, qid = q - \u0026qdma-\u003eq_tx[0];\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=1124=static int airoha_qdma_tx_irq_init(struct airoha_tx_irq_queue *irq_q,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-1127-\tint id = irq_q - \u0026qdma-\u003eq_tx_irq[0];\ndrivers/net/ethernet/airoha/airoha_eth.c:1128:\tstruct airoha_eth *eth = qdma-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_eth.c-1129-\tdma_addr_t dma_addr;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=1243=static int airoha_qdma_init_hfwd_queues(struct airoha_qdma *qdma)\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-1245-\tint size, index, num_desc = HW_DSCP_NUM;\ndrivers/net/ethernet/airoha/airoha_eth.c:1246:\tstruct airoha_eth *eth = qdma-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_eth.c-1247-\tint id = qdma - \u0026eth-\u003eqdma[0];\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=1499=static int airoha_qdma_init_irq_banks(struct platform_device *pdev,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-1501-{\ndrivers/net/ethernet/airoha/airoha_eth.c:1502:\tstruct airoha_eth *eth = qdma-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_eth.c-1503-\tint i, id = qdma - \u0026eth-\u003eqdma[0];\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=1532=static int airoha_qdma_init(struct platform_device *pdev,\ndrivers/net/ethernet/airoha/airoha_eth.c:1533:\t\t\t struct airoha_eth *eth,\ndrivers/net/ethernet/airoha/airoha_eth.c-1534-\t\t\t struct airoha_qdma *qdma)\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-1567-\ndrivers/net/ethernet/airoha/airoha_eth.c:1568:static void airoha_qdma_cleanup(struct airoha_eth *eth,\ndrivers/net/ethernet/airoha/airoha_eth.c-1569-\t\t\t\tstruct airoha_qdma *qdma)\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=1606=static int airoha_hw_init(struct platform_device *pdev,\ndrivers/net/ethernet/airoha/airoha_eth.c:1607:\t\t\t struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_eth.c-1608-{\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-1649-\ndrivers/net/ethernet/airoha/airoha_eth.c:1650:static void airoha_hw_cleanup(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_eth.c-1651-{\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=1689=static void airoha_dev_get_hw_stats(struct airoha_gdm_dev *dev)\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-1691-\tstruct airoha_gdm_port *port = dev-\u003eport;\ndrivers/net/ethernet/airoha/airoha_eth.c:1692:\tstruct airoha_eth *eth = dev-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_eth.c-1693-\tu32 val, i = 0;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=1934=static int airoha_enable_gdm2_loopback(struct airoha_gdm_dev *dev)\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-1936-\tstruct airoha_gdm_port *port = dev-\u003eport;\ndrivers/net/ethernet/airoha/airoha_eth.c:1937:\tstruct airoha_eth *eth = dev-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_eth.c-1938-\tu32 val, pse_port, chan;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=1992=static int airoha_disable_gdm2_loopback(struct airoha_gdm_dev *dev)\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-1994-\tstruct airoha_gdm_port *port = dev-\u003eport;\ndrivers/net/ethernet/airoha/airoha_eth.c:1995:\tstruct airoha_eth *eth = dev-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_eth.c-1996-\tint i, src_port;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=2039=static struct airoha_gdm_dev *\ndrivers/net/ethernet/airoha/airoha_eth.c:2040:airoha_get_wan_gdm_dev(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_eth.c-2041-{\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=2062=static void airoha_dev_set_qdma(struct airoha_gdm_dev *dev)\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-2065-\tstruct airoha_qdma *cur_qdma, *qdma;\ndrivers/net/ethernet/airoha/airoha_eth.c:2066:\tstruct airoha_eth *eth = dev-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_eth.c-2067-\tint i, ppe_id;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=2228=int airoha_get_fe_port(struct airoha_gdm_dev *dev)\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-2230-\tstruct airoha_gdm_port *port = dev-\u003eport;\ndrivers/net/ethernet/airoha/airoha_eth.c:2231:\tstruct airoha_eth *eth = dev-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_eth.c-2232-\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=2244=static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-2394-\ndrivers/net/ethernet/airoha/airoha_eth.c:2395:static void airoha_ethtool_get_drvinfo(struct net_device *netdev,\ndrivers/net/ethernet/airoha/airoha_eth.c-2396-\t\t\t\t struct ethtool_drvinfo *info)\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-2398-\tstruct airoha_gdm_dev *dev = netdev_priv(netdev);\ndrivers/net/ethernet/airoha/airoha_eth.c:2399:\tstruct airoha_eth *eth = dev-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_eth.c-2400-\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-2404-\ndrivers/net/ethernet/airoha/airoha_eth.c:2405:static void airoha_ethtool_get_mac_stats(struct net_device *netdev,\ndrivers/net/ethernet/airoha/airoha_eth.c-2406-\t\t\t\t\t struct ethtool_eth_mac_stats *stats)\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-2423-\ndrivers/net/ethernet/airoha/airoha_eth.c:2424:static const struct ethtool_rmon_hist_range airoha_ethtool_rmon_ranges[] = {\ndrivers/net/ethernet/airoha/airoha_eth.c-2425-\t{ 0, 64 },\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=2435=static void\ndrivers/net/ethernet/airoha/airoha_eth.c:2436:airoha_ethtool_get_rmon_stats(struct net_device *netdev,\ndrivers/net/ethernet/airoha/airoha_eth.c-2437-\t\t\t struct ethtool_rmon_stats *stats,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-2443-\ndrivers/net/ethernet/airoha/airoha_eth.c:2444:\tBUILD_BUG_ON(ARRAY_SIZE(airoha_ethtool_rmon_ranges) !=\ndrivers/net/ethernet/airoha/airoha_eth.c-2445-\t\t ARRAY_SIZE(hw_stats-\u003etx_len) + 1);\ndrivers/net/ethernet/airoha/airoha_eth.c:2446:\tBUILD_BUG_ON(ARRAY_SIZE(airoha_ethtool_rmon_ranges) !=\ndrivers/net/ethernet/airoha/airoha_eth.c-2447-\t\t ARRAY_SIZE(hw_stats-\u003erx_len) + 1);\ndrivers/net/ethernet/airoha/airoha_eth.c-2448-\ndrivers/net/ethernet/airoha/airoha_eth.c:2449:\t*ranges = airoha_ethtool_rmon_ranges;\ndrivers/net/ethernet/airoha/airoha_eth.c-2450-\tairoha_update_hw_stats(dev);\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-2456-\t\tstats-\u003ejabbers = hw_stats-\u003erx_jabber;\ndrivers/net/ethernet/airoha/airoha_eth.c:2457:\t\tfor (i = 0; i \u003c ARRAY_SIZE(airoha_ethtool_rmon_ranges) - 1;\ndrivers/net/ethernet/airoha/airoha_eth.c-2458-\t\t i++) {\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=3028=static int airoha_dev_setup_tc_block_cb(enum tc_setup_type type,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-3032-\tstruct airoha_gdm_dev *dev = netdev_priv(netdev);\ndrivers/net/ethernet/airoha/airoha_eth.c:3033:\tstruct airoha_eth *eth = dev-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_eth.c-3034-\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=3150=static int airoha_enable_qos_for_gdm34(struct net_device *netdev,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-3154-\tstruct airoha_gdm_port *port = dev-\u003eport;\ndrivers/net/ethernet/airoha/airoha_eth.c:3155:\tstruct airoha_eth *eth = dev-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_eth.c-3156-\tint err = -EBUSY;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=3294=static const struct net_device_ops airoha_netdev_ops = {\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-3305-\ndrivers/net/ethernet/airoha/airoha_eth.c:3306:static const struct ethtool_ops airoha_ethtool_ops = {\ndrivers/net/ethernet/airoha/airoha_eth.c:3307:\t.get_drvinfo\t\t= airoha_ethtool_get_drvinfo,\ndrivers/net/ethernet/airoha/airoha_eth.c:3308:\t.get_eth_mac_stats = airoha_ethtool_get_mac_stats,\ndrivers/net/ethernet/airoha/airoha_eth.c:3309:\t.get_rmon_stats\t\t= airoha_ethtool_get_rmon_stats,\ndrivers/net/ethernet/airoha/airoha_eth.c-3310-\t.get_link_ksettings\t= phy_ethtool_get_link_ksettings,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=3333=static void airoha_metadata_dst_free(struct airoha_gdm_port *port)\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-3344-\ndrivers/net/ethernet/airoha/airoha_eth.c:3345:bool airoha_is_valid_gdm_dev(struct airoha_eth *eth,\ndrivers/net/ethernet/airoha/airoha_eth.c-3346-\t\t\t struct airoha_gdm_dev *dev)\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-3365-\ndrivers/net/ethernet/airoha/airoha_eth.c:3366:static int airoha_alloc_gdm_device(struct airoha_eth *eth,\ndrivers/net/ethernet/airoha/airoha_eth.c-3367-\t\t\t\t struct airoha_gdm_port *port,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-3383-\tnetdev-\u003enetdev_ops = \u0026airoha_netdev_ops;\ndrivers/net/ethernet/airoha/airoha_eth.c:3384:\tnetdev-\u003eethtool_ops = \u0026airoha_ethtool_ops;\ndrivers/net/ethernet/airoha/airoha_eth.c-3385-\tnetdev-\u003emax_mtu = AIROHA_MAX_MTU;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-3431-\ndrivers/net/ethernet/airoha/airoha_eth.c:3432:static int airoha_alloc_gdm_port(struct airoha_eth *eth,\ndrivers/net/ethernet/airoha/airoha_eth.c-3433-\t\t\t\t struct device_node *np)\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-3511-\ndrivers/net/ethernet/airoha/airoha_eth.c:3512:static int airoha_register_gdm_devices(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_eth.c-3513-{\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=3541=static int airoha_probe(struct platform_device *pdev)\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-3544-\tstruct device_node *np;\ndrivers/net/ethernet/airoha/airoha_eth.c:3545:\tstruct airoha_eth *eth;\ndrivers/net/ethernet/airoha/airoha_eth.c-3546-\tint i, err;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=3673=static void airoha_remove(struct platform_device *pdev)\ndrivers/net/ethernet/airoha/airoha_eth.c-3674-{\ndrivers/net/ethernet/airoha/airoha_eth.c:3675:\tstruct airoha_eth *eth = platform_get_drvdata(pdev);\ndrivers/net/ethernet/airoha/airoha_eth.c-3676-\tint i;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=3845=static int airoha_an7583_get_dev_from_sport(struct airoha_qdma_desc *desc,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-3874-\ndrivers/net/ethernet/airoha/airoha_eth.c:3875:static const struct airoha_eth_soc_data en7581_soc_data = {\ndrivers/net/ethernet/airoha/airoha_eth.c-3876-\t.version = 0x7581,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-3886-\ndrivers/net/ethernet/airoha/airoha_eth.c:3887:static const struct airoha_eth_soc_data an7583_soc_data = {\ndrivers/net/ethernet/airoha/airoha_eth.c-3888-\t.version = 0x7583,\n--\ndrivers/net/ethernet/airoha/airoha_eth.h=532=struct airoha_qdma {\ndrivers/net/ethernet/airoha/airoha_eth.h:533:\tstruct airoha_eth *eth;\ndrivers/net/ethernet/airoha/airoha_eth.h-534-\tvoid __iomem *regs;\n--\ndrivers/net/ethernet/airoha/airoha_eth.h=551=struct airoha_gdm_dev {\n--\ndrivers/net/ethernet/airoha/airoha_eth.h-553-\tstruct airoha_gdm_port *port;\ndrivers/net/ethernet/airoha/airoha_eth.h:554:\tstruct airoha_eth *eth;\ndrivers/net/ethernet/airoha/airoha_eth.h-555-\n--\ndrivers/net/ethernet/airoha/airoha_eth.h=582=struct airoha_ppe {\ndrivers/net/ethernet/airoha/airoha_eth.h-583-\tstruct airoha_ppe_dev dev;\ndrivers/net/ethernet/airoha/airoha_eth.h:584:\tstruct airoha_eth *eth;\ndrivers/net/ethernet/airoha/airoha_eth.h-585-\n--\ndrivers/net/ethernet/airoha/airoha_eth.h-599-\ndrivers/net/ethernet/airoha/airoha_eth.h:600:struct airoha_eth_soc_data {\ndrivers/net/ethernet/airoha/airoha_eth.h-601-\tu16 version;\n--\ndrivers/net/ethernet/airoha/airoha_eth.h-612-\ndrivers/net/ethernet/airoha/airoha_eth.h:613:struct airoha_eth {\ndrivers/net/ethernet/airoha/airoha_eth.h-614-\tstruct device *dev;\ndrivers/net/ethernet/airoha/airoha_eth.h-615-\ndrivers/net/ethernet/airoha/airoha_eth.h:616:\tconst struct airoha_eth_soc_data *soc;\ndrivers/net/ethernet/airoha/airoha_eth.h-617-\n--\ndrivers/net/ethernet/airoha/airoha_eth.h=670=static inline bool airoha_is_lan_gdm_dev(struct airoha_gdm_dev *dev)\n--\ndrivers/net/ethernet/airoha/airoha_eth.h-674-\ndrivers/net/ethernet/airoha/airoha_eth.h:675:static inline bool airoha_is_7581(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_eth.h-676-{\n--\ndrivers/net/ethernet/airoha/airoha_eth.h-679-\ndrivers/net/ethernet/airoha/airoha_eth.h:680:static inline bool airoha_is_7583(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_eth.h-681-{\n--\ndrivers/net/ethernet/airoha/airoha_eth.h=685=int airoha_get_fe_port(struct airoha_gdm_dev *dev);\ndrivers/net/ethernet/airoha/airoha_eth.h:686:bool airoha_is_valid_gdm_dev(struct airoha_eth *eth,\ndrivers/net/ethernet/airoha/airoha_eth.h-687-\t\t\t struct airoha_gdm_dev *dev);\n--\ndrivers/net/ethernet/airoha/airoha_eth.h=700=void airoha_ppe_set_cpu_port(struct airoha_gdm_dev *dev, u8 ppe_id, u8 fport);\ndrivers/net/ethernet/airoha/airoha_eth.h:701:bool airoha_ppe_is_enabled(struct airoha_eth *eth, int index);\ndrivers/net/ethernet/airoha/airoha_eth.h-702-void airoha_ppe_check_skb(struct airoha_ppe_dev *dev, struct sk_buff *skb,\n--\ndrivers/net/ethernet/airoha/airoha_eth.h=704=int airoha_ppe_setup_tc_block_cb(struct airoha_ppe_dev *dev, void *type_data);\ndrivers/net/ethernet/airoha/airoha_eth.h:705:int airoha_ppe_init(struct airoha_eth *eth);\ndrivers/net/ethernet/airoha/airoha_eth.h:706:void airoha_ppe_deinit(struct airoha_eth *eth);\ndrivers/net/ethernet/airoha/airoha_eth.h-707-void airoha_ppe_init_upd_mem(struct airoha_gdm_dev *dev, const u8 *addr);\n--\ndrivers/net/ethernet/airoha/airoha_npu.c-14-\ndrivers/net/ethernet/airoha/airoha_npu.c:15:#include \"airoha_eth.h\"\ndrivers/net/ethernet/airoha/airoha_npu.c-16-\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c-15-#include \"airoha_regs.h\"\ndrivers/net/ethernet/airoha/airoha_ppe.c:16:#include \"airoha_eth.h\"\ndrivers/net/ethernet/airoha/airoha_ppe.c-17-\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c=49=static int airoha_ppe_get_total_num_stats_entries(struct airoha_ppe *ppe)\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c-53-\tif (num_stats \u003e 0) {\ndrivers/net/ethernet/airoha/airoha_ppe.c:54:\t\tstruct airoha_eth *eth = ppe-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_ppe.c-55-\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c=62=static u32 airoha_ppe_get_total_sram_num_entries(struct airoha_ppe *ppe)\ndrivers/net/ethernet/airoha/airoha_ppe.c-63-{\ndrivers/net/ethernet/airoha/airoha_ppe.c:64:\tstruct airoha_eth *eth = ppe-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_ppe.c-65-\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c=69=u32 airoha_ppe_get_total_num_entries(struct airoha_ppe *ppe)\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c-75-\ndrivers/net/ethernet/airoha/airoha_ppe.c:76:bool airoha_ppe_is_enabled(struct airoha_eth *eth, int index)\ndrivers/net/ethernet/airoha/airoha_ppe.c-77-{\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c=90=void airoha_ppe_set_cpu_port(struct airoha_gdm_dev *dev, u8 ppe_id, u8 fport)\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c-92-\tstruct airoha_qdma *qdma = airoha_qdma_deref(dev);\ndrivers/net/ethernet/airoha/airoha_ppe.c:93:\tstruct airoha_eth *eth = dev-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_ppe.c-94-\tu8 qdma_id = qdma - \u0026eth-\u003eqdma[0];\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c=103=void airoha_ppe_set_xmit_frame_size(struct airoha_gdm_dev *dev)\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c-105-\tstruct airoha_gdm_port *port = dev-\u003eport;\ndrivers/net/ethernet/airoha/airoha_ppe.c:106:\tstruct airoha_eth *eth = dev-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_ppe.c-107-\tint i, ppe_id, index;\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c=130=static void airoha_ppe_hw_init(struct airoha_ppe *ppe)\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c-133-\tu32 sram_tb_size, dram_num_entries;\ndrivers/net/ethernet/airoha/airoha_ppe.c:134:\tstruct airoha_eth *eth = ppe-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_ppe.c-135-\tint i, sram_num_stats_entries;\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c=324=static void airoha_ppe_foe_set_bridge_addrs(struct airoha_foe_bridge *br,\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c-332-\ndrivers/net/ethernet/airoha/airoha_ppe.c:333:static int airoha_ppe_foe_entry_prepare(struct airoha_eth *eth,\ndrivers/net/ethernet/airoha/airoha_ppe.c-334-\t\t\t\t\tstruct airoha_foe_entry *hwe,\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c=680=airoha_ppe_foe_get_entry_locked(struct airoha_ppe *ppe, u32 hash)\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c-688-\t\tbool ppe2 = hash \u003e= PPE_SRAM_NUM_ENTRIES;\ndrivers/net/ethernet/airoha/airoha_ppe.c:689:\t\tstruct airoha_eth *eth = ppe-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_ppe.c-690-\t\tu32 val;\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c=761=static int airoha_ppe_foe_commit_entry(struct airoha_ppe *ppe,\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c-767-\tu32 ts = airoha_ppe_get_timestamp(ppe);\ndrivers/net/ethernet/airoha/airoha_ppe.c:768:\tstruct airoha_eth *eth = ppe-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_ppe.c-769-\tstruct airoha_npu *npu;\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c=1071=static int airoha_ppe_entry_idle_time(struct airoha_ppe *ppe,\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c-1078-\ndrivers/net/ethernet/airoha/airoha_ppe.c:1079:static int airoha_ppe_flow_offload_replace(struct airoha_eth *eth,\ndrivers/net/ethernet/airoha/airoha_ppe.c-1080-\t\t\t\t\t struct flow_cls_offload *f)\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c-1278-\ndrivers/net/ethernet/airoha/airoha_ppe.c:1279:static int airoha_ppe_flow_offload_destroy(struct airoha_eth *eth,\ndrivers/net/ethernet/airoha/airoha_ppe.c-1280-\t\t\t\t\t struct flow_cls_offload *f)\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c=1297=void airoha_ppe_foe_entry_get_stats(struct airoha_ppe *ppe, u32 hash,\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c-1299-{\ndrivers/net/ethernet/airoha/airoha_ppe.c:1300:\tstruct airoha_eth *eth = ppe-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_ppe.c-1301-\tint ppe_num_stats_entries;\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c-1331-\ndrivers/net/ethernet/airoha/airoha_ppe.c:1332:static int airoha_ppe_flow_offload_stats(struct airoha_eth *eth,\ndrivers/net/ethernet/airoha/airoha_ppe.c-1333-\t\t\t\t\t struct flow_cls_offload *f)\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c-1357-\ndrivers/net/ethernet/airoha/airoha_ppe.c:1358:static int airoha_ppe_flow_offload_cmd(struct airoha_eth *eth,\ndrivers/net/ethernet/airoha/airoha_ppe.c-1359-\t\t\t\t struct flow_cls_offload *f)\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c=1375=static int airoha_ppe_flush_sram_entries(struct airoha_ppe *ppe)\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c-1392-\ndrivers/net/ethernet/airoha/airoha_ppe.c:1393:static struct airoha_npu *airoha_ppe_npu_get(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_ppe.c-1394-{\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c-1404-\ndrivers/net/ethernet/airoha/airoha_ppe.c:1405:static int airoha_ppe_wait_for_npu_init(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_ppe.c-1406-{\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c-1427-\ndrivers/net/ethernet/airoha/airoha_ppe.c:1428:static int airoha_ppe_offload_setup(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_ppe.c-1429-{\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c=1468=int airoha_ppe_setup_tc_block_cb(struct airoha_ppe_dev *dev, void *type_data)\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c-1470-\tstruct airoha_ppe *ppe = dev-\u003epriv;\ndrivers/net/ethernet/airoha/airoha_ppe.c:1471:\tstruct airoha_eth *eth = ppe-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_ppe.c-1472-\tint err = 0;\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c=1512=void airoha_ppe_init_upd_mem(struct airoha_gdm_dev *dev, const u8 *addr)\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c-1514-\tstruct airoha_gdm_port *port = dev-\u003eport;\ndrivers/net/ethernet/airoha/airoha_ppe.c:1515:\tstruct airoha_eth *eth = dev-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_ppe.c-1516-\tu32 val;\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c=1532=struct airoha_ppe_dev *airoha_ppe_get_dev(struct device *dev)\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c-1535-\tstruct device_node *np;\ndrivers/net/ethernet/airoha/airoha_ppe.c:1536:\tstruct airoha_eth *eth;\ndrivers/net/ethernet/airoha/airoha_ppe.c-1537-\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c=1577=void airoha_ppe_put_dev(struct airoha_ppe_dev *dev)\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c-1579-\tstruct airoha_ppe *ppe = dev-\u003epriv;\ndrivers/net/ethernet/airoha/airoha_ppe.c:1580:\tstruct airoha_eth *eth = ppe-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_ppe.c-1581-\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c=1585=EXPORT_SYMBOL_GPL(airoha_ppe_put_dev);\ndrivers/net/ethernet/airoha/airoha_ppe.c-1586-\ndrivers/net/ethernet/airoha/airoha_ppe.c:1587:int airoha_ppe_init(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_ppe.c-1588-{\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c-1657-\ndrivers/net/ethernet/airoha/airoha_ppe.c:1658:void airoha_ppe_deinit(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_ppe.c-1659-{\n--\ndrivers/net/ethernet/airoha/airoha_ppe_debugfs.c-6-\ndrivers/net/ethernet/airoha/airoha_ppe_debugfs.c:7:#include \"airoha_eth.h\"\ndrivers/net/ethernet/airoha/airoha_ppe_debugfs.c-8-\n"
} |
| 5/2 | 2026/07/21 07:04 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 23155 output: 32 thoughts: 316 Thoughts: **Analyzing the Reachability of the Airoha Ethernet Driver for Fuzzing** Okay, so the driver in question is `CONFIG_NET_AIROHA`. My initial thought is to assess its reachability for fuzzing. It's a platform driver, which immediately raises a flag. Platform drivers often have very specific hardware dependencies. My first instinct is, can we actually trigger its code? And given its an ethernet driver, can it be fuzzed? Ethernet drivers, in my experience, are usually deeply tied to hardware and often necessitate real hardware or a very sophisticated software emulator to function properly. Therefore I'll need to know whether the `airoha_eth` driver is a virtual or hardware-specific driver. A quick check reveals it's designed for Airoha EN7581/AN7583 SoCs, which confirms my hardware-dependency suspicion. It utilizes `platform_driver_register`, solidifying its platform-specific nature. The key question now is, can we create a platform device for it within a virtualized environment? Syzkaller, in theory, can generate these platform devices using mechanisms like `syz_devlink` or by modifying the device tree. But, platform drivers, especially those accessing specific MMIO addresses, tend to crash or fail to probe in a standard QEMU environment without some kind of hardware emulation. Wait a second… does Syzkaller *actually* fuzz this driver? The commit message… says something about a Syzkaller cluster and applied patches. Okay, let's see. The prompt is reminding me that certain code paths are simply inaccessible in virtualized environments like GCE or QEMU, even with software-emulated hardware. This is the crux of the issue. Given that it is a hardware-specific platform driver and based on the information I currently have, if there is no emulator, it is essentially unreachable. Now, the final step will be to explore the availability of any kind of Airoha emulator within QEMU or directly within the kernel. |
| 6/2 | 2026/07/21 07:04 | tool | grepper |
0mArgs:{
"Expression": "airoha",
"PathPrefix": "drivers/net/ethernet/airoha/"
}Results: {
"Output": "\nFull output is too long, showing 500 out of 3656 lines.\nUse more precise expression if possible.\n\ndrivers/net/ethernet/airoha/Makefile-5-\ndrivers/net/ethernet/airoha/Makefile:6:obj-$(CONFIG_NET_AIROHA) += airoha-eth.o\ndrivers/net/ethernet/airoha/Makefile:7:airoha-eth-y := airoha_eth.o airoha_ppe.o\ndrivers/net/ethernet/airoha/Makefile:8:airoha-eth-$(CONFIG_DEBUG_FS) += airoha_ppe_debugfs.o\ndrivers/net/ethernet/airoha/Makefile:9:obj-$(CONFIG_NET_AIROHA_NPU) += airoha_npu.o\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-16-\ndrivers/net/ethernet/airoha/airoha_eth.c:17:#include \"airoha_regs.h\"\ndrivers/net/ethernet/airoha/airoha_eth.c:18:#include \"airoha_eth.h\"\ndrivers/net/ethernet/airoha/airoha_eth.c-19-\ndrivers/net/ethernet/airoha/airoha_eth.c:20:u32 airoha_rr(void __iomem *base, u32 offset)\ndrivers/net/ethernet/airoha/airoha_eth.c-21-{\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-24-\ndrivers/net/ethernet/airoha/airoha_eth.c:25:void airoha_wr(void __iomem *base, u32 offset, u32 val)\ndrivers/net/ethernet/airoha/airoha_eth.c-26-{\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-29-\ndrivers/net/ethernet/airoha/airoha_eth.c:30:u32 airoha_rmw(void __iomem *base, u32 offset, u32 mask, u32 val)\ndrivers/net/ethernet/airoha/airoha_eth.c-31-{\ndrivers/net/ethernet/airoha/airoha_eth.c:32:\tval |= (airoha_rr(base, offset) \u0026 ~mask);\ndrivers/net/ethernet/airoha/airoha_eth.c:33:\tairoha_wr(base, offset, val);\ndrivers/net/ethernet/airoha/airoha_eth.c-34-\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-37-\ndrivers/net/ethernet/airoha/airoha_eth.c:38:static void airoha_qdma_set_irqmask(struct airoha_irq_bank *irq_bank,\ndrivers/net/ethernet/airoha/airoha_eth.c-39-\t\t\t\t int index, u32 clear, u32 set)\ndrivers/net/ethernet/airoha/airoha_eth.c-40-{\ndrivers/net/ethernet/airoha/airoha_eth.c:41:\tstruct airoha_qdma *qdma = irq_bank-\u003eqdma;\ndrivers/net/ethernet/airoha/airoha_eth.c-42-\tint bank = irq_bank - \u0026qdma-\u003eirq_banks[0];\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-51-\tirq_bank-\u003eirqmask[index] |= set;\ndrivers/net/ethernet/airoha/airoha_eth.c:52:\tairoha_qdma_wr(qdma, REG_INT_ENABLE(bank, index),\ndrivers/net/ethernet/airoha/airoha_eth.c-53-\t\t irq_bank-\u003eirqmask[index]);\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-56-\t */\ndrivers/net/ethernet/airoha/airoha_eth.c:57:\tairoha_qdma_rr(qdma, REG_INT_ENABLE(bank, index));\ndrivers/net/ethernet/airoha/airoha_eth.c-58-\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-61-\ndrivers/net/ethernet/airoha/airoha_eth.c:62:static void airoha_qdma_irq_enable(struct airoha_irq_bank *irq_bank,\ndrivers/net/ethernet/airoha/airoha_eth.c-63-\t\t\t\t int index, u32 mask)\ndrivers/net/ethernet/airoha/airoha_eth.c-64-{\ndrivers/net/ethernet/airoha/airoha_eth.c:65:\tairoha_qdma_set_irqmask(irq_bank, index, 0, mask);\ndrivers/net/ethernet/airoha/airoha_eth.c-66-}\ndrivers/net/ethernet/airoha/airoha_eth.c-67-\ndrivers/net/ethernet/airoha/airoha_eth.c:68:static void airoha_qdma_irq_disable(struct airoha_irq_bank *irq_bank,\ndrivers/net/ethernet/airoha/airoha_eth.c-69-\t\t\t\t int index, u32 mask)\ndrivers/net/ethernet/airoha/airoha_eth.c-70-{\ndrivers/net/ethernet/airoha/airoha_eth.c:71:\tairoha_qdma_set_irqmask(irq_bank, index, mask, 0);\ndrivers/net/ethernet/airoha/airoha_eth.c-72-}\ndrivers/net/ethernet/airoha/airoha_eth.c-73-\ndrivers/net/ethernet/airoha/airoha_eth.c:74:static int airoha_set_macaddr(struct airoha_gdm_dev *dev, const u8 *addr)\ndrivers/net/ethernet/airoha/airoha_eth.c-75-{\ndrivers/net/ethernet/airoha/airoha_eth.c-76-\tu8 ref_addr[ETH_ALEN] __aligned(2);\ndrivers/net/ethernet/airoha/airoha_eth.c:77:\tstruct airoha_eth *eth = dev-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_eth.c-78-\tu32 reg, val, lmin, lmax;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-85-\tfor (i = 0; i \u003c ARRAY_SIZE(eth-\u003eports); i++) {\ndrivers/net/ethernet/airoha/airoha_eth.c:86:\t\tstruct airoha_gdm_port *port = eth-\u003eports[i];\ndrivers/net/ethernet/airoha/airoha_eth.c-87-\t\tint j;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-92-\t\tfor (j = 0; j \u003c ARRAY_SIZE(port-\u003edevs); j++) {\ndrivers/net/ethernet/airoha/airoha_eth.c:93:\t\t\tstruct airoha_gdm_dev *iter_dev;\ndrivers/net/ethernet/airoha/airoha_eth.c-94-\t\t\tstruct net_device *netdev;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-99-\ndrivers/net/ethernet/airoha/airoha_eth.c:100:\t\t\tif (airoha_is_lan_gdm_dev(iter_dev) !=\ndrivers/net/ethernet/airoha/airoha_eth.c:101:\t\t\t airoha_is_lan_gdm_dev(dev))\ndrivers/net/ethernet/airoha/airoha_eth.c-102-\t\t\t\tcontinue;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-133-\ndrivers/net/ethernet/airoha/airoha_eth.c:134:\treg = airoha_is_lan_gdm_dev(dev) ? REG_FE_LAN_MAC_H : REG_FE_WAN_MAC_H;\ndrivers/net/ethernet/airoha/airoha_eth.c-135-\tval = (addr[0] \u003c\u003c 16) | (addr[1] \u003c\u003c 8) | addr[2];\ndrivers/net/ethernet/airoha/airoha_eth.c:136:\tairoha_fe_wr(eth, reg, val);\ndrivers/net/ethernet/airoha/airoha_eth.c-137-\ndrivers/net/ethernet/airoha/airoha_eth.c:138:\tairoha_fe_wr(eth, REG_FE_MAC_LMIN(reg), lmin);\ndrivers/net/ethernet/airoha/airoha_eth.c:139:\tairoha_fe_wr(eth, REG_FE_MAC_LMAX(reg), lmax);\ndrivers/net/ethernet/airoha/airoha_eth.c-140-\ndrivers/net/ethernet/airoha/airoha_eth.c:141:\tairoha_ppe_init_upd_mem(dev, addr);\ndrivers/net/ethernet/airoha/airoha_eth.c-142-\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-145-\ndrivers/net/ethernet/airoha/airoha_eth.c:146:static void airoha_set_gdm_port_fwd_cfg(struct airoha_eth *eth, u32 addr,\ndrivers/net/ethernet/airoha/airoha_eth.c-147-\t\t\t\t\tu32 val)\ndrivers/net/ethernet/airoha/airoha_eth.c-148-{\ndrivers/net/ethernet/airoha/airoha_eth.c:149:\tairoha_fe_rmw(eth, addr, GDM_OCFQ_MASK,\ndrivers/net/ethernet/airoha/airoha_eth.c-150-\t\t FIELD_PREP(GDM_OCFQ_MASK, val));\ndrivers/net/ethernet/airoha/airoha_eth.c:151:\tairoha_fe_rmw(eth, addr, GDM_MCFQ_MASK,\ndrivers/net/ethernet/airoha/airoha_eth.c-152-\t\t FIELD_PREP(GDM_MCFQ_MASK, val));\ndrivers/net/ethernet/airoha/airoha_eth.c:153:\tairoha_fe_rmw(eth, addr, GDM_BCFQ_MASK,\ndrivers/net/ethernet/airoha/airoha_eth.c-154-\t\t FIELD_PREP(GDM_BCFQ_MASK, val));\ndrivers/net/ethernet/airoha/airoha_eth.c:155:\tairoha_fe_rmw(eth, addr, GDM_UCFQ_MASK,\ndrivers/net/ethernet/airoha/airoha_eth.c-156-\t\t FIELD_PREP(GDM_UCFQ_MASK, val));\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-158-\ndrivers/net/ethernet/airoha/airoha_eth.c:159:static int airoha_set_vip_for_gdm_port(struct airoha_gdm_dev *dev, bool enable)\ndrivers/net/ethernet/airoha/airoha_eth.c-160-{\ndrivers/net/ethernet/airoha/airoha_eth.c:161:\tstruct airoha_gdm_port *port = dev-\u003eport;\ndrivers/net/ethernet/airoha/airoha_eth.c:162:\tstruct airoha_eth *eth = dev-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_eth.c-163-\tu32 vip_port;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-166-\tif (enable) {\ndrivers/net/ethernet/airoha/airoha_eth.c:167:\t\tairoha_fe_set(eth, REG_FE_VIP_PORT_EN, vip_port);\ndrivers/net/ethernet/airoha/airoha_eth.c:168:\t\tairoha_fe_set(eth, REG_FE_IFC_PORT_EN, vip_port);\ndrivers/net/ethernet/airoha/airoha_eth.c-169-\t} else {\ndrivers/net/ethernet/airoha/airoha_eth.c:170:\t\tairoha_fe_clear(eth, REG_FE_VIP_PORT_EN, vip_port);\ndrivers/net/ethernet/airoha/airoha_eth.c:171:\t\tairoha_fe_clear(eth, REG_FE_IFC_PORT_EN, vip_port);\ndrivers/net/ethernet/airoha/airoha_eth.c-172-\t}\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-176-\ndrivers/net/ethernet/airoha/airoha_eth.c:177:static void airoha_fe_maccr_init(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_eth.c-178-{\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-181-\tfor (p = 1; p \u003c= ARRAY_SIZE(eth-\u003eports); p++) {\ndrivers/net/ethernet/airoha/airoha_eth.c:182:\t\tairoha_fe_set(eth, REG_GDM_FWD_CFG(p),\ndrivers/net/ethernet/airoha/airoha_eth.c-183-\t\t\t GDM_TCP_CKSUM_MASK | GDM_UDP_CKSUM_MASK |\ndrivers/net/ethernet/airoha/airoha_eth.c-184-\t\t\t GDM_IP4_CKSUM_MASK | GDM_DROP_CRC_ERR_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c:185:\t\tairoha_fe_rmw(eth, REG_GDM_LEN_CFG(p),\ndrivers/net/ethernet/airoha/airoha_eth.c-186-\t\t\t GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-190-\ndrivers/net/ethernet/airoha/airoha_eth.c:191:\tairoha_fe_rmw(eth, REG_CDM_VLAN_CTRL(1), CDM_VLAN_MASK,\ndrivers/net/ethernet/airoha/airoha_eth.c-192-\t\t FIELD_PREP(CDM_VLAN_MASK, 0x8100));\ndrivers/net/ethernet/airoha/airoha_eth.c-193-\ndrivers/net/ethernet/airoha/airoha_eth.c:194:\tairoha_fe_set(eth, REG_FE_CPORT_CFG, FE_CPORT_PAD);\ndrivers/net/ethernet/airoha/airoha_eth.c-195-}\ndrivers/net/ethernet/airoha/airoha_eth.c-196-\ndrivers/net/ethernet/airoha/airoha_eth.c:197:static void airoha_fe_vip_setup(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_eth.c-198-{\ndrivers/net/ethernet/airoha/airoha_eth.c:199:\tairoha_fe_wr(eth, REG_FE_VIP_PATN(3), ETH_P_PPP_DISC);\ndrivers/net/ethernet/airoha/airoha_eth.c:200:\tairoha_fe_wr(eth, REG_FE_VIP_EN(3), PATN_FCPU_EN_MASK | PATN_EN_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c-201-\ndrivers/net/ethernet/airoha/airoha_eth.c:202:\tairoha_fe_wr(eth, REG_FE_VIP_PATN(4), PPP_LCP);\ndrivers/net/ethernet/airoha/airoha_eth.c:203:\tairoha_fe_wr(eth, REG_FE_VIP_EN(4),\ndrivers/net/ethernet/airoha/airoha_eth.c-204-\t\t PATN_FCPU_EN_MASK | FIELD_PREP(PATN_TYPE_MASK, 1) |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-206-\ndrivers/net/ethernet/airoha/airoha_eth.c:207:\tairoha_fe_wr(eth, REG_FE_VIP_PATN(6), PPP_IPCP);\ndrivers/net/ethernet/airoha/airoha_eth.c:208:\tairoha_fe_wr(eth, REG_FE_VIP_EN(6),\ndrivers/net/ethernet/airoha/airoha_eth.c-209-\t\t PATN_FCPU_EN_MASK | FIELD_PREP(PATN_TYPE_MASK, 1) |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-211-\ndrivers/net/ethernet/airoha/airoha_eth.c:212:\tairoha_fe_wr(eth, REG_FE_VIP_PATN(7), PPP_CHAP);\ndrivers/net/ethernet/airoha/airoha_eth.c:213:\tairoha_fe_wr(eth, REG_FE_VIP_EN(7),\ndrivers/net/ethernet/airoha/airoha_eth.c-214-\t\t PATN_FCPU_EN_MASK | FIELD_PREP(PATN_TYPE_MASK, 1) |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-217-\t/* BOOTP (0x43) */\ndrivers/net/ethernet/airoha/airoha_eth.c:218:\tairoha_fe_wr(eth, REG_FE_VIP_PATN(8), 0x43);\ndrivers/net/ethernet/airoha/airoha_eth.c:219:\tairoha_fe_wr(eth, REG_FE_VIP_EN(8),\ndrivers/net/ethernet/airoha/airoha_eth.c-220-\t\t PATN_FCPU_EN_MASK | PATN_SP_EN_MASK |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-223-\t/* BOOTP (0x44) */\ndrivers/net/ethernet/airoha/airoha_eth.c:224:\tairoha_fe_wr(eth, REG_FE_VIP_PATN(9), 0x44);\ndrivers/net/ethernet/airoha/airoha_eth.c:225:\tairoha_fe_wr(eth, REG_FE_VIP_EN(9),\ndrivers/net/ethernet/airoha/airoha_eth.c-226-\t\t PATN_FCPU_EN_MASK | PATN_SP_EN_MASK |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-229-\t/* ISAKMP */\ndrivers/net/ethernet/airoha/airoha_eth.c:230:\tairoha_fe_wr(eth, REG_FE_VIP_PATN(10), 0x1f401f4);\ndrivers/net/ethernet/airoha/airoha_eth.c:231:\tairoha_fe_wr(eth, REG_FE_VIP_EN(10),\ndrivers/net/ethernet/airoha/airoha_eth.c-232-\t\t PATN_FCPU_EN_MASK | PATN_DP_EN_MASK | PATN_SP_EN_MASK |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-234-\ndrivers/net/ethernet/airoha/airoha_eth.c:235:\tairoha_fe_wr(eth, REG_FE_VIP_PATN(11), PPP_IPV6CP);\ndrivers/net/ethernet/airoha/airoha_eth.c:236:\tairoha_fe_wr(eth, REG_FE_VIP_EN(11),\ndrivers/net/ethernet/airoha/airoha_eth.c-237-\t\t PATN_FCPU_EN_MASK | FIELD_PREP(PATN_TYPE_MASK, 1) |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-240-\t/* DHCPv6 */\ndrivers/net/ethernet/airoha/airoha_eth.c:241:\tairoha_fe_wr(eth, REG_FE_VIP_PATN(12), 0x2220223);\ndrivers/net/ethernet/airoha/airoha_eth.c:242:\tairoha_fe_wr(eth, REG_FE_VIP_EN(12),\ndrivers/net/ethernet/airoha/airoha_eth.c-243-\t\t PATN_FCPU_EN_MASK | PATN_DP_EN_MASK | PATN_SP_EN_MASK |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-245-\ndrivers/net/ethernet/airoha/airoha_eth.c:246:\tairoha_fe_wr(eth, REG_FE_VIP_PATN(19), PPP_PAP);\ndrivers/net/ethernet/airoha/airoha_eth.c:247:\tairoha_fe_wr(eth, REG_FE_VIP_EN(19),\ndrivers/net/ethernet/airoha/airoha_eth.c-248-\t\t PATN_FCPU_EN_MASK | FIELD_PREP(PATN_TYPE_MASK, 1) |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-251-\t/* ETH-\u003eETH_P_1905 (0x893a) */\ndrivers/net/ethernet/airoha/airoha_eth.c:252:\tairoha_fe_wr(eth, REG_FE_VIP_PATN(20), 0x893a);\ndrivers/net/ethernet/airoha/airoha_eth.c:253:\tairoha_fe_wr(eth, REG_FE_VIP_EN(20),\ndrivers/net/ethernet/airoha/airoha_eth.c-254-\t\t PATN_FCPU_EN_MASK | PATN_EN_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c-255-\ndrivers/net/ethernet/airoha/airoha_eth.c:256:\tairoha_fe_wr(eth, REG_FE_VIP_PATN(21), ETH_P_LLDP);\ndrivers/net/ethernet/airoha/airoha_eth.c:257:\tairoha_fe_wr(eth, REG_FE_VIP_EN(21),\ndrivers/net/ethernet/airoha/airoha_eth.c-258-\t\t PATN_FCPU_EN_MASK | PATN_EN_MASK);\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-260-\ndrivers/net/ethernet/airoha/airoha_eth.c:261:static u32 airoha_fe_get_pse_queue_rsv_pages(struct airoha_eth *eth,\ndrivers/net/ethernet/airoha/airoha_eth.c-262-\t\t\t\t\t u32 port, u32 queue)\ndrivers/net/ethernet/airoha/airoha_eth.c-263-{\ndrivers/net/ethernet/airoha/airoha_eth.c:264:\tairoha_fe_rmw(eth, REG_FE_PSE_QUEUE_CFG_WR,\ndrivers/net/ethernet/airoha/airoha_eth.c-265-\t\t PSE_CFG_PORT_ID_MASK | PSE_CFG_QUEUE_ID_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-268-\ndrivers/net/ethernet/airoha/airoha_eth.c:269:\treturn airoha_fe_get(eth, REG_FE_PSE_QUEUE_CFG_VAL,\ndrivers/net/ethernet/airoha/airoha_eth.c-270-\t\t\t PSE_CFG_OQ_RSV_MASK);\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-272-\ndrivers/net/ethernet/airoha/airoha_eth.c:273:static void airoha_fe_set_pse_queue_rsv_pages(struct airoha_eth *eth,\ndrivers/net/ethernet/airoha/airoha_eth.c-274-\t\t\t\t\t u32 port, u32 queue, u32 val)\ndrivers/net/ethernet/airoha/airoha_eth.c-275-{\ndrivers/net/ethernet/airoha/airoha_eth.c:276:\tairoha_fe_rmw(eth, REG_FE_PSE_QUEUE_CFG_VAL, PSE_CFG_OQ_RSV_MASK,\ndrivers/net/ethernet/airoha/airoha_eth.c-277-\t\t FIELD_PREP(PSE_CFG_OQ_RSV_MASK, val));\ndrivers/net/ethernet/airoha/airoha_eth.c:278:\tairoha_fe_rmw(eth, REG_FE_PSE_QUEUE_CFG_WR,\ndrivers/net/ethernet/airoha/airoha_eth.c-279-\t\t PSE_CFG_PORT_ID_MASK | PSE_CFG_QUEUE_ID_MASK |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-285-\ndrivers/net/ethernet/airoha/airoha_eth.c:286:static u32 airoha_fe_get_pse_all_rsv(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_eth.c-287-{\ndrivers/net/ethernet/airoha/airoha_eth.c:288:\treturn airoha_fe_get(eth, REG_FE_PSE_BUF_SET, PSE_ALLRSV_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c-289-}\ndrivers/net/ethernet/airoha/airoha_eth.c-290-\ndrivers/net/ethernet/airoha/airoha_eth.c:291:static int airoha_fe_set_pse_oq_rsv(struct airoha_eth *eth,\ndrivers/net/ethernet/airoha/airoha_eth.c-292-\t\t\t\t u32 port, u32 queue, u32 val)\ndrivers/net/ethernet/airoha/airoha_eth.c-293-{\ndrivers/net/ethernet/airoha/airoha_eth.c:294:\tu32 orig_val = airoha_fe_get_pse_queue_rsv_pages(eth, port, queue);\ndrivers/net/ethernet/airoha/airoha_eth.c-295-\tu32 tmp, all_rsv, fq_limit;\ndrivers/net/ethernet/airoha/airoha_eth.c-296-\ndrivers/net/ethernet/airoha/airoha_eth.c:297:\tairoha_fe_set_pse_queue_rsv_pages(eth, port, queue, val);\ndrivers/net/ethernet/airoha/airoha_eth.c-298-\ndrivers/net/ethernet/airoha/airoha_eth.c-299-\t/* modify all rsv */\ndrivers/net/ethernet/airoha/airoha_eth.c:300:\tall_rsv = airoha_fe_get_pse_all_rsv(eth);\ndrivers/net/ethernet/airoha/airoha_eth.c-301-\tall_rsv += (val - orig_val);\ndrivers/net/ethernet/airoha/airoha_eth.c:302:\tairoha_fe_rmw(eth, REG_FE_PSE_BUF_SET, PSE_ALLRSV_MASK,\ndrivers/net/ethernet/airoha/airoha_eth.c-303-\t\t FIELD_PREP(PSE_ALLRSV_MASK, all_rsv));\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-305-\t/* modify hthd */\ndrivers/net/ethernet/airoha/airoha_eth.c:306:\tfq_limit = airoha_fe_get(eth, PSE_FQ_CFG, PSE_FQ_LIMIT_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c-307-\ttmp = fq_limit - all_rsv - 0x20;\ndrivers/net/ethernet/airoha/airoha_eth.c:308:\tairoha_fe_rmw(eth, REG_PSE_SHARE_USED_THD,\ndrivers/net/ethernet/airoha/airoha_eth.c-309-\t\t PSE_SHARE_USED_HTHD_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-312-\ttmp = fq_limit - all_rsv - 0x100;\ndrivers/net/ethernet/airoha/airoha_eth.c:313:\tairoha_fe_rmw(eth, REG_PSE_SHARE_USED_THD,\ndrivers/net/ethernet/airoha/airoha_eth.c-314-\t\t PSE_SHARE_USED_MTHD_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-316-\ttmp = (3 * tmp) \u003e\u003e 2;\ndrivers/net/ethernet/airoha/airoha_eth.c:317:\tairoha_fe_rmw(eth, REG_FE_PSE_BUF_SET,\ndrivers/net/ethernet/airoha/airoha_eth.c-318-\t\t PSE_SHARE_USED_LTHD_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-323-\ndrivers/net/ethernet/airoha/airoha_eth.c:324:static void airoha_fe_pse_ports_init(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_eth.c-325-{\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-340-\ndrivers/net/ethernet/airoha/airoha_eth.c:341:\tif (airoha_ppe_is_enabled(eth, 1)) {\ndrivers/net/ethernet/airoha/airoha_eth.c-342-\t\tu32 all_rsv;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-344-\t\t/* hw misses PPE2 oq rsv */\ndrivers/net/ethernet/airoha/airoha_eth.c:345:\t\tall_rsv = airoha_fe_get_pse_all_rsv(eth);\ndrivers/net/ethernet/airoha/airoha_eth.c-346-\t\tall_rsv += PSE_RSV_PAGES *\ndrivers/net/ethernet/airoha/airoha_eth.c-347-\t\t\t pse_port_num_queues[FE_PSE_PORT_PPE2];\ndrivers/net/ethernet/airoha/airoha_eth.c:348:\t\tairoha_fe_rmw(eth, REG_FE_PSE_BUF_SET, PSE_ALLRSV_MASK,\ndrivers/net/ethernet/airoha/airoha_eth.c-349-\t\t\t FIELD_PREP(PSE_ALLRSV_MASK, all_rsv));\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-353-\tfor (q = 0; q \u003c pse_port_num_queues[FE_PSE_PORT_CDM1]; q++)\ndrivers/net/ethernet/airoha/airoha_eth.c:354:\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM1, q,\ndrivers/net/ethernet/airoha/airoha_eth.c-355-\t\t\t\t\t PSE_QUEUE_RSV_PAGES);\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-357-\tfor (q = 0; q \u003c pse_port_num_queues[FE_PSE_PORT_GDM1]; q++)\ndrivers/net/ethernet/airoha/airoha_eth.c:358:\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM1, q,\ndrivers/net/ethernet/airoha/airoha_eth.c-359-\t\t\t\t\t PSE_QUEUE_RSV_PAGES);\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-361-\tfor (q = 6; q \u003c pse_port_num_queues[FE_PSE_PORT_GDM2]; q++)\ndrivers/net/ethernet/airoha/airoha_eth.c:362:\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM2, q, 0);\ndrivers/net/ethernet/airoha/airoha_eth.c-363-\t/* GDM3 */\ndrivers/net/ethernet/airoha/airoha_eth.c-364-\tfor (q = 0; q \u003c pse_port_num_queues[FE_PSE_PORT_GDM3]; q++)\ndrivers/net/ethernet/airoha/airoha_eth.c:365:\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM3, q,\ndrivers/net/ethernet/airoha/airoha_eth.c-366-\t\t\t\t\t PSE_QUEUE_RSV_PAGES);\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-369-\t\tif (q \u003c pse_port_num_queues[FE_PSE_PORT_PPE1] / 2)\ndrivers/net/ethernet/airoha/airoha_eth.c:370:\t\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE1, q,\ndrivers/net/ethernet/airoha/airoha_eth.c-371-\t\t\t\t\t\t PSE_QUEUE_RSV_PAGES);\ndrivers/net/ethernet/airoha/airoha_eth.c-372-\t\telse\ndrivers/net/ethernet/airoha/airoha_eth.c:373:\t\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE1, q, 0);\ndrivers/net/ethernet/airoha/airoha_eth.c-374-\t}\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-376-\tfor (q = 0; q \u003c pse_port_num_queues[FE_PSE_PORT_CDM2]; q++)\ndrivers/net/ethernet/airoha/airoha_eth.c:377:\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM2, q,\ndrivers/net/ethernet/airoha/airoha_eth.c-378-\t\t\t\t\t PSE_QUEUE_RSV_PAGES);\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-380-\tfor (q = 0; q \u003c pse_port_num_queues[FE_PSE_PORT_CDM3] - 1; q++)\ndrivers/net/ethernet/airoha/airoha_eth.c:381:\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM3, q, 0);\ndrivers/net/ethernet/airoha/airoha_eth.c-382-\t/* CDM4 */\ndrivers/net/ethernet/airoha/airoha_eth.c-383-\tfor (q = 4; q \u003c pse_port_num_queues[FE_PSE_PORT_CDM4]; q++)\ndrivers/net/ethernet/airoha/airoha_eth.c:384:\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM4, q,\ndrivers/net/ethernet/airoha/airoha_eth.c-385-\t\t\t\t\t PSE_QUEUE_RSV_PAGES);\ndrivers/net/ethernet/airoha/airoha_eth.c:386:\tif (airoha_ppe_is_enabled(eth, 1)) {\ndrivers/net/ethernet/airoha/airoha_eth.c-387-\t\t/* PPE2 */\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-389-\t\t\tif (q \u003c pse_port_num_queues[FE_PSE_PORT_PPE2] / 2)\ndrivers/net/ethernet/airoha/airoha_eth.c:390:\t\t\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE2,\ndrivers/net/ethernet/airoha/airoha_eth.c-391-\t\t\t\t\t\t\t q,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-393-\t\t\telse\ndrivers/net/ethernet/airoha/airoha_eth.c:394:\t\t\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE2,\ndrivers/net/ethernet/airoha/airoha_eth.c-395-\t\t\t\t\t\t\t q, 0);\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-399-\tfor (q = 0; q \u003c pse_port_num_queues[FE_PSE_PORT_GDM4]; q++)\ndrivers/net/ethernet/airoha/airoha_eth.c:400:\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM4, q,\ndrivers/net/ethernet/airoha/airoha_eth.c-401-\t\t\t\t\t PSE_QUEUE_RSV_PAGES);\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-403-\tfor (q = 0; q \u003c pse_port_num_queues[FE_PSE_PORT_CDM5]; q++)\ndrivers/net/ethernet/airoha/airoha_eth.c:404:\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM5, q,\ndrivers/net/ethernet/airoha/airoha_eth.c-405-\t\t\t\t\t PSE_QUEUE_RSV_PAGES);\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-407-\ndrivers/net/ethernet/airoha/airoha_eth.c:408:static int airoha_fe_mc_vlan_clear(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_eth.c-409-{\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-415-\ndrivers/net/ethernet/airoha/airoha_eth.c:416:\t\tairoha_fe_wr(eth, REG_MC_VLAN_DATA, 0x0);\ndrivers/net/ethernet/airoha/airoha_eth.c-417-\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-419-\t\t MC_VLAN_CFG_TABLE_SEL_MASK | MC_VLAN_CFG_RW_MASK;\ndrivers/net/ethernet/airoha/airoha_eth.c:420:\t\tairoha_fe_wr(eth, REG_MC_VLAN_CFG, val);\ndrivers/net/ethernet/airoha/airoha_eth.c:421:\t\terr = read_poll_timeout(airoha_fe_rr, val,\ndrivers/net/ethernet/airoha/airoha_eth.c-422-\t\t\t\t\tval \u0026 MC_VLAN_CFG_CMD_DONE_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-428-\t\tfor (j = 0; j \u003c AIROHA_FE_MC_MAX_VLAN_PORT; j++) {\ndrivers/net/ethernet/airoha/airoha_eth.c:429:\t\t\tairoha_fe_wr(eth, REG_MC_VLAN_DATA, 0x0);\ndrivers/net/ethernet/airoha/airoha_eth.c-430-\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-433-\t\t\t MC_VLAN_CFG_RW_MASK;\ndrivers/net/ethernet/airoha/airoha_eth.c:434:\t\t\tairoha_fe_wr(eth, REG_MC_VLAN_CFG, val);\ndrivers/net/ethernet/airoha/airoha_eth.c:435:\t\t\terr = read_poll_timeout(airoha_fe_rr, val,\ndrivers/net/ethernet/airoha/airoha_eth.c-436-\t\t\t\t\t\tval \u0026 MC_VLAN_CFG_CMD_DONE_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-447-\ndrivers/net/ethernet/airoha/airoha_eth.c:448:static void airoha_fe_crsn_qsel_init(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_eth.c-449-{\ndrivers/net/ethernet/airoha/airoha_eth.c-450-\t/* CDM1_CRSN_QSEL */\ndrivers/net/ethernet/airoha/airoha_eth.c:451:\tairoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(1, CRSN_22 \u003e\u003e 2),\ndrivers/net/ethernet/airoha/airoha_eth.c-452-\t\t CDM_CRSN_QSEL_REASON_MASK(CRSN_22),\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-454-\t\t\t\t CDM_CRSN_QSEL_Q1));\ndrivers/net/ethernet/airoha/airoha_eth.c:455:\tairoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(1, CRSN_08 \u003e\u003e 2),\ndrivers/net/ethernet/airoha/airoha_eth.c-456-\t\t CDM_CRSN_QSEL_REASON_MASK(CRSN_08),\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-458-\t\t\t\t CDM_CRSN_QSEL_Q1));\ndrivers/net/ethernet/airoha/airoha_eth.c:459:\tairoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(1, CRSN_21 \u003e\u003e 2),\ndrivers/net/ethernet/airoha/airoha_eth.c-460-\t\t CDM_CRSN_QSEL_REASON_MASK(CRSN_21),\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-462-\t\t\t\t CDM_CRSN_QSEL_Q1));\ndrivers/net/ethernet/airoha/airoha_eth.c:463:\tairoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(1, CRSN_24 \u003e\u003e 2),\ndrivers/net/ethernet/airoha/airoha_eth.c-464-\t\t CDM_CRSN_QSEL_REASON_MASK(CRSN_24),\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-466-\t\t\t\t CDM_CRSN_QSEL_Q6));\ndrivers/net/ethernet/airoha/airoha_eth.c:467:\tairoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(1, CRSN_25 \u003e\u003e 2),\ndrivers/net/ethernet/airoha/airoha_eth.c-468-\t\t CDM_CRSN_QSEL_REASON_MASK(CRSN_25),\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-471-\t/* CDM2_CRSN_QSEL */\ndrivers/net/ethernet/airoha/airoha_eth.c:472:\tairoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(2, CRSN_08 \u003e\u003e 2),\ndrivers/net/ethernet/airoha/airoha_eth.c-473-\t\t CDM_CRSN_QSEL_REASON_MASK(CRSN_08),\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-475-\t\t\t\t CDM_CRSN_QSEL_Q1));\ndrivers/net/ethernet/airoha/airoha_eth.c:476:\tairoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(2, CRSN_21 \u003e\u003e 2),\ndrivers/net/ethernet/airoha/airoha_eth.c-477-\t\t CDM_CRSN_QSEL_REASON_MASK(CRSN_21),\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-479-\t\t\t\t CDM_CRSN_QSEL_Q1));\ndrivers/net/ethernet/airoha/airoha_eth.c:480:\tairoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(2, CRSN_22 \u003e\u003e 2),\ndrivers/net/ethernet/airoha/airoha_eth.c-481-\t\t CDM_CRSN_QSEL_REASON_MASK(CRSN_22),\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-483-\t\t\t\t CDM_CRSN_QSEL_Q1));\ndrivers/net/ethernet/airoha/airoha_eth.c:484:\tairoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(2, CRSN_24 \u003e\u003e 2),\ndrivers/net/ethernet/airoha/airoha_eth.c-485-\t\t CDM_CRSN_QSEL_REASON_MASK(CRSN_24),\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-487-\t\t\t\t CDM_CRSN_QSEL_Q6));\ndrivers/net/ethernet/airoha/airoha_eth.c:488:\tairoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(2, CRSN_25 \u003e\u003e 2),\ndrivers/net/ethernet/airoha/airoha_eth.c-489-\t\t CDM_CRSN_QSEL_REASON_MASK(CRSN_25),\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-493-\ndrivers/net/ethernet/airoha/airoha_eth.c:494:static int airoha_fe_init(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_eth.c-495-{\ndrivers/net/ethernet/airoha/airoha_eth.c:496:\tairoha_fe_maccr_init(eth);\ndrivers/net/ethernet/airoha/airoha_eth.c-497-\ndrivers/net/ethernet/airoha/airoha_eth.c-498-\t/* PSE IQ reserve */\ndrivers/net/ethernet/airoha/airoha_eth.c:499:\tairoha_fe_rmw(eth, REG_PSE_IQ_REV1, PSE_IQ_RES1_P2_MASK,\ndrivers/net/ethernet/airoha/airoha_eth.c-500-\t\t FIELD_PREP(PSE_IQ_RES1_P2_MASK, 0x10));\ndrivers/net/ethernet/airoha/airoha_eth.c:501:\tairoha_fe_rmw(eth, REG_PSE_IQ_REV2,\ndrivers/net/ethernet/airoha/airoha_eth.c-502-\t\t PSE_IQ_RES2_P5_MASK | PSE_IQ_RES2_P4_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-506-\t/* enable FE copy engine for KA/DPI */\ndrivers/net/ethernet/airoha/airoha_eth.c:507:\tairoha_fe_wr(eth, REG_FE_PCE_CFG, PCE_DPI_EN_MASK | PCE_KA_EN_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c-508-\t/* set vip queue selection to ring 1 */\ndrivers/net/ethernet/airoha/airoha_eth.c:509:\tairoha_fe_rmw(eth, REG_CDM_FWD_CFG(1), CDM_VIP_QSEL_MASK,\ndrivers/net/ethernet/airoha/airoha_eth.c-510-\t\t FIELD_PREP(CDM_VIP_QSEL_MASK, 0x4));\ndrivers/net/ethernet/airoha/airoha_eth.c:511:\tairoha_fe_rmw(eth, REG_CDM_FWD_CFG(2), CDM_VIP_QSEL_MASK,\ndrivers/net/ethernet/airoha/airoha_eth.c-512-\t\t FIELD_PREP(CDM_VIP_QSEL_MASK, 0x4));\ndrivers/net/ethernet/airoha/airoha_eth.c-513-\t/* set GDM4 source interface offset to 8 */\ndrivers/net/ethernet/airoha/airoha_eth.c:514:\tairoha_fe_rmw(eth, REG_GDM_SRC_PORT_SET(4),\ndrivers/net/ethernet/airoha/airoha_eth.c-515-\t\t GDM_SPORT_OFF2_MASK |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-522-\t/* set PSE Page as 128B */\ndrivers/net/ethernet/airoha/airoha_eth.c:523:\tairoha_fe_rmw(eth, REG_FE_DMA_GLO_CFG,\ndrivers/net/ethernet/airoha/airoha_eth.c-524-\t\t FE_DMA_GLO_L2_SPACE_MASK | FE_DMA_GLO_PG_SZ_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-526-\t\t FE_DMA_GLO_PG_SZ_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c:527:\tairoha_fe_wr(eth, REG_FE_RST_GLO_CFG,\ndrivers/net/ethernet/airoha/airoha_eth.c-528-\t\t FE_RST_CORE_MASK | FE_RST_GDM3_MBI_ARB_MASK |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-534-\t */\ndrivers/net/ethernet/airoha/airoha_eth.c:535:\tairoha_fe_wr(eth, REG_FE_CDM1_OQ_MAP0, BIT(4));\ndrivers/net/ethernet/airoha/airoha_eth.c:536:\tairoha_fe_wr(eth, REG_FE_CDM1_OQ_MAP1, BIT(28));\ndrivers/net/ethernet/airoha/airoha_eth.c:537:\tairoha_fe_wr(eth, REG_FE_CDM1_OQ_MAP2, BIT(4));\ndrivers/net/ethernet/airoha/airoha_eth.c:538:\tairoha_fe_wr(eth, REG_FE_CDM1_OQ_MAP3, BIT(28));\ndrivers/net/ethernet/airoha/airoha_eth.c-539-\ndrivers/net/ethernet/airoha/airoha_eth.c:540:\tairoha_fe_vip_setup(eth);\ndrivers/net/ethernet/airoha/airoha_eth.c:541:\tairoha_fe_pse_ports_init(eth);\ndrivers/net/ethernet/airoha/airoha_eth.c-542-\ndrivers/net/ethernet/airoha/airoha_eth.c:543:\tairoha_fe_set(eth, REG_GDM_MISC_CFG,\ndrivers/net/ethernet/airoha/airoha_eth.c-544-\t\t GDM2_RDM_ACK_WAIT_PREF_MASK |\ndrivers/net/ethernet/airoha/airoha_eth.c-545-\t\t GDM2_CHN_VLD_MODE_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c:546:\tairoha_fe_rmw(eth, REG_CDM_FWD_CFG(2), CDM_OAM_QSEL_MASK,\ndrivers/net/ethernet/airoha/airoha_eth.c-547-\t\t FIELD_PREP(CDM_OAM_QSEL_MASK, 15));\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-550-\t/* NPU Core-3, NPU Bridge Channel-3 */\ndrivers/net/ethernet/airoha/airoha_eth.c:551:\tairoha_fe_rmw(eth, REG_IP_FRAG_FP,\ndrivers/net/ethernet/airoha/airoha_eth.c-552-\t\t IP_FRAGMENT_PORT_MASK | IP_FRAGMENT_NBQ_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-555-\t/* QDMA LAN, RX Ring-22 */\ndrivers/net/ethernet/airoha/airoha_eth.c:556:\tairoha_fe_rmw(eth, REG_IP_FRAG_FP,\ndrivers/net/ethernet/airoha/airoha_eth.c-557-\t\t IP_ASSEMBLE_PORT_MASK | IP_ASSEMBLE_NBQ_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-560-\ndrivers/net/ethernet/airoha/airoha_eth.c:561:\tairoha_fe_set(eth, REG_GDM_FWD_CFG(AIROHA_GDM3_IDX), GDM_PAD_EN_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c:562:\tairoha_fe_set(eth, REG_GDM_FWD_CFG(AIROHA_GDM4_IDX), GDM_PAD_EN_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c-563-\ndrivers/net/ethernet/airoha/airoha_eth.c-564-\t/* Enable split for MIB counters for GDM3 and GDM4 */\ndrivers/net/ethernet/airoha/airoha_eth.c:565:\tairoha_fe_set(eth, REG_FE_GDM_MIB_CFG(AIROHA_GDM3_IDX),\ndrivers/net/ethernet/airoha/airoha_eth.c-566-\t\t FE_GDM_TX_MIB_SPLIT_EN_MASK |\ndrivers/net/ethernet/airoha/airoha_eth.c-567-\t\t FE_GDM_RX_MIB_SPLIT_EN_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c:568:\tairoha_fe_set(eth, REG_FE_GDM_MIB_CFG(AIROHA_GDM4_IDX),\ndrivers/net/ethernet/airoha/airoha_eth.c-569-\t\t FE_GDM_TX_MIB_SPLIT_EN_MASK |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-571-\ndrivers/net/ethernet/airoha/airoha_eth.c:572:\tairoha_fe_crsn_qsel_init(eth);\ndrivers/net/ethernet/airoha/airoha_eth.c-573-\ndrivers/net/ethernet/airoha/airoha_eth.c:574:\tairoha_fe_clear(eth, REG_FE_CPORT_CFG, FE_CPORT_QUEUE_XFC_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c:575:\tairoha_fe_set(eth, REG_FE_CPORT_CFG, FE_CPORT_PORT_XFC_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c-576-\ndrivers/net/ethernet/airoha/airoha_eth.c-577-\t/* default aging mode for mbi unlock issue */\ndrivers/net/ethernet/airoha/airoha_eth.c:578:\tairoha_fe_rmw(eth, REG_GDM_CHN_RLS(2),\ndrivers/net/ethernet/airoha/airoha_eth.c-579-\t\t MBI_RX_AGE_SEL_MASK | MBI_TX_AGE_SEL_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-583-\t/* disable IFC by default */\ndrivers/net/ethernet/airoha/airoha_eth.c:584:\tairoha_fe_clear(eth, REG_FE_CSR_IFC_CFG, FE_IFC_EN_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c-585-\ndrivers/net/ethernet/airoha/airoha_eth.c-586-\t/* enable 1:N vlan action, init vlan table */\ndrivers/net/ethernet/airoha/airoha_eth.c:587:\tairoha_fe_set(eth, REG_MC_VLAN_EN, MC_VLAN_EN_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c-588-\ndrivers/net/ethernet/airoha/airoha_eth.c:589:\treturn airoha_fe_mc_vlan_clear(eth);\ndrivers/net/ethernet/airoha/airoha_eth.c-590-}\ndrivers/net/ethernet/airoha/airoha_eth.c-591-\ndrivers/net/ethernet/airoha/airoha_eth.c:592:static int airoha_qdma_fill_rx_queue(struct airoha_queue *q)\ndrivers/net/ethernet/airoha/airoha_eth.c-593-{\ndrivers/net/ethernet/airoha/airoha_eth.c:594:\tstruct airoha_qdma *qdma = q-\u003eqdma;\ndrivers/net/ethernet/airoha/airoha_eth.c-595-\tint qid = q - \u0026qdma-\u003eq_rx[0];\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-598-\twhile (q-\u003equeued \u003c q-\u003endesc - 1) {\ndrivers/net/ethernet/airoha/airoha_eth.c:599:\t\tstruct airoha_queue_entry *e = \u0026q-\u003eentry[q-\u003ehead];\ndrivers/net/ethernet/airoha/airoha_eth.c:600:\t\tstruct airoha_qdma_desc *desc = \u0026q-\u003edesc[q-\u003ehead];\ndrivers/net/ethernet/airoha/airoha_eth.c-601-\t\tstruct page *page;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-630-\tif (nframes)\ndrivers/net/ethernet/airoha/airoha_eth.c:631:\t\tairoha_qdma_rmw(qdma, REG_RX_CPU_IDX(qid),\ndrivers/net/ethernet/airoha/airoha_eth.c-632-\t\t\t\tRX_RING_CPU_IDX_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-637-\ndrivers/net/ethernet/airoha/airoha_eth.c:638:static struct airoha_gdm_dev *\ndrivers/net/ethernet/airoha/airoha_eth.c:639:airoha_qdma_get_gdm_dev(struct airoha_eth *eth, struct airoha_qdma_desc *desc)\ndrivers/net/ethernet/airoha/airoha_eth.c-640-{\ndrivers/net/ethernet/airoha/airoha_eth.c:641:\tstruct airoha_gdm_port *port;\ndrivers/net/ethernet/airoha/airoha_eth.c-642-\tu16 p, d;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-659-\ndrivers/net/ethernet/airoha/airoha_eth.c:660:static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)\ndrivers/net/ethernet/airoha/airoha_eth.c-661-{\ndrivers/net/ethernet/airoha/airoha_eth.c-662-\tenum dma_data_direction dir = page_pool_get_dma_dir(q-\u003epage_pool);\ndrivers/net/ethernet/airoha/airoha_eth.c:663:\tstruct airoha_qdma *qdma = q-\u003eqdma;\ndrivers/net/ethernet/airoha/airoha_eth.c:664:\tstruct airoha_eth *eth = qdma-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_eth.c-665-\tint qid = q - \u0026qdma-\u003eq_rx[0];\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-668-\twhile (done \u003c budget) {\ndrivers/net/ethernet/airoha/airoha_eth.c:669:\t\tstruct airoha_queue_entry *e = \u0026q-\u003eentry[q-\u003etail];\ndrivers/net/ethernet/airoha/airoha_eth.c:670:\t\tstruct airoha_qdma_desc *desc = \u0026q-\u003edesc[q-\u003etail];\ndrivers/net/ethernet/airoha/airoha_eth.c-671-\t\tu32 hash, reason, msg1, desc_ctrl;\ndrivers/net/ethernet/airoha/airoha_eth.c:672:\t\tstruct airoha_gdm_dev *dev;\ndrivers/net/ethernet/airoha/airoha_eth.c-673-\t\tstruct net_device *netdev;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-694-\ndrivers/net/ethernet/airoha/airoha_eth.c:695:\t\tdev = airoha_qdma_get_gdm_dev(eth, desc);\ndrivers/net/ethernet/airoha/airoha_eth.c-696-\t\tif (IS_ERR(dev))\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-728-\t\tif (netdev_uses_dsa(netdev)) {\ndrivers/net/ethernet/airoha/airoha_eth.c:729:\t\t\tstruct airoha_gdm_port *port = dev-\u003eport;\ndrivers/net/ethernet/airoha/airoha_eth.c-730-\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-752-\t\tif (reason == PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED)\ndrivers/net/ethernet/airoha/airoha_eth.c:753:\t\t\tairoha_ppe_check_skb(\u0026eth-\u003eppe-\u003edev, q-\u003eskb, hash,\n\n"
} |
| 7/2 | 2026/07/21 07:04 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 40218 output: 35 thoughts: 441 Thoughts: **Analyzing the Airoha Ethernet Driver Fuzzing Strategy**
Okay, so `airoha_eth` is specifically for Airoha SoCs. The immediate question is, is there an emulator for Airoha SoCs within QEMU, or even a software-based emulator in the kernel itself? No, there isn't. So, how *does* syzkaller fuzz this particular driver? Ah, right. It leverages the platform driver model. Syzkaller can fuzz platform drivers if it can instantiate them using `syz_devlink` or if it can simply create a "fake" platform device.
Now, let's look at how `airoha_eth` is registered. It's using `module_platform_driver(airoha_driver);`. This means that if syzkaller creates a platform device named "airoha-eth", the driver's probe function will be called. Let's see what happens within `airoha_probe`:
```c
static int airoha_probe(struct platform_device *pdev)
{
struct device_node *np;
struct airoha_eth *eth;
int i, err;
eth = devm_kzalloc(&pdev->dev, sizeof(*eth), GFP_KERNEL);
...
eth->soc = of_device_get_match_data(&pdev->dev);
...
eth->fe_regs = devm_platform_ioremap_resource_byname(pdev, "fe");
...
}
```
Okay, so `airoha_probe` allocates an `airoha_eth` structure and uses `devm_platform_ioremap_resource_byname(pdev, "fe")` to map the "fe" resource. If syzkaller creates a fake device tree node or platform device, it can provide those "fake" memory resources. But, the crucial point is that when the driver accesses `eth->fe_regs` through functions like `airoha_fe_wr`, it'll be reading or writing to *that* fake memory space.
Now, wait a second. If it's *fake* memory, it won't crash, but it also won't reflect any real hardware behavior. The driver will just be reading/writing to memory that's controlled by syzkaller.
Let me think… the `airoha_probe` function *does* call `airoha_hw_init`, which in turn calls `airoha_fe_init`, which is the function that reads and writes registers. So, if we're just reading/writing fake memory, those reads will likely just give back 0s, or whatever syzkaller has placed there.
The question then is, will the probe function *succeed*? It seems like it will, since there aren't many checks that depend on the value of the registers. It seems syzkaller can reach deep into the driver logic, but without any actual hardware interactions. To confirm my thoughts, I need to check the exact checks performed during `airoha_hw_init` or `airoha_probe`.
|
| 8/2 | 2026/07/21 07:04 | tool | grepper |
0mArgs:{
"Expression": "read_poll_timeout",
"PathPrefix": "drivers/net/ethernet/airoha/"
}Results: {
"Output": "drivers/net/ethernet/airoha/airoha_eth.c=408=static int airoha_fe_mc_vlan_clear(struct airoha_eth *eth)\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-420-\t\tairoha_fe_wr(eth, REG_MC_VLAN_CFG, val);\ndrivers/net/ethernet/airoha/airoha_eth.c:421:\t\terr = read_poll_timeout(airoha_fe_rr, val,\ndrivers/net/ethernet/airoha/airoha_eth.c-422-\t\t\t\t\tval \u0026 MC_VLAN_CFG_CMD_DONE_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-434-\t\t\tairoha_fe_wr(eth, REG_MC_VLAN_CFG, val);\ndrivers/net/ethernet/airoha/airoha_eth.c:435:\t\t\terr = read_poll_timeout(airoha_fe_rr, val,\ndrivers/net/ethernet/airoha/airoha_eth.c-436-\t\t\t\t\t\tval \u0026 MC_VLAN_CFG_CMD_DONE_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=1173=static void airoha_qdma_tx_cleanup(struct airoha_qdma *qdma)\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-1179-\t\t\t GLOBAL_CFG_TX_DMA_EN_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c:1180:\tif (read_poll_timeout(airoha_qdma_rr, status,\ndrivers/net/ethernet/airoha/airoha_eth.c-1181-\t\t\t !(status \u0026 GLOBAL_CFG_TX_DMA_BUSY_MASK),\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=1243=static int airoha_qdma_init_hfwd_queues(struct airoha_qdma *qdma)\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-1306-\ndrivers/net/ethernet/airoha/airoha_eth.c:1307:\treturn read_poll_timeout(airoha_qdma_rr, status,\ndrivers/net/ethernet/airoha/airoha_eth.c-1308-\t\t\t\t !(status \u0026 LMGR_INIT_START), USEC_PER_MSEC,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=1568=static void airoha_qdma_cleanup(struct airoha_eth *eth,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-1577-\t\t\t\t GLOBAL_CFG_RX_DMA_EN_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c:1578:\t\tif (read_poll_timeout(airoha_qdma_rr, status,\ndrivers/net/ethernet/airoha/airoha_eth.c-1579-\t\t\t\t !(status \u0026 GLOBAL_CFG_RX_DMA_BUSY_MASK),\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=2465=static int airoha_qdma_set_chan_tx_sched(struct net_device *netdev,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-2486-\t\t\t FIELD_PREP(TWRR_VALUE_MASK, weights[i]));\ndrivers/net/ethernet/airoha/airoha_eth.c:2487:\t\terr = read_poll_timeout(airoha_qdma_rr, status,\ndrivers/net/ethernet/airoha/airoha_eth.c-2488-\t\t\t\t\tstatus \u0026 TWRR_RW_CMD_DONE,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=2603=static int airoha_qdma_get_rl_param(struct airoha_qdma *qdma, int queue_id,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-2612-\tairoha_qdma_wr(qdma, REG_TRTCM_CFG_PARAM(addr), config);\ndrivers/net/ethernet/airoha/airoha_eth.c:2613:\tif (read_poll_timeout(airoha_qdma_rr, val,\ndrivers/net/ethernet/airoha/airoha_eth.c-2614-\t\t\t val \u0026 RATE_LIMIT_PARAM_RW_DONE_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=2626=static int airoha_qdma_set_rl_param(struct airoha_qdma *qdma, int queue_id,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-2638-\ndrivers/net/ethernet/airoha/airoha_eth.c:2639:\treturn read_poll_timeout(airoha_qdma_rr, val,\ndrivers/net/ethernet/airoha/airoha_eth.c-2640-\t\t\t\t val \u0026 RATE_LIMIT_PARAM_RW_DONE_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=2722=static int airoha_qdma_get_trtcm_param(struct airoha_qdma *qdma, int channel,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-2733-\tairoha_qdma_wr(qdma, REG_TRTCM_CFG_PARAM(addr), config);\ndrivers/net/ethernet/airoha/airoha_eth.c:2734:\tif (read_poll_timeout(airoha_qdma_rr, val,\ndrivers/net/ethernet/airoha/airoha_eth.c-2735-\t\t\t val \u0026 TRTCM_PARAM_RW_DONE_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=2747=static int airoha_qdma_set_trtcm_param(struct airoha_qdma *qdma, int channel,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-2760-\ndrivers/net/ethernet/airoha/airoha_eth.c:2761:\treturn read_poll_timeout(airoha_qdma_rr, val,\ndrivers/net/ethernet/airoha/airoha_eth.c-2762-\t\t\t\t val \u0026 TRTCM_PARAM_RW_DONE_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_npu.c=163=static int airoha_npu_send_msg(struct airoha_npu *npu, int func_id,\n--\ndrivers/net/ethernet/airoha/airoha_npu.c-184-\ndrivers/net/ethernet/airoha/airoha_npu.c:185:\tret = regmap_read_poll_timeout_atomic(npu-\u003eregmap,\ndrivers/net/ethernet/airoha/airoha_npu.c-186-\t\t\t\t\t REG_CR_MBQ0_CTRL(3) + offset,\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c=680=airoha_ppe_foe_get_entry_locked(struct airoha_ppe *ppe, u32 hash)\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c-695-\t\t\t PPE_SRAM_CTRL_REQ_MASK);\ndrivers/net/ethernet/airoha/airoha_ppe.c:696:\t\tif (read_poll_timeout_atomic(airoha_fe_rr, val,\ndrivers/net/ethernet/airoha/airoha_ppe.c-697-\t\t\t\t\t val \u0026 PPE_SRAM_CTRL_ACK_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c=740=static int airoha_ppe_foe_commit_sram_entry(struct airoha_ppe *ppe, u32 hash)\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c-754-\ndrivers/net/ethernet/airoha/airoha_ppe.c:755:\treturn read_poll_timeout_atomic(airoha_fe_rr, val,\ndrivers/net/ethernet/airoha/airoha_ppe.c-756-\t\t\t\t\tval \u0026 PPE_SRAM_CTRL_ACK_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c=1405=static int airoha_ppe_wait_for_npu_init(struct airoha_eth *eth)\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c-1413-\t */\ndrivers/net/ethernet/airoha/airoha_ppe.c:1414:\terr = read_poll_timeout(airoha_fe_rr, val, val, USEC_PER_MSEC,\ndrivers/net/ethernet/airoha/airoha_ppe.c-1415-\t\t\t\t100 * USEC_PER_MSEC, false, eth,\n--\ndrivers/net/ethernet/airoha/airoha_ppe.c-1420-\tif (airoha_ppe_is_enabled(eth, 1))\ndrivers/net/ethernet/airoha/airoha_ppe.c:1421:\t\terr = read_poll_timeout(airoha_fe_rr, val, val, USEC_PER_MSEC,\ndrivers/net/ethernet/airoha/airoha_ppe.c-1422-\t\t\t\t\t100 * USEC_PER_MSEC, false, eth,\n"
} |
| 9/2 | 2026/07/21 07:04 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 43833 output: 46 thoughts: 496 Thoughts: **Analyzing the Airoha Driver's Vulnerability in Virtualized Environments** Okay, so I'm looking at this Airoha driver, and immediately I see `read_poll_timeout` being used all over the place. Hmm, if syzkaller uses its typical fake memory mapping, `airoha_fe_rr` is going to return 0, which is concerning. Let's see... the conditions within `read_poll_timeout` involve checking `val & MC_VLAN_CFG_CMD_DONE_MASK`. If `val` is actually zero, then the mask operation will result in a zero, causing a timeout and an error. Wait a second, if that error happens, then `airoha_fe_mc_vlan_clear` fails, and that makes `airoha_fe_init` fail. Which, in turn, kills `airoha_hw_init`, and ultimately causes `airoha_probe` to fail. Right, so in a virtualized environment, unless the fake memory happens to return *exactly* the correct values, this driver won't even probe successfully. Now, syzkaller does have mechanisms like `syz_devlink` and `syz_mount_image`, but there isn't a *generic* way to mock MMIO reads to bypass these `read_poll_timeout` loops unless we're talking about specific fault injection or specialized emulators. I mean, sure, it has things like `syz_usb_connect` and `syz_80211_join_ibss`, but there's no `syz_airoha_connect`. Hmm, this is a roadblock. Syzkaller can leverage `KCOV` to guide fuzzing, but if `probe` fails, the rest of the code is never reached. This really limits the scope of what we can hit! Hold on... Is there *any* way to actually fuzz this driver? The prompt is very specific: "Code paths that are impossible to reach in virtualized environments like GCE or QEMU..." So, if `probe` fails, code paths like `airoha_dev_open`, `airoha_dev_xmit`, `airoha_tc_setup_qdisc_htb` become completely unreachable. Wait, is there *any* way to bypass the `probe` step at all? No, if `probe` fails, the net_device doesn't get registered, which means `airoha_dev_open` won't even *be* called. Okay, I need to double-check if `airoha_probe` does something clever and ignores the `airoha_hw_init` error somehow, but based on what I see, it looks like it is failing the driver completely. |
| 10/2 | 2026/07/21 07:04 | tool | read-file |
0mArgs:{
"File": "drivers/net/ethernet/airoha/airoha_eth.c",
"FirstLine": 3541,
"LineCount": 100
}Results: {
"Contents": "3541:\tstatic int airoha_probe(struct platform_device *pdev)\n3542:\t{\n3543:\t\tstruct reset_control_bulk_data *xsi_rsts;\n3544:\t\tstruct device_node *np;\n3545:\t\tstruct airoha_eth *eth;\n3546:\t\tint i, err;\n3547:\t\n3548:\t\teth = devm_kzalloc(\u0026pdev-\u003edev, sizeof(*eth), GFP_KERNEL);\n3549:\t\tif (!eth)\n3550:\t\t\treturn -ENOMEM;\n3551:\t\n3552:\t\teth-\u003esoc = of_device_get_match_data(\u0026pdev-\u003edev);\n3553:\t\tif (!eth-\u003esoc)\n3554:\t\t\treturn -EINVAL;\n3555:\t\n3556:\t\teth-\u003edev = \u0026pdev-\u003edev;\n3557:\t\n3558:\t\terr = dma_set_mask_and_coherent(eth-\u003edev, DMA_BIT_MASK(32));\n3559:\t\tif (err) {\n3560:\t\t\tdev_err(eth-\u003edev, \"failed configuring DMA mask\\n\");\n3561:\t\t\treturn err;\n3562:\t\t}\n3563:\t\n3564:\t\teth-\u003efe_regs = devm_platform_ioremap_resource_byname(pdev, \"fe\");\n3565:\t\tif (IS_ERR(eth-\u003efe_regs))\n3566:\t\t\treturn dev_err_probe(eth-\u003edev, PTR_ERR(eth-\u003efe_regs),\n3567:\t\t\t\t\t \"failed to iomap fe regs\\n\");\n3568:\t\n3569:\t\teth-\u003ersts[0].id = \"fe\";\n3570:\t\teth-\u003ersts[1].id = \"pdma\";\n3571:\t\teth-\u003ersts[2].id = \"qdma\";\n3572:\t\terr = devm_reset_control_bulk_get_exclusive(eth-\u003edev,\n3573:\t\t\t\t\t\t\t ARRAY_SIZE(eth-\u003ersts),\n3574:\t\t\t\t\t\t\t eth-\u003ersts);\n3575:\t\tif (err) {\n3576:\t\t\tdev_err(eth-\u003edev, \"failed to get bulk reset lines\\n\");\n3577:\t\t\treturn err;\n3578:\t\t}\n3579:\t\n3580:\t\txsi_rsts = devm_kcalloc(eth-\u003edev,\n3581:\t\t\t\t\teth-\u003esoc-\u003enum_xsi_rsts, sizeof(*xsi_rsts),\n3582:\t\t\t\t\tGFP_KERNEL);\n3583:\t\tif (!xsi_rsts)\n3584:\t\t\treturn -ENOMEM;\n3585:\t\n3586:\t\teth-\u003exsi_rsts = xsi_rsts;\n3587:\t\tfor (i = 0; i \u003c eth-\u003esoc-\u003enum_xsi_rsts; i++)\n3588:\t\t\teth-\u003exsi_rsts[i].id = eth-\u003esoc-\u003exsi_rsts_names[i];\n3589:\t\n3590:\t\terr = devm_reset_control_bulk_get_exclusive(eth-\u003edev,\n3591:\t\t\t\t\t\t\t eth-\u003esoc-\u003enum_xsi_rsts,\n3592:\t\t\t\t\t\t\t eth-\u003exsi_rsts);\n3593:\t\tif (err) {\n3594:\t\t\tdev_err(eth-\u003edev, \"failed to get bulk xsi reset lines\\n\");\n3595:\t\t\treturn err;\n3596:\t\t}\n3597:\t\n3598:\t\teth-\u003enapi_dev = alloc_netdev_dummy(0);\n3599:\t\tif (!eth-\u003enapi_dev)\n3600:\t\t\treturn -ENOMEM;\n3601:\t\n3602:\t\t/* Enable threaded NAPI by default */\n3603:\t\teth-\u003enapi_dev-\u003ethreaded = true;\n3604:\t\tstrscpy(eth-\u003enapi_dev-\u003ename, \"qdma_eth\", sizeof(eth-\u003enapi_dev-\u003ename));\n3605:\t\tplatform_set_drvdata(pdev, eth);\n3606:\t\n3607:\t\terr = airoha_hw_init(pdev, eth);\n3608:\t\tif (err)\n3609:\t\t\tgoto error_netdev_free;\n3610:\t\n3611:\t\tfor (i = 0; i \u003c ARRAY_SIZE(eth-\u003eqdma); i++) {\n3612:\t\t\tairoha_qdma_start_napi(\u0026eth-\u003eqdma[i]);\n3613:\t\t\tairoha_qdma_set(\u0026eth-\u003eqdma[i], REG_QDMA_GLOBAL_CFG,\n3614:\t\t\t\t\tGLOBAL_CFG_TX_DMA_EN_MASK |\n3615:\t\t\t\t\tGLOBAL_CFG_RX_DMA_EN_MASK);\n3616:\t\t}\n3617:\t\n3618:\t\tfor_each_child_of_node(pdev-\u003edev.of_node, np) {\n3619:\t\t\tif (!of_device_is_compatible(np, \"airoha,eth-mac\"))\n3620:\t\t\t\tcontinue;\n3621:\t\n3622:\t\t\tif (!of_device_is_available(np))\n3623:\t\t\t\tcontinue;\n3624:\t\n3625:\t\t\terr = airoha_alloc_gdm_port(eth, np);\n3626:\t\t\tif (err) {\n3627:\t\t\t\tof_node_put(np);\n3628:\t\t\t\tgoto error_napi_stop;\n3629:\t\t\t}\n3630:\t\t}\n3631:\t\n3632:\t\terr = airoha_register_gdm_devices(eth);\n3633:\t\tif (err)\n3634:\t\t\tgoto error_napi_stop;\n3635:\t\n3636:\t\treturn 0;\n3637:\t\n3638:\terror_napi_stop:\n3639:\t\tfor (i = 0; i \u003c ARRAY_SIZE(eth-\u003eqdma); i++) {\n3640:\t\t\tairoha_qdma_stop_napi(\u0026eth-\u003eqdma[i]);\n"
} |
| 11/2 | 2026/07/21 07:04 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 46587 output: 26 thoughts: 666 Thoughts: **Analyzing the Reachability of Airoha Ethernet Driver Code for Fuzzing** Okay, so I'm digging into this Airoha Ethernet driver, trying to figure out if syzkaller can actually hit any interesting code paths. The initial suspicion is that the `airoha_hw_init` function, called during device probe, is the key entry point. This function, and its dependencies like `airoha_fe_init`, `airoha_fe_mc_vlan_clear`, and ultimately `read_poll_timeout`, seem to be on a critical path. If `read_poll_timeout` fails within this chain, the entire `airoha_hw_init` and therefore `airoha_probe` fails. My immediate thought is, can syzkaller bypass this issue? I know syzkaller has some tricks up its sleeve - `syz_devlink`, `syz_mount_image`, `syz_genetlink_get_family_id`, and `syz_init_net_socket` – but those seem like a long shot for this specific scenario. Typically, for platform drivers like this, syzkaller leverages existing kernel modules like `mac80211_hwsim`, `vkms`, `vhci`, `dummy`, `veth`, `tun`, `tap`, or `netdevsim` to emulate the hardware. The big question is, does an `airoha_sim` or equivalent exist? It doesn't seem like it. I'm also considering fault injection. Can syzkaller inject specific values to help pass the polling loop within `read_poll_timeout`? Probably not, not directly. Then, there's another angle: what if the driver is compiled, but *never* probed? If the device doesn't probe, those core functions are unreachable. Is there a way to reach the `airoha_tc_setup_qdisc_htb` function without probing? No, that's called through callbacks associated with a `net_device`. If the device isn't registered, no `net_device`, no callback. The route is through `airoha_alloc_gdm_device` and then `airoha_netdev_ops` which assign the callback. It's all tied to a successfully initialized and registered device. The more pressing question is: is syzkaller even *fuzzing* this driver effectively? The commit message mentioning a "syz-cluster" and a patch under review suggests that syzbot tested a patch related to this driver. If so, syzbot usually just tries to apply and run existing fuzzing or a reproducer. But, if the patch is for an unreachable driver, it'll compile and run, but never execute the target code. This is where I start to see a critical connection. The prompt I'm seeing asks if it's "WorthFuzzing=false" if the code paths are unreachable in virtualized environments. This is a dead giveaway. Since the `airoha_eth` driver is hardware-specific, and there's no software emulator like `netdevsim`, then it's *impossible* to reach the code in GCE or QEMU. That means it likely isn't being efficiently fuzzed. I need to make sure there isn't some obscure `netdevsim`-like mock for the Airoha platform I'm missing. |
| 12/2 | 2026/07/21 07:04 | tool | grepper |
0mArgs:{
"Expression": "airoha",
"PathPrefix": "drivers/net/"
}Results: {
"Output": "\nFull output is too long, showing 500 out of 4063 lines.\nUse more precise expression if possible.\n\ndrivers/net/dsa/mt7530-mmio.c=12=static const struct of_device_id mt7988_of_match[] = {\ndrivers/net/dsa/mt7530-mmio.c:13:\t{ .compatible = \"airoha,an7583-switch\", .data = \u0026mt753x_table[ID_AN7583], },\ndrivers/net/dsa/mt7530-mmio.c:14:\t{ .compatible = \"airoha,en7581-switch\", .data = \u0026mt753x_table[ID_EN7581], },\ndrivers/net/dsa/mt7530-mmio.c-15-\t{ .compatible = \"mediatek,mt7988-switch\", .data = \u0026mt753x_table[ID_MT7988], },\n--\ndrivers/net/ethernet/Kconfig=22=source \"drivers/net/ethernet/agere/Kconfig\"\ndrivers/net/ethernet/Kconfig:23:source \"drivers/net/ethernet/airoha/Kconfig\"\ndrivers/net/ethernet/Kconfig-24-source \"drivers/net/ethernet/alacritech/Kconfig\"\n--\ndrivers/net/ethernet/Makefile=12=obj-$(CONFIG_NET_VENDOR_AGERE) += agere/\ndrivers/net/ethernet/Makefile:13:obj-$(CONFIG_NET_VENDOR_AIROHA) += airoha/\ndrivers/net/ethernet/Makefile-14-obj-$(CONFIG_NET_VENDOR_ALACRITECH) += alacritech/\n--\ndrivers/net/ethernet/airoha/Makefile-5-\ndrivers/net/ethernet/airoha/Makefile:6:obj-$(CONFIG_NET_AIROHA) += airoha-eth.o\ndrivers/net/ethernet/airoha/Makefile:7:airoha-eth-y := airoha_eth.o airoha_ppe.o\ndrivers/net/ethernet/airoha/Makefile:8:airoha-eth-$(CONFIG_DEBUG_FS) += airoha_ppe_debugfs.o\ndrivers/net/ethernet/airoha/Makefile:9:obj-$(CONFIG_NET_AIROHA_NPU) += airoha_npu.o\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-16-\ndrivers/net/ethernet/airoha/airoha_eth.c:17:#include \"airoha_regs.h\"\ndrivers/net/ethernet/airoha/airoha_eth.c:18:#include \"airoha_eth.h\"\ndrivers/net/ethernet/airoha/airoha_eth.c-19-\ndrivers/net/ethernet/airoha/airoha_eth.c:20:u32 airoha_rr(void __iomem *base, u32 offset)\ndrivers/net/ethernet/airoha/airoha_eth.c-21-{\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-24-\ndrivers/net/ethernet/airoha/airoha_eth.c:25:void airoha_wr(void __iomem *base, u32 offset, u32 val)\ndrivers/net/ethernet/airoha/airoha_eth.c-26-{\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-29-\ndrivers/net/ethernet/airoha/airoha_eth.c:30:u32 airoha_rmw(void __iomem *base, u32 offset, u32 mask, u32 val)\ndrivers/net/ethernet/airoha/airoha_eth.c-31-{\ndrivers/net/ethernet/airoha/airoha_eth.c:32:\tval |= (airoha_rr(base, offset) \u0026 ~mask);\ndrivers/net/ethernet/airoha/airoha_eth.c:33:\tairoha_wr(base, offset, val);\ndrivers/net/ethernet/airoha/airoha_eth.c-34-\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-37-\ndrivers/net/ethernet/airoha/airoha_eth.c:38:static void airoha_qdma_set_irqmask(struct airoha_irq_bank *irq_bank,\ndrivers/net/ethernet/airoha/airoha_eth.c-39-\t\t\t\t int index, u32 clear, u32 set)\ndrivers/net/ethernet/airoha/airoha_eth.c-40-{\ndrivers/net/ethernet/airoha/airoha_eth.c:41:\tstruct airoha_qdma *qdma = irq_bank-\u003eqdma;\ndrivers/net/ethernet/airoha/airoha_eth.c-42-\tint bank = irq_bank - \u0026qdma-\u003eirq_banks[0];\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-51-\tirq_bank-\u003eirqmask[index] |= set;\ndrivers/net/ethernet/airoha/airoha_eth.c:52:\tairoha_qdma_wr(qdma, REG_INT_ENABLE(bank, index),\ndrivers/net/ethernet/airoha/airoha_eth.c-53-\t\t irq_bank-\u003eirqmask[index]);\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-56-\t */\ndrivers/net/ethernet/airoha/airoha_eth.c:57:\tairoha_qdma_rr(qdma, REG_INT_ENABLE(bank, index));\ndrivers/net/ethernet/airoha/airoha_eth.c-58-\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-61-\ndrivers/net/ethernet/airoha/airoha_eth.c:62:static void airoha_qdma_irq_enable(struct airoha_irq_bank *irq_bank,\ndrivers/net/ethernet/airoha/airoha_eth.c-63-\t\t\t\t int index, u32 mask)\ndrivers/net/ethernet/airoha/airoha_eth.c-64-{\ndrivers/net/ethernet/airoha/airoha_eth.c:65:\tairoha_qdma_set_irqmask(irq_bank, index, 0, mask);\ndrivers/net/ethernet/airoha/airoha_eth.c-66-}\ndrivers/net/ethernet/airoha/airoha_eth.c-67-\ndrivers/net/ethernet/airoha/airoha_eth.c:68:static void airoha_qdma_irq_disable(struct airoha_irq_bank *irq_bank,\ndrivers/net/ethernet/airoha/airoha_eth.c-69-\t\t\t\t int index, u32 mask)\ndrivers/net/ethernet/airoha/airoha_eth.c-70-{\ndrivers/net/ethernet/airoha/airoha_eth.c:71:\tairoha_qdma_set_irqmask(irq_bank, index, mask, 0);\ndrivers/net/ethernet/airoha/airoha_eth.c-72-}\ndrivers/net/ethernet/airoha/airoha_eth.c-73-\ndrivers/net/ethernet/airoha/airoha_eth.c:74:static int airoha_set_macaddr(struct airoha_gdm_dev *dev, const u8 *addr)\ndrivers/net/ethernet/airoha/airoha_eth.c-75-{\ndrivers/net/ethernet/airoha/airoha_eth.c-76-\tu8 ref_addr[ETH_ALEN] __aligned(2);\ndrivers/net/ethernet/airoha/airoha_eth.c:77:\tstruct airoha_eth *eth = dev-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_eth.c-78-\tu32 reg, val, lmin, lmax;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-85-\tfor (i = 0; i \u003c ARRAY_SIZE(eth-\u003eports); i++) {\ndrivers/net/ethernet/airoha/airoha_eth.c:86:\t\tstruct airoha_gdm_port *port = eth-\u003eports[i];\ndrivers/net/ethernet/airoha/airoha_eth.c-87-\t\tint j;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-92-\t\tfor (j = 0; j \u003c ARRAY_SIZE(port-\u003edevs); j++) {\ndrivers/net/ethernet/airoha/airoha_eth.c:93:\t\t\tstruct airoha_gdm_dev *iter_dev;\ndrivers/net/ethernet/airoha/airoha_eth.c-94-\t\t\tstruct net_device *netdev;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-99-\ndrivers/net/ethernet/airoha/airoha_eth.c:100:\t\t\tif (airoha_is_lan_gdm_dev(iter_dev) !=\ndrivers/net/ethernet/airoha/airoha_eth.c:101:\t\t\t airoha_is_lan_gdm_dev(dev))\ndrivers/net/ethernet/airoha/airoha_eth.c-102-\t\t\t\tcontinue;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-133-\ndrivers/net/ethernet/airoha/airoha_eth.c:134:\treg = airoha_is_lan_gdm_dev(dev) ? REG_FE_LAN_MAC_H : REG_FE_WAN_MAC_H;\ndrivers/net/ethernet/airoha/airoha_eth.c-135-\tval = (addr[0] \u003c\u003c 16) | (addr[1] \u003c\u003c 8) | addr[2];\ndrivers/net/ethernet/airoha/airoha_eth.c:136:\tairoha_fe_wr(eth, reg, val);\ndrivers/net/ethernet/airoha/airoha_eth.c-137-\ndrivers/net/ethernet/airoha/airoha_eth.c:138:\tairoha_fe_wr(eth, REG_FE_MAC_LMIN(reg), lmin);\ndrivers/net/ethernet/airoha/airoha_eth.c:139:\tairoha_fe_wr(eth, REG_FE_MAC_LMAX(reg), lmax);\ndrivers/net/ethernet/airoha/airoha_eth.c-140-\ndrivers/net/ethernet/airoha/airoha_eth.c:141:\tairoha_ppe_init_upd_mem(dev, addr);\ndrivers/net/ethernet/airoha/airoha_eth.c-142-\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-145-\ndrivers/net/ethernet/airoha/airoha_eth.c:146:static void airoha_set_gdm_port_fwd_cfg(struct airoha_eth *eth, u32 addr,\ndrivers/net/ethernet/airoha/airoha_eth.c-147-\t\t\t\t\tu32 val)\ndrivers/net/ethernet/airoha/airoha_eth.c-148-{\ndrivers/net/ethernet/airoha/airoha_eth.c:149:\tairoha_fe_rmw(eth, addr, GDM_OCFQ_MASK,\ndrivers/net/ethernet/airoha/airoha_eth.c-150-\t\t FIELD_PREP(GDM_OCFQ_MASK, val));\ndrivers/net/ethernet/airoha/airoha_eth.c:151:\tairoha_fe_rmw(eth, addr, GDM_MCFQ_MASK,\ndrivers/net/ethernet/airoha/airoha_eth.c-152-\t\t FIELD_PREP(GDM_MCFQ_MASK, val));\ndrivers/net/ethernet/airoha/airoha_eth.c:153:\tairoha_fe_rmw(eth, addr, GDM_BCFQ_MASK,\ndrivers/net/ethernet/airoha/airoha_eth.c-154-\t\t FIELD_PREP(GDM_BCFQ_MASK, val));\ndrivers/net/ethernet/airoha/airoha_eth.c:155:\tairoha_fe_rmw(eth, addr, GDM_UCFQ_MASK,\ndrivers/net/ethernet/airoha/airoha_eth.c-156-\t\t FIELD_PREP(GDM_UCFQ_MASK, val));\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-158-\ndrivers/net/ethernet/airoha/airoha_eth.c:159:static int airoha_set_vip_for_gdm_port(struct airoha_gdm_dev *dev, bool enable)\ndrivers/net/ethernet/airoha/airoha_eth.c-160-{\ndrivers/net/ethernet/airoha/airoha_eth.c:161:\tstruct airoha_gdm_port *port = dev-\u003eport;\ndrivers/net/ethernet/airoha/airoha_eth.c:162:\tstruct airoha_eth *eth = dev-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_eth.c-163-\tu32 vip_port;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-166-\tif (enable) {\ndrivers/net/ethernet/airoha/airoha_eth.c:167:\t\tairoha_fe_set(eth, REG_FE_VIP_PORT_EN, vip_port);\ndrivers/net/ethernet/airoha/airoha_eth.c:168:\t\tairoha_fe_set(eth, REG_FE_IFC_PORT_EN, vip_port);\ndrivers/net/ethernet/airoha/airoha_eth.c-169-\t} else {\ndrivers/net/ethernet/airoha/airoha_eth.c:170:\t\tairoha_fe_clear(eth, REG_FE_VIP_PORT_EN, vip_port);\ndrivers/net/ethernet/airoha/airoha_eth.c:171:\t\tairoha_fe_clear(eth, REG_FE_IFC_PORT_EN, vip_port);\ndrivers/net/ethernet/airoha/airoha_eth.c-172-\t}\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-176-\ndrivers/net/ethernet/airoha/airoha_eth.c:177:static void airoha_fe_maccr_init(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_eth.c-178-{\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-181-\tfor (p = 1; p \u003c= ARRAY_SIZE(eth-\u003eports); p++) {\ndrivers/net/ethernet/airoha/airoha_eth.c:182:\t\tairoha_fe_set(eth, REG_GDM_FWD_CFG(p),\ndrivers/net/ethernet/airoha/airoha_eth.c-183-\t\t\t GDM_TCP_CKSUM_MASK | GDM_UDP_CKSUM_MASK |\ndrivers/net/ethernet/airoha/airoha_eth.c-184-\t\t\t GDM_IP4_CKSUM_MASK | GDM_DROP_CRC_ERR_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c:185:\t\tairoha_fe_rmw(eth, REG_GDM_LEN_CFG(p),\ndrivers/net/ethernet/airoha/airoha_eth.c-186-\t\t\t GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-190-\ndrivers/net/ethernet/airoha/airoha_eth.c:191:\tairoha_fe_rmw(eth, REG_CDM_VLAN_CTRL(1), CDM_VLAN_MASK,\ndrivers/net/ethernet/airoha/airoha_eth.c-192-\t\t FIELD_PREP(CDM_VLAN_MASK, 0x8100));\ndrivers/net/ethernet/airoha/airoha_eth.c-193-\ndrivers/net/ethernet/airoha/airoha_eth.c:194:\tairoha_fe_set(eth, REG_FE_CPORT_CFG, FE_CPORT_PAD);\ndrivers/net/ethernet/airoha/airoha_eth.c-195-}\ndrivers/net/ethernet/airoha/airoha_eth.c-196-\ndrivers/net/ethernet/airoha/airoha_eth.c:197:static void airoha_fe_vip_setup(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_eth.c-198-{\ndrivers/net/ethernet/airoha/airoha_eth.c:199:\tairoha_fe_wr(eth, REG_FE_VIP_PATN(3), ETH_P_PPP_DISC);\ndrivers/net/ethernet/airoha/airoha_eth.c:200:\tairoha_fe_wr(eth, REG_FE_VIP_EN(3), PATN_FCPU_EN_MASK | PATN_EN_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c-201-\ndrivers/net/ethernet/airoha/airoha_eth.c:202:\tairoha_fe_wr(eth, REG_FE_VIP_PATN(4), PPP_LCP);\ndrivers/net/ethernet/airoha/airoha_eth.c:203:\tairoha_fe_wr(eth, REG_FE_VIP_EN(4),\ndrivers/net/ethernet/airoha/airoha_eth.c-204-\t\t PATN_FCPU_EN_MASK | FIELD_PREP(PATN_TYPE_MASK, 1) |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-206-\ndrivers/net/ethernet/airoha/airoha_eth.c:207:\tairoha_fe_wr(eth, REG_FE_VIP_PATN(6), PPP_IPCP);\ndrivers/net/ethernet/airoha/airoha_eth.c:208:\tairoha_fe_wr(eth, REG_FE_VIP_EN(6),\ndrivers/net/ethernet/airoha/airoha_eth.c-209-\t\t PATN_FCPU_EN_MASK | FIELD_PREP(PATN_TYPE_MASK, 1) |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-211-\ndrivers/net/ethernet/airoha/airoha_eth.c:212:\tairoha_fe_wr(eth, REG_FE_VIP_PATN(7), PPP_CHAP);\ndrivers/net/ethernet/airoha/airoha_eth.c:213:\tairoha_fe_wr(eth, REG_FE_VIP_EN(7),\ndrivers/net/ethernet/airoha/airoha_eth.c-214-\t\t PATN_FCPU_EN_MASK | FIELD_PREP(PATN_TYPE_MASK, 1) |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-217-\t/* BOOTP (0x43) */\ndrivers/net/ethernet/airoha/airoha_eth.c:218:\tairoha_fe_wr(eth, REG_FE_VIP_PATN(8), 0x43);\ndrivers/net/ethernet/airoha/airoha_eth.c:219:\tairoha_fe_wr(eth, REG_FE_VIP_EN(8),\ndrivers/net/ethernet/airoha/airoha_eth.c-220-\t\t PATN_FCPU_EN_MASK | PATN_SP_EN_MASK |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-223-\t/* BOOTP (0x44) */\ndrivers/net/ethernet/airoha/airoha_eth.c:224:\tairoha_fe_wr(eth, REG_FE_VIP_PATN(9), 0x44);\ndrivers/net/ethernet/airoha/airoha_eth.c:225:\tairoha_fe_wr(eth, REG_FE_VIP_EN(9),\ndrivers/net/ethernet/airoha/airoha_eth.c-226-\t\t PATN_FCPU_EN_MASK | PATN_SP_EN_MASK |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-229-\t/* ISAKMP */\ndrivers/net/ethernet/airoha/airoha_eth.c:230:\tairoha_fe_wr(eth, REG_FE_VIP_PATN(10), 0x1f401f4);\ndrivers/net/ethernet/airoha/airoha_eth.c:231:\tairoha_fe_wr(eth, REG_FE_VIP_EN(10),\ndrivers/net/ethernet/airoha/airoha_eth.c-232-\t\t PATN_FCPU_EN_MASK | PATN_DP_EN_MASK | PATN_SP_EN_MASK |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-234-\ndrivers/net/ethernet/airoha/airoha_eth.c:235:\tairoha_fe_wr(eth, REG_FE_VIP_PATN(11), PPP_IPV6CP);\ndrivers/net/ethernet/airoha/airoha_eth.c:236:\tairoha_fe_wr(eth, REG_FE_VIP_EN(11),\ndrivers/net/ethernet/airoha/airoha_eth.c-237-\t\t PATN_FCPU_EN_MASK | FIELD_PREP(PATN_TYPE_MASK, 1) |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-240-\t/* DHCPv6 */\ndrivers/net/ethernet/airoha/airoha_eth.c:241:\tairoha_fe_wr(eth, REG_FE_VIP_PATN(12), 0x2220223);\ndrivers/net/ethernet/airoha/airoha_eth.c:242:\tairoha_fe_wr(eth, REG_FE_VIP_EN(12),\ndrivers/net/ethernet/airoha/airoha_eth.c-243-\t\t PATN_FCPU_EN_MASK | PATN_DP_EN_MASK | PATN_SP_EN_MASK |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-245-\ndrivers/net/ethernet/airoha/airoha_eth.c:246:\tairoha_fe_wr(eth, REG_FE_VIP_PATN(19), PPP_PAP);\ndrivers/net/ethernet/airoha/airoha_eth.c:247:\tairoha_fe_wr(eth, REG_FE_VIP_EN(19),\ndrivers/net/ethernet/airoha/airoha_eth.c-248-\t\t PATN_FCPU_EN_MASK | FIELD_PREP(PATN_TYPE_MASK, 1) |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-251-\t/* ETH-\u003eETH_P_1905 (0x893a) */\ndrivers/net/ethernet/airoha/airoha_eth.c:252:\tairoha_fe_wr(eth, REG_FE_VIP_PATN(20), 0x893a);\ndrivers/net/ethernet/airoha/airoha_eth.c:253:\tairoha_fe_wr(eth, REG_FE_VIP_EN(20),\ndrivers/net/ethernet/airoha/airoha_eth.c-254-\t\t PATN_FCPU_EN_MASK | PATN_EN_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c-255-\ndrivers/net/ethernet/airoha/airoha_eth.c:256:\tairoha_fe_wr(eth, REG_FE_VIP_PATN(21), ETH_P_LLDP);\ndrivers/net/ethernet/airoha/airoha_eth.c:257:\tairoha_fe_wr(eth, REG_FE_VIP_EN(21),\ndrivers/net/ethernet/airoha/airoha_eth.c-258-\t\t PATN_FCPU_EN_MASK | PATN_EN_MASK);\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-260-\ndrivers/net/ethernet/airoha/airoha_eth.c:261:static u32 airoha_fe_get_pse_queue_rsv_pages(struct airoha_eth *eth,\ndrivers/net/ethernet/airoha/airoha_eth.c-262-\t\t\t\t\t u32 port, u32 queue)\ndrivers/net/ethernet/airoha/airoha_eth.c-263-{\ndrivers/net/ethernet/airoha/airoha_eth.c:264:\tairoha_fe_rmw(eth, REG_FE_PSE_QUEUE_CFG_WR,\ndrivers/net/ethernet/airoha/airoha_eth.c-265-\t\t PSE_CFG_PORT_ID_MASK | PSE_CFG_QUEUE_ID_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-268-\ndrivers/net/ethernet/airoha/airoha_eth.c:269:\treturn airoha_fe_get(eth, REG_FE_PSE_QUEUE_CFG_VAL,\ndrivers/net/ethernet/airoha/airoha_eth.c-270-\t\t\t PSE_CFG_OQ_RSV_MASK);\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-272-\ndrivers/net/ethernet/airoha/airoha_eth.c:273:static void airoha_fe_set_pse_queue_rsv_pages(struct airoha_eth *eth,\ndrivers/net/ethernet/airoha/airoha_eth.c-274-\t\t\t\t\t u32 port, u32 queue, u32 val)\ndrivers/net/ethernet/airoha/airoha_eth.c-275-{\ndrivers/net/ethernet/airoha/airoha_eth.c:276:\tairoha_fe_rmw(eth, REG_FE_PSE_QUEUE_CFG_VAL, PSE_CFG_OQ_RSV_MASK,\ndrivers/net/ethernet/airoha/airoha_eth.c-277-\t\t FIELD_PREP(PSE_CFG_OQ_RSV_MASK, val));\ndrivers/net/ethernet/airoha/airoha_eth.c:278:\tairoha_fe_rmw(eth, REG_FE_PSE_QUEUE_CFG_WR,\ndrivers/net/ethernet/airoha/airoha_eth.c-279-\t\t PSE_CFG_PORT_ID_MASK | PSE_CFG_QUEUE_ID_MASK |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-285-\ndrivers/net/ethernet/airoha/airoha_eth.c:286:static u32 airoha_fe_get_pse_all_rsv(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_eth.c-287-{\ndrivers/net/ethernet/airoha/airoha_eth.c:288:\treturn airoha_fe_get(eth, REG_FE_PSE_BUF_SET, PSE_ALLRSV_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c-289-}\ndrivers/net/ethernet/airoha/airoha_eth.c-290-\ndrivers/net/ethernet/airoha/airoha_eth.c:291:static int airoha_fe_set_pse_oq_rsv(struct airoha_eth *eth,\ndrivers/net/ethernet/airoha/airoha_eth.c-292-\t\t\t\t u32 port, u32 queue, u32 val)\ndrivers/net/ethernet/airoha/airoha_eth.c-293-{\ndrivers/net/ethernet/airoha/airoha_eth.c:294:\tu32 orig_val = airoha_fe_get_pse_queue_rsv_pages(eth, port, queue);\ndrivers/net/ethernet/airoha/airoha_eth.c-295-\tu32 tmp, all_rsv, fq_limit;\ndrivers/net/ethernet/airoha/airoha_eth.c-296-\ndrivers/net/ethernet/airoha/airoha_eth.c:297:\tairoha_fe_set_pse_queue_rsv_pages(eth, port, queue, val);\ndrivers/net/ethernet/airoha/airoha_eth.c-298-\ndrivers/net/ethernet/airoha/airoha_eth.c-299-\t/* modify all rsv */\ndrivers/net/ethernet/airoha/airoha_eth.c:300:\tall_rsv = airoha_fe_get_pse_all_rsv(eth);\ndrivers/net/ethernet/airoha/airoha_eth.c-301-\tall_rsv += (val - orig_val);\ndrivers/net/ethernet/airoha/airoha_eth.c:302:\tairoha_fe_rmw(eth, REG_FE_PSE_BUF_SET, PSE_ALLRSV_MASK,\ndrivers/net/ethernet/airoha/airoha_eth.c-303-\t\t FIELD_PREP(PSE_ALLRSV_MASK, all_rsv));\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-305-\t/* modify hthd */\ndrivers/net/ethernet/airoha/airoha_eth.c:306:\tfq_limit = airoha_fe_get(eth, PSE_FQ_CFG, PSE_FQ_LIMIT_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c-307-\ttmp = fq_limit - all_rsv - 0x20;\ndrivers/net/ethernet/airoha/airoha_eth.c:308:\tairoha_fe_rmw(eth, REG_PSE_SHARE_USED_THD,\ndrivers/net/ethernet/airoha/airoha_eth.c-309-\t\t PSE_SHARE_USED_HTHD_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-312-\ttmp = fq_limit - all_rsv - 0x100;\ndrivers/net/ethernet/airoha/airoha_eth.c:313:\tairoha_fe_rmw(eth, REG_PSE_SHARE_USED_THD,\ndrivers/net/ethernet/airoha/airoha_eth.c-314-\t\t PSE_SHARE_USED_MTHD_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-316-\ttmp = (3 * tmp) \u003e\u003e 2;\ndrivers/net/ethernet/airoha/airoha_eth.c:317:\tairoha_fe_rmw(eth, REG_FE_PSE_BUF_SET,\ndrivers/net/ethernet/airoha/airoha_eth.c-318-\t\t PSE_SHARE_USED_LTHD_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-323-\ndrivers/net/ethernet/airoha/airoha_eth.c:324:static void airoha_fe_pse_ports_init(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_eth.c-325-{\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-340-\ndrivers/net/ethernet/airoha/airoha_eth.c:341:\tif (airoha_ppe_is_enabled(eth, 1)) {\ndrivers/net/ethernet/airoha/airoha_eth.c-342-\t\tu32 all_rsv;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-344-\t\t/* hw misses PPE2 oq rsv */\ndrivers/net/ethernet/airoha/airoha_eth.c:345:\t\tall_rsv = airoha_fe_get_pse_all_rsv(eth);\ndrivers/net/ethernet/airoha/airoha_eth.c-346-\t\tall_rsv += PSE_RSV_PAGES *\ndrivers/net/ethernet/airoha/airoha_eth.c-347-\t\t\t pse_port_num_queues[FE_PSE_PORT_PPE2];\ndrivers/net/ethernet/airoha/airoha_eth.c:348:\t\tairoha_fe_rmw(eth, REG_FE_PSE_BUF_SET, PSE_ALLRSV_MASK,\ndrivers/net/ethernet/airoha/airoha_eth.c-349-\t\t\t FIELD_PREP(PSE_ALLRSV_MASK, all_rsv));\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-353-\tfor (q = 0; q \u003c pse_port_num_queues[FE_PSE_PORT_CDM1]; q++)\ndrivers/net/ethernet/airoha/airoha_eth.c:354:\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM1, q,\ndrivers/net/ethernet/airoha/airoha_eth.c-355-\t\t\t\t\t PSE_QUEUE_RSV_PAGES);\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-357-\tfor (q = 0; q \u003c pse_port_num_queues[FE_PSE_PORT_GDM1]; q++)\ndrivers/net/ethernet/airoha/airoha_eth.c:358:\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM1, q,\ndrivers/net/ethernet/airoha/airoha_eth.c-359-\t\t\t\t\t PSE_QUEUE_RSV_PAGES);\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-361-\tfor (q = 6; q \u003c pse_port_num_queues[FE_PSE_PORT_GDM2]; q++)\ndrivers/net/ethernet/airoha/airoha_eth.c:362:\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM2, q, 0);\ndrivers/net/ethernet/airoha/airoha_eth.c-363-\t/* GDM3 */\ndrivers/net/ethernet/airoha/airoha_eth.c-364-\tfor (q = 0; q \u003c pse_port_num_queues[FE_PSE_PORT_GDM3]; q++)\ndrivers/net/ethernet/airoha/airoha_eth.c:365:\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM3, q,\ndrivers/net/ethernet/airoha/airoha_eth.c-366-\t\t\t\t\t PSE_QUEUE_RSV_PAGES);\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-369-\t\tif (q \u003c pse_port_num_queues[FE_PSE_PORT_PPE1] / 2)\ndrivers/net/ethernet/airoha/airoha_eth.c:370:\t\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE1, q,\ndrivers/net/ethernet/airoha/airoha_eth.c-371-\t\t\t\t\t\t PSE_QUEUE_RSV_PAGES);\ndrivers/net/ethernet/airoha/airoha_eth.c-372-\t\telse\ndrivers/net/ethernet/airoha/airoha_eth.c:373:\t\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE1, q, 0);\ndrivers/net/ethernet/airoha/airoha_eth.c-374-\t}\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-376-\tfor (q = 0; q \u003c pse_port_num_queues[FE_PSE_PORT_CDM2]; q++)\ndrivers/net/ethernet/airoha/airoha_eth.c:377:\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM2, q,\ndrivers/net/ethernet/airoha/airoha_eth.c-378-\t\t\t\t\t PSE_QUEUE_RSV_PAGES);\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-380-\tfor (q = 0; q \u003c pse_port_num_queues[FE_PSE_PORT_CDM3] - 1; q++)\ndrivers/net/ethernet/airoha/airoha_eth.c:381:\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM3, q, 0);\ndrivers/net/ethernet/airoha/airoha_eth.c-382-\t/* CDM4 */\ndrivers/net/ethernet/airoha/airoha_eth.c-383-\tfor (q = 4; q \u003c pse_port_num_queues[FE_PSE_PORT_CDM4]; q++)\ndrivers/net/ethernet/airoha/airoha_eth.c:384:\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM4, q,\ndrivers/net/ethernet/airoha/airoha_eth.c-385-\t\t\t\t\t PSE_QUEUE_RSV_PAGES);\ndrivers/net/ethernet/airoha/airoha_eth.c:386:\tif (airoha_ppe_is_enabled(eth, 1)) {\ndrivers/net/ethernet/airoha/airoha_eth.c-387-\t\t/* PPE2 */\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-389-\t\t\tif (q \u003c pse_port_num_queues[FE_PSE_PORT_PPE2] / 2)\ndrivers/net/ethernet/airoha/airoha_eth.c:390:\t\t\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE2,\ndrivers/net/ethernet/airoha/airoha_eth.c-391-\t\t\t\t\t\t\t q,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-393-\t\t\telse\ndrivers/net/ethernet/airoha/airoha_eth.c:394:\t\t\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE2,\ndrivers/net/ethernet/airoha/airoha_eth.c-395-\t\t\t\t\t\t\t q, 0);\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-399-\tfor (q = 0; q \u003c pse_port_num_queues[FE_PSE_PORT_GDM4]; q++)\ndrivers/net/ethernet/airoha/airoha_eth.c:400:\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM4, q,\ndrivers/net/ethernet/airoha/airoha_eth.c-401-\t\t\t\t\t PSE_QUEUE_RSV_PAGES);\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-403-\tfor (q = 0; q \u003c pse_port_num_queues[FE_PSE_PORT_CDM5]; q++)\ndrivers/net/ethernet/airoha/airoha_eth.c:404:\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM5, q,\ndrivers/net/ethernet/airoha/airoha_eth.c-405-\t\t\t\t\t PSE_QUEUE_RSV_PAGES);\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-407-\ndrivers/net/ethernet/airoha/airoha_eth.c:408:static int airoha_fe_mc_vlan_clear(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_eth.c-409-{\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-415-\ndrivers/net/ethernet/airoha/airoha_eth.c:416:\t\tairoha_fe_wr(eth, REG_MC_VLAN_DATA, 0x0);\ndrivers/net/ethernet/airoha/airoha_eth.c-417-\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-419-\t\t MC_VLAN_CFG_TABLE_SEL_MASK | MC_VLAN_CFG_RW_MASK;\ndrivers/net/ethernet/airoha/airoha_eth.c:420:\t\tairoha_fe_wr(eth, REG_MC_VLAN_CFG, val);\ndrivers/net/ethernet/airoha/airoha_eth.c:421:\t\terr = read_poll_timeout(airoha_fe_rr, val,\ndrivers/net/ethernet/airoha/airoha_eth.c-422-\t\t\t\t\tval \u0026 MC_VLAN_CFG_CMD_DONE_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-428-\t\tfor (j = 0; j \u003c AIROHA_FE_MC_MAX_VLAN_PORT; j++) {\ndrivers/net/ethernet/airoha/airoha_eth.c:429:\t\t\tairoha_fe_wr(eth, REG_MC_VLAN_DATA, 0x0);\ndrivers/net/ethernet/airoha/airoha_eth.c-430-\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-433-\t\t\t MC_VLAN_CFG_RW_MASK;\ndrivers/net/ethernet/airoha/airoha_eth.c:434:\t\t\tairoha_fe_wr(eth, REG_MC_VLAN_CFG, val);\ndrivers/net/ethernet/airoha/airoha_eth.c:435:\t\t\terr = read_poll_timeout(airoha_fe_rr, val,\ndrivers/net/ethernet/airoha/airoha_eth.c-436-\t\t\t\t\t\tval \u0026 MC_VLAN_CFG_CMD_DONE_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-447-\ndrivers/net/ethernet/airoha/airoha_eth.c:448:static void airoha_fe_crsn_qsel_init(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_eth.c-449-{\ndrivers/net/ethernet/airoha/airoha_eth.c-450-\t/* CDM1_CRSN_QSEL */\ndrivers/net/ethernet/airoha/airoha_eth.c:451:\tairoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(1, CRSN_22 \u003e\u003e 2),\ndrivers/net/ethernet/airoha/airoha_eth.c-452-\t\t CDM_CRSN_QSEL_REASON_MASK(CRSN_22),\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-454-\t\t\t\t CDM_CRSN_QSEL_Q1));\ndrivers/net/ethernet/airoha/airoha_eth.c:455:\tairoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(1, CRSN_08 \u003e\u003e 2),\ndrivers/net/ethernet/airoha/airoha_eth.c-456-\t\t CDM_CRSN_QSEL_REASON_MASK(CRSN_08),\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-458-\t\t\t\t CDM_CRSN_QSEL_Q1));\ndrivers/net/ethernet/airoha/airoha_eth.c:459:\tairoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(1, CRSN_21 \u003e\u003e 2),\ndrivers/net/ethernet/airoha/airoha_eth.c-460-\t\t CDM_CRSN_QSEL_REASON_MASK(CRSN_21),\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-462-\t\t\t\t CDM_CRSN_QSEL_Q1));\ndrivers/net/ethernet/airoha/airoha_eth.c:463:\tairoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(1, CRSN_24 \u003e\u003e 2),\ndrivers/net/ethernet/airoha/airoha_eth.c-464-\t\t CDM_CRSN_QSEL_REASON_MASK(CRSN_24),\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-466-\t\t\t\t CDM_CRSN_QSEL_Q6));\ndrivers/net/ethernet/airoha/airoha_eth.c:467:\tairoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(1, CRSN_25 \u003e\u003e 2),\ndrivers/net/ethernet/airoha/airoha_eth.c-468-\t\t CDM_CRSN_QSEL_REASON_MASK(CRSN_25),\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-471-\t/* CDM2_CRSN_QSEL */\ndrivers/net/ethernet/airoha/airoha_eth.c:472:\tairoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(2, CRSN_08 \u003e\u003e 2),\ndrivers/net/ethernet/airoha/airoha_eth.c-473-\t\t CDM_CRSN_QSEL_REASON_MASK(CRSN_08),\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-475-\t\t\t\t CDM_CRSN_QSEL_Q1));\ndrivers/net/ethernet/airoha/airoha_eth.c:476:\tairoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(2, CRSN_21 \u003e\u003e 2),\ndrivers/net/ethernet/airoha/airoha_eth.c-477-\t\t CDM_CRSN_QSEL_REASON_MASK(CRSN_21),\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-479-\t\t\t\t CDM_CRSN_QSEL_Q1));\ndrivers/net/ethernet/airoha/airoha_eth.c:480:\tairoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(2, CRSN_22 \u003e\u003e 2),\ndrivers/net/ethernet/airoha/airoha_eth.c-481-\t\t CDM_CRSN_QSEL_REASON_MASK(CRSN_22),\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-483-\t\t\t\t CDM_CRSN_QSEL_Q1));\ndrivers/net/ethernet/airoha/airoha_eth.c:484:\tairoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(2, CRSN_24 \u003e\u003e 2),\ndrivers/net/ethernet/airoha/airoha_eth.c-485-\t\t CDM_CRSN_QSEL_REASON_MASK(CRSN_24),\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-487-\t\t\t\t CDM_CRSN_QSEL_Q6));\ndrivers/net/ethernet/airoha/airoha_eth.c:488:\tairoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(2, CRSN_25 \u003e\u003e 2),\ndrivers/net/ethernet/airoha/airoha_eth.c-489-\t\t CDM_CRSN_QSEL_REASON_MASK(CRSN_25),\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-493-\ndrivers/net/ethernet/airoha/airoha_eth.c:494:static int airoha_fe_init(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_eth.c-495-{\ndrivers/net/ethernet/airoha/airoha_eth.c:496:\tairoha_fe_maccr_init(eth);\ndrivers/net/ethernet/airoha/airoha_eth.c-497-\ndrivers/net/ethernet/airoha/airoha_eth.c-498-\t/* PSE IQ reserve */\ndrivers/net/ethernet/airoha/airoha_eth.c:499:\tairoha_fe_rmw(eth, REG_PSE_IQ_REV1, PSE_IQ_RES1_P2_MASK,\ndrivers/net/ethernet/airoha/airoha_eth.c-500-\t\t FIELD_PREP(PSE_IQ_RES1_P2_MASK, 0x10));\ndrivers/net/ethernet/airoha/airoha_eth.c:501:\tairoha_fe_rmw(eth, REG_PSE_IQ_REV2,\ndrivers/net/ethernet/airoha/airoha_eth.c-502-\t\t PSE_IQ_RES2_P5_MASK | PSE_IQ_RES2_P4_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-506-\t/* enable FE copy engine for KA/DPI */\ndrivers/net/ethernet/airoha/airoha_eth.c:507:\tairoha_fe_wr(eth, REG_FE_PCE_CFG, PCE_DPI_EN_MASK | PCE_KA_EN_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c-508-\t/* set vip queue selection to ring 1 */\ndrivers/net/ethernet/airoha/airoha_eth.c:509:\tairoha_fe_rmw(eth, REG_CDM_FWD_CFG(1), CDM_VIP_QSEL_MASK,\ndrivers/net/ethernet/airoha/airoha_eth.c-510-\t\t FIELD_PREP(CDM_VIP_QSEL_MASK, 0x4));\ndrivers/net/ethernet/airoha/airoha_eth.c:511:\tairoha_fe_rmw(eth, REG_CDM_FWD_CFG(2), CDM_VIP_QSEL_MASK,\ndrivers/net/ethernet/airoha/airoha_eth.c-512-\t\t FIELD_PREP(CDM_VIP_QSEL_MASK, 0x4));\ndrivers/net/ethernet/airoha/airoha_eth.c-513-\t/* set GDM4 source interface offset to 8 */\ndrivers/net/ethernet/airoha/airoha_eth.c:514:\tairoha_fe_rmw(eth, REG_GDM_SRC_PORT_SET(4),\ndrivers/net/ethernet/airoha/airoha_eth.c-515-\t\t GDM_SPORT_OFF2_MASK |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-522-\t/* set PSE Page as 128B */\ndrivers/net/ethernet/airoha/airoha_eth.c:523:\tairoha_fe_rmw(eth, REG_FE_DMA_GLO_CFG,\ndrivers/net/ethernet/airoha/airoha_eth.c-524-\t\t FE_DMA_GLO_L2_SPACE_MASK | FE_DMA_GLO_PG_SZ_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-526-\t\t FE_DMA_GLO_PG_SZ_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c:527:\tairoha_fe_wr(eth, REG_FE_RST_GLO_CFG,\ndrivers/net/ethernet/airoha/airoha_eth.c-528-\t\t FE_RST_CORE_MASK | FE_RST_GDM3_MBI_ARB_MASK |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-534-\t */\ndrivers/net/ethernet/airoha/airoha_eth.c:535:\tairoha_fe_wr(eth, REG_FE_CDM1_OQ_MAP0, BIT(4));\ndrivers/net/ethernet/airoha/airoha_eth.c:536:\tairoha_fe_wr(eth, REG_FE_CDM1_OQ_MAP1, BIT(28));\ndrivers/net/ethernet/airoha/airoha_eth.c:537:\tairoha_fe_wr(eth, REG_FE_CDM1_OQ_MAP2, BIT(4));\ndrivers/net/ethernet/airoha/airoha_eth.c:538:\tairoha_fe_wr(eth, REG_FE_CDM1_OQ_MAP3, BIT(28));\ndrivers/net/ethernet/airoha/airoha_eth.c-539-\ndrivers/net/ethernet/airoha/airoha_eth.c:540:\tairoha_fe_vip_setup(eth);\ndrivers/net/ethernet/airoha/airoha_eth.c:541:\tairoha_fe_pse_ports_init(eth);\ndrivers/net/ethernet/airoha/airoha_eth.c-542-\ndrivers/net/ethernet/airoha/airoha_eth.c:543:\tairoha_fe_set(eth, REG_GDM_MISC_CFG,\ndrivers/net/ethernet/airoha/airoha_eth.c-544-\t\t GDM2_RDM_ACK_WAIT_PREF_MASK |\ndrivers/net/ethernet/airoha/airoha_eth.c-545-\t\t GDM2_CHN_VLD_MODE_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c:546:\tairoha_fe_rmw(eth, REG_CDM_FWD_CFG(2), CDM_OAM_QSEL_MASK,\ndrivers/net/ethernet/airoha/airoha_eth.c-547-\t\t FIELD_PREP(CDM_OAM_QSEL_MASK, 15));\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-550-\t/* NPU Core-3, NPU Bridge Channel-3 */\ndrivers/net/ethernet/airoha/airoha_eth.c:551:\tairoha_fe_rmw(eth, REG_IP_FRAG_FP,\ndrivers/net/ethernet/airoha/airoha_eth.c-552-\t\t IP_FRAGMENT_PORT_MASK | IP_FRAGMENT_NBQ_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-555-\t/* QDMA LAN, RX Ring-22 */\ndrivers/net/ethernet/airoha/airoha_eth.c:556:\tairoha_fe_rmw(eth, REG_IP_FRAG_FP,\ndrivers/net/ethernet/airoha/airoha_eth.c-557-\t\t IP_ASSEMBLE_PORT_MASK | IP_ASSEMBLE_NBQ_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-560-\ndrivers/net/ethernet/airoha/airoha_eth.c:561:\tairoha_fe_set(eth, REG_GDM_FWD_CFG(AIROHA_GDM3_IDX), GDM_PAD_EN_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c:562:\tairoha_fe_set(eth, REG_GDM_FWD_CFG(AIROHA_GDM4_IDX), GDM_PAD_EN_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c-563-\ndrivers/net/ethernet/airoha/airoha_eth.c-564-\t/* Enable split for MIB counters for GDM3 and GDM4 */\ndrivers/net/ethernet/airoha/airoha_eth.c:565:\tairoha_fe_set(eth, REG_FE_GDM_MIB_CFG(AIROHA_GDM3_IDX),\ndrivers/net/ethernet/airoha/airoha_eth.c-566-\t\t FE_GDM_TX_MIB_SPLIT_EN_MASK |\ndrivers/net/ethernet/airoha/airoha_eth.c-567-\t\t FE_GDM_RX_MIB_SPLIT_EN_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c:568:\tairoha_fe_set(eth, REG_FE_GDM_MIB_CFG(AIROHA_GDM4_IDX),\ndrivers/net/ethernet/airoha/airoha_eth.c-569-\t\t FE_GDM_TX_MIB_SPLIT_EN_MASK |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-571-\ndrivers/net/ethernet/airoha/airoha_eth.c:572:\tairoha_fe_crsn_qsel_init(eth);\ndrivers/net/ethernet/airoha/airoha_eth.c-573-\ndrivers/net/ethernet/airoha/airoha_eth.c:574:\tairoha_fe_clear(eth, REG_FE_CPORT_CFG, FE_CPORT_QUEUE_XFC_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c:575:\tairoha_fe_set(eth, REG_FE_CPORT_CFG, FE_CPORT_PORT_XFC_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c-576-\ndrivers/net/ethernet/airoha/airoha_eth.c-577-\t/* default aging mode for mbi unlock issue */\ndrivers/net/ethernet/airoha/airoha_eth.c:578:\tairoha_fe_rmw(eth, REG_GDM_CHN_RLS(2),\ndrivers/net/ethernet/airoha/airoha_eth.c-579-\t\t MBI_RX_AGE_SEL_MASK | MBI_TX_AGE_SEL_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-583-\t/* disable IFC by default */\ndrivers/net/ethernet/airoha/airoha_eth.c:584:\tairoha_fe_clear(eth, REG_FE_CSR_IFC_CFG, FE_IFC_EN_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c-585-\ndrivers/net/ethernet/airoha/airoha_eth.c-586-\t/* enable 1:N vlan action, init vlan table */\ndrivers/net/ethernet/airoha/airoha_eth.c:587:\tairoha_fe_set(eth, REG_MC_VLAN_EN, MC_VLAN_EN_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c-588-\ndrivers/net/ethernet/airoha/airoha_eth.c:589:\treturn airoha_fe_mc_vlan_clear(eth);\ndrivers/net/ethernet/airoha/airoha_eth.c-590-}\ndrivers/net/ethernet/airoha/airoha_eth.c-591-\ndrivers/net/ethernet/airoha/airoha_eth.c:592:static int airoha_qdma_fill_rx_queue(struct airoha_queue *q)\ndrivers/net/ethernet/airoha/airoha_eth.c-593-{\ndrivers/net/ethernet/airoha/airoha_eth.c:594:\tstruct airoha_qdma *qdma = q-\u003eqdma;\ndrivers/net/ethernet/airoha/airoha_eth.c-595-\tint qid = q - \u0026qdma-\u003eq_rx[0];\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-598-\twhile (q-\u003equeued \u003c q-\u003endesc - 1) {\ndrivers/net/ethernet/airoha/airoha_eth.c:599:\t\tstruct airoha_queue_entry *e = \u0026q-\u003eentry[q-\u003ehead];\ndrivers/net/ethernet/airoha/airoha_eth.c:600:\t\tstruct airoha_qdma_desc *desc = \u0026q-\u003edesc[q-\u003ehead];\ndrivers/net/ethernet/airoha/airoha_eth.c-601-\t\tstruct page *page;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-630-\tif (nframes)\ndrivers/net/ethernet/airoha/airoha_eth.c:631:\t\tairoha_qdma_rmw(qdma, REG_RX_CPU_IDX(qid),\ndrivers/net/ethernet/airoha/airoha_eth.c-632-\t\t\t\tRX_RING_CPU_IDX_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-637-\ndrivers/net/ethernet/airoha/airoha_eth.c:638:static struct airoha_gdm_dev *\ndrivers/net/ethernet/airoha/airoha_eth.c:639:airoha_qdma_get_gdm_dev(struct airoha_eth *eth, struct airoha_qdma_desc *desc)\ndrivers/net/ethernet/airoha/airoha_eth.c-640-{\ndrivers/net/ethernet/airoha/airoha_eth.c:641:\tstruct airoha_gdm_port *port;\ndrivers/net/ethernet/airoha/airoha_eth.c-642-\tu16 p, d;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-659-\ndrivers/net/ethernet/airoha/airoha_eth.c:660:static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)\ndrivers/net/ethernet/airoha/airoha_eth.c-661-{\ndrivers/net/ethernet/airoha/airoha_eth.c-662-\tenum dma_data_direction dir = page_pool_get_dma_dir(q-\u003epage_pool);\ndrivers/net/ethernet/airoha/airoha_eth.c:663:\tstruct airoha_qdma *qdma = q-\u003eqdma;\ndrivers/net/ethernet/airoha/airoha_eth.c:664:\tstruct airoha_eth *eth = qdma-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_eth.c-665-\tint qid = q - \u0026qdma-\u003eq_rx[0];\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-668-\twhile (done \u003c budget) {\ndrivers/net/ethernet/airoha/airoha_eth.c:669:\t\tstruct airoha_queue_entry *e = \u0026q-\u003eentry[q-\u003etail];\ndrivers/net/ethernet/airoha/airoha_eth.c:670:\t\tstruct airoha_qdma_desc *desc = \u0026q-\u003edesc[q-\u003etail];\ndrivers/net/ethernet/airoha/airoha_eth.c-671-\t\tu32 hash, reason, msg1, desc_ctrl;\n\n"
} |
| 13/2 | 2026/07/21 07:04 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 64346 output: 26 thoughts: 479 Thoughts: **Analyzing the Reachability of `airoha_eth` Driver for Fuzzing** Okay, so I'm thinking about this `airoha_eth` driver. It's a platform driver, right? And I'm trying to figure out if it's worth fuzzing using syzkaller. The immediate thing that jumps out is the potential disconnect. Syzkaller has a lot of cool features: `syz_devlink` (for devlink, though not relevant here), `syz_init_net_socket`, even `syz_mount_image`, `syz_usb_connect`, `syz_80211_join_ibss`, and `syz_kvm_setup_cpu`. It can open device files (`syz_open_dev`) too, which I find interesting in light of platform drivers, but none of these readily create platform devices with *arbitrary MMIO regions* that respond to `read_poll_timeout` in a truly generic fashion. This is the crux of the problem. The fact that syzkaller *doesn't* have a clear path to instantiating these specific devices is concerning, it's the elephant in the room. But then I'm wondering, if this is unreachable code, why would syzbot even touch it? Then I remembered: syzbot hits everything submitted to netdev, right? It's just a broad net, it applies the patch, builds, and runs the corpus. So a "pass" on the test doesn't actually mean the code was exercised, just that there were no immediate build problems. That explains it. Then, the prompt itself becomes crucial. It says we should return `WorthFuzzing=false` if the patch only contains unreachable code paths in virtualized environments like GCE or QEMU, even with software emulated hardware like `mac80211_hwsim`. And the pieces of the puzzle come together. `airoha_eth` is *hardware-specific* to Airoha SoCs. There's no software emulator for Airoha, no `mac80211_hwsim` equivalent, no `netdevsim` for Airoha. This seems like a pretty clear case of code that is simply *unreachable* in our target environments. Now, to be absolutely sure, I'll double-check to make sure there really isn't some hidden emulator in the kernel that I'm overlooking... just to be completely certain. |
| 14/2 | 2026/07/21 07:04 | tool | grepper |
0mArgs:{
"Expression": "airoha",
"PathPrefix": "drivers/net/"
}Results: {
"Output": "\nFull output is too long, showing 500 out of 4063 lines.\nUse more precise expression if possible.\n\ndrivers/net/dsa/mt7530-mmio.c=12=static const struct of_device_id mt7988_of_match[] = {\ndrivers/net/dsa/mt7530-mmio.c:13:\t{ .compatible = \"airoha,an7583-switch\", .data = \u0026mt753x_table[ID_AN7583], },\ndrivers/net/dsa/mt7530-mmio.c:14:\t{ .compatible = \"airoha,en7581-switch\", .data = \u0026mt753x_table[ID_EN7581], },\ndrivers/net/dsa/mt7530-mmio.c-15-\t{ .compatible = \"mediatek,mt7988-switch\", .data = \u0026mt753x_table[ID_MT7988], },\n--\ndrivers/net/ethernet/Kconfig=22=source \"drivers/net/ethernet/agere/Kconfig\"\ndrivers/net/ethernet/Kconfig:23:source \"drivers/net/ethernet/airoha/Kconfig\"\ndrivers/net/ethernet/Kconfig-24-source \"drivers/net/ethernet/alacritech/Kconfig\"\n--\ndrivers/net/ethernet/Makefile=12=obj-$(CONFIG_NET_VENDOR_AGERE) += agere/\ndrivers/net/ethernet/Makefile:13:obj-$(CONFIG_NET_VENDOR_AIROHA) += airoha/\ndrivers/net/ethernet/Makefile-14-obj-$(CONFIG_NET_VENDOR_ALACRITECH) += alacritech/\n--\ndrivers/net/ethernet/airoha/Makefile-5-\ndrivers/net/ethernet/airoha/Makefile:6:obj-$(CONFIG_NET_AIROHA) += airoha-eth.o\ndrivers/net/ethernet/airoha/Makefile:7:airoha-eth-y := airoha_eth.o airoha_ppe.o\ndrivers/net/ethernet/airoha/Makefile:8:airoha-eth-$(CONFIG_DEBUG_FS) += airoha_ppe_debugfs.o\ndrivers/net/ethernet/airoha/Makefile:9:obj-$(CONFIG_NET_AIROHA_NPU) += airoha_npu.o\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-16-\ndrivers/net/ethernet/airoha/airoha_eth.c:17:#include \"airoha_regs.h\"\ndrivers/net/ethernet/airoha/airoha_eth.c:18:#include \"airoha_eth.h\"\ndrivers/net/ethernet/airoha/airoha_eth.c-19-\ndrivers/net/ethernet/airoha/airoha_eth.c:20:u32 airoha_rr(void __iomem *base, u32 offset)\ndrivers/net/ethernet/airoha/airoha_eth.c-21-{\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-24-\ndrivers/net/ethernet/airoha/airoha_eth.c:25:void airoha_wr(void __iomem *base, u32 offset, u32 val)\ndrivers/net/ethernet/airoha/airoha_eth.c-26-{\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-29-\ndrivers/net/ethernet/airoha/airoha_eth.c:30:u32 airoha_rmw(void __iomem *base, u32 offset, u32 mask, u32 val)\ndrivers/net/ethernet/airoha/airoha_eth.c-31-{\ndrivers/net/ethernet/airoha/airoha_eth.c:32:\tval |= (airoha_rr(base, offset) \u0026 ~mask);\ndrivers/net/ethernet/airoha/airoha_eth.c:33:\tairoha_wr(base, offset, val);\ndrivers/net/ethernet/airoha/airoha_eth.c-34-\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-37-\ndrivers/net/ethernet/airoha/airoha_eth.c:38:static void airoha_qdma_set_irqmask(struct airoha_irq_bank *irq_bank,\ndrivers/net/ethernet/airoha/airoha_eth.c-39-\t\t\t\t int index, u32 clear, u32 set)\ndrivers/net/ethernet/airoha/airoha_eth.c-40-{\ndrivers/net/ethernet/airoha/airoha_eth.c:41:\tstruct airoha_qdma *qdma = irq_bank-\u003eqdma;\ndrivers/net/ethernet/airoha/airoha_eth.c-42-\tint bank = irq_bank - \u0026qdma-\u003eirq_banks[0];\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-51-\tirq_bank-\u003eirqmask[index] |= set;\ndrivers/net/ethernet/airoha/airoha_eth.c:52:\tairoha_qdma_wr(qdma, REG_INT_ENABLE(bank, index),\ndrivers/net/ethernet/airoha/airoha_eth.c-53-\t\t irq_bank-\u003eirqmask[index]);\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-56-\t */\ndrivers/net/ethernet/airoha/airoha_eth.c:57:\tairoha_qdma_rr(qdma, REG_INT_ENABLE(bank, index));\ndrivers/net/ethernet/airoha/airoha_eth.c-58-\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-61-\ndrivers/net/ethernet/airoha/airoha_eth.c:62:static void airoha_qdma_irq_enable(struct airoha_irq_bank *irq_bank,\ndrivers/net/ethernet/airoha/airoha_eth.c-63-\t\t\t\t int index, u32 mask)\ndrivers/net/ethernet/airoha/airoha_eth.c-64-{\ndrivers/net/ethernet/airoha/airoha_eth.c:65:\tairoha_qdma_set_irqmask(irq_bank, index, 0, mask);\ndrivers/net/ethernet/airoha/airoha_eth.c-66-}\ndrivers/net/ethernet/airoha/airoha_eth.c-67-\ndrivers/net/ethernet/airoha/airoha_eth.c:68:static void airoha_qdma_irq_disable(struct airoha_irq_bank *irq_bank,\ndrivers/net/ethernet/airoha/airoha_eth.c-69-\t\t\t\t int index, u32 mask)\ndrivers/net/ethernet/airoha/airoha_eth.c-70-{\ndrivers/net/ethernet/airoha/airoha_eth.c:71:\tairoha_qdma_set_irqmask(irq_bank, index, mask, 0);\ndrivers/net/ethernet/airoha/airoha_eth.c-72-}\ndrivers/net/ethernet/airoha/airoha_eth.c-73-\ndrivers/net/ethernet/airoha/airoha_eth.c:74:static int airoha_set_macaddr(struct airoha_gdm_dev *dev, const u8 *addr)\ndrivers/net/ethernet/airoha/airoha_eth.c-75-{\ndrivers/net/ethernet/airoha/airoha_eth.c-76-\tu8 ref_addr[ETH_ALEN] __aligned(2);\ndrivers/net/ethernet/airoha/airoha_eth.c:77:\tstruct airoha_eth *eth = dev-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_eth.c-78-\tu32 reg, val, lmin, lmax;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-85-\tfor (i = 0; i \u003c ARRAY_SIZE(eth-\u003eports); i++) {\ndrivers/net/ethernet/airoha/airoha_eth.c:86:\t\tstruct airoha_gdm_port *port = eth-\u003eports[i];\ndrivers/net/ethernet/airoha/airoha_eth.c-87-\t\tint j;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-92-\t\tfor (j = 0; j \u003c ARRAY_SIZE(port-\u003edevs); j++) {\ndrivers/net/ethernet/airoha/airoha_eth.c:93:\t\t\tstruct airoha_gdm_dev *iter_dev;\ndrivers/net/ethernet/airoha/airoha_eth.c-94-\t\t\tstruct net_device *netdev;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-99-\ndrivers/net/ethernet/airoha/airoha_eth.c:100:\t\t\tif (airoha_is_lan_gdm_dev(iter_dev) !=\ndrivers/net/ethernet/airoha/airoha_eth.c:101:\t\t\t airoha_is_lan_gdm_dev(dev))\ndrivers/net/ethernet/airoha/airoha_eth.c-102-\t\t\t\tcontinue;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-133-\ndrivers/net/ethernet/airoha/airoha_eth.c:134:\treg = airoha_is_lan_gdm_dev(dev) ? REG_FE_LAN_MAC_H : REG_FE_WAN_MAC_H;\ndrivers/net/ethernet/airoha/airoha_eth.c-135-\tval = (addr[0] \u003c\u003c 16) | (addr[1] \u003c\u003c 8) | addr[2];\ndrivers/net/ethernet/airoha/airoha_eth.c:136:\tairoha_fe_wr(eth, reg, val);\ndrivers/net/ethernet/airoha/airoha_eth.c-137-\ndrivers/net/ethernet/airoha/airoha_eth.c:138:\tairoha_fe_wr(eth, REG_FE_MAC_LMIN(reg), lmin);\ndrivers/net/ethernet/airoha/airoha_eth.c:139:\tairoha_fe_wr(eth, REG_FE_MAC_LMAX(reg), lmax);\ndrivers/net/ethernet/airoha/airoha_eth.c-140-\ndrivers/net/ethernet/airoha/airoha_eth.c:141:\tairoha_ppe_init_upd_mem(dev, addr);\ndrivers/net/ethernet/airoha/airoha_eth.c-142-\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-145-\ndrivers/net/ethernet/airoha/airoha_eth.c:146:static void airoha_set_gdm_port_fwd_cfg(struct airoha_eth *eth, u32 addr,\ndrivers/net/ethernet/airoha/airoha_eth.c-147-\t\t\t\t\tu32 val)\ndrivers/net/ethernet/airoha/airoha_eth.c-148-{\ndrivers/net/ethernet/airoha/airoha_eth.c:149:\tairoha_fe_rmw(eth, addr, GDM_OCFQ_MASK,\ndrivers/net/ethernet/airoha/airoha_eth.c-150-\t\t FIELD_PREP(GDM_OCFQ_MASK, val));\ndrivers/net/ethernet/airoha/airoha_eth.c:151:\tairoha_fe_rmw(eth, addr, GDM_MCFQ_MASK,\ndrivers/net/ethernet/airoha/airoha_eth.c-152-\t\t FIELD_PREP(GDM_MCFQ_MASK, val));\ndrivers/net/ethernet/airoha/airoha_eth.c:153:\tairoha_fe_rmw(eth, addr, GDM_BCFQ_MASK,\ndrivers/net/ethernet/airoha/airoha_eth.c-154-\t\t FIELD_PREP(GDM_BCFQ_MASK, val));\ndrivers/net/ethernet/airoha/airoha_eth.c:155:\tairoha_fe_rmw(eth, addr, GDM_UCFQ_MASK,\ndrivers/net/ethernet/airoha/airoha_eth.c-156-\t\t FIELD_PREP(GDM_UCFQ_MASK, val));\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-158-\ndrivers/net/ethernet/airoha/airoha_eth.c:159:static int airoha_set_vip_for_gdm_port(struct airoha_gdm_dev *dev, bool enable)\ndrivers/net/ethernet/airoha/airoha_eth.c-160-{\ndrivers/net/ethernet/airoha/airoha_eth.c:161:\tstruct airoha_gdm_port *port = dev-\u003eport;\ndrivers/net/ethernet/airoha/airoha_eth.c:162:\tstruct airoha_eth *eth = dev-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_eth.c-163-\tu32 vip_port;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-166-\tif (enable) {\ndrivers/net/ethernet/airoha/airoha_eth.c:167:\t\tairoha_fe_set(eth, REG_FE_VIP_PORT_EN, vip_port);\ndrivers/net/ethernet/airoha/airoha_eth.c:168:\t\tairoha_fe_set(eth, REG_FE_IFC_PORT_EN, vip_port);\ndrivers/net/ethernet/airoha/airoha_eth.c-169-\t} else {\ndrivers/net/ethernet/airoha/airoha_eth.c:170:\t\tairoha_fe_clear(eth, REG_FE_VIP_PORT_EN, vip_port);\ndrivers/net/ethernet/airoha/airoha_eth.c:171:\t\tairoha_fe_clear(eth, REG_FE_IFC_PORT_EN, vip_port);\ndrivers/net/ethernet/airoha/airoha_eth.c-172-\t}\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-176-\ndrivers/net/ethernet/airoha/airoha_eth.c:177:static void airoha_fe_maccr_init(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_eth.c-178-{\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-181-\tfor (p = 1; p \u003c= ARRAY_SIZE(eth-\u003eports); p++) {\ndrivers/net/ethernet/airoha/airoha_eth.c:182:\t\tairoha_fe_set(eth, REG_GDM_FWD_CFG(p),\ndrivers/net/ethernet/airoha/airoha_eth.c-183-\t\t\t GDM_TCP_CKSUM_MASK | GDM_UDP_CKSUM_MASK |\ndrivers/net/ethernet/airoha/airoha_eth.c-184-\t\t\t GDM_IP4_CKSUM_MASK | GDM_DROP_CRC_ERR_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c:185:\t\tairoha_fe_rmw(eth, REG_GDM_LEN_CFG(p),\ndrivers/net/ethernet/airoha/airoha_eth.c-186-\t\t\t GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-190-\ndrivers/net/ethernet/airoha/airoha_eth.c:191:\tairoha_fe_rmw(eth, REG_CDM_VLAN_CTRL(1), CDM_VLAN_MASK,\ndrivers/net/ethernet/airoha/airoha_eth.c-192-\t\t FIELD_PREP(CDM_VLAN_MASK, 0x8100));\ndrivers/net/ethernet/airoha/airoha_eth.c-193-\ndrivers/net/ethernet/airoha/airoha_eth.c:194:\tairoha_fe_set(eth, REG_FE_CPORT_CFG, FE_CPORT_PAD);\ndrivers/net/ethernet/airoha/airoha_eth.c-195-}\ndrivers/net/ethernet/airoha/airoha_eth.c-196-\ndrivers/net/ethernet/airoha/airoha_eth.c:197:static void airoha_fe_vip_setup(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_eth.c-198-{\ndrivers/net/ethernet/airoha/airoha_eth.c:199:\tairoha_fe_wr(eth, REG_FE_VIP_PATN(3), ETH_P_PPP_DISC);\ndrivers/net/ethernet/airoha/airoha_eth.c:200:\tairoha_fe_wr(eth, REG_FE_VIP_EN(3), PATN_FCPU_EN_MASK | PATN_EN_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c-201-\ndrivers/net/ethernet/airoha/airoha_eth.c:202:\tairoha_fe_wr(eth, REG_FE_VIP_PATN(4), PPP_LCP);\ndrivers/net/ethernet/airoha/airoha_eth.c:203:\tairoha_fe_wr(eth, REG_FE_VIP_EN(4),\ndrivers/net/ethernet/airoha/airoha_eth.c-204-\t\t PATN_FCPU_EN_MASK | FIELD_PREP(PATN_TYPE_MASK, 1) |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-206-\ndrivers/net/ethernet/airoha/airoha_eth.c:207:\tairoha_fe_wr(eth, REG_FE_VIP_PATN(6), PPP_IPCP);\ndrivers/net/ethernet/airoha/airoha_eth.c:208:\tairoha_fe_wr(eth, REG_FE_VIP_EN(6),\ndrivers/net/ethernet/airoha/airoha_eth.c-209-\t\t PATN_FCPU_EN_MASK | FIELD_PREP(PATN_TYPE_MASK, 1) |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-211-\ndrivers/net/ethernet/airoha/airoha_eth.c:212:\tairoha_fe_wr(eth, REG_FE_VIP_PATN(7), PPP_CHAP);\ndrivers/net/ethernet/airoha/airoha_eth.c:213:\tairoha_fe_wr(eth, REG_FE_VIP_EN(7),\ndrivers/net/ethernet/airoha/airoha_eth.c-214-\t\t PATN_FCPU_EN_MASK | FIELD_PREP(PATN_TYPE_MASK, 1) |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-217-\t/* BOOTP (0x43) */\ndrivers/net/ethernet/airoha/airoha_eth.c:218:\tairoha_fe_wr(eth, REG_FE_VIP_PATN(8), 0x43);\ndrivers/net/ethernet/airoha/airoha_eth.c:219:\tairoha_fe_wr(eth, REG_FE_VIP_EN(8),\ndrivers/net/ethernet/airoha/airoha_eth.c-220-\t\t PATN_FCPU_EN_MASK | PATN_SP_EN_MASK |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-223-\t/* BOOTP (0x44) */\ndrivers/net/ethernet/airoha/airoha_eth.c:224:\tairoha_fe_wr(eth, REG_FE_VIP_PATN(9), 0x44);\ndrivers/net/ethernet/airoha/airoha_eth.c:225:\tairoha_fe_wr(eth, REG_FE_VIP_EN(9),\ndrivers/net/ethernet/airoha/airoha_eth.c-226-\t\t PATN_FCPU_EN_MASK | PATN_SP_EN_MASK |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-229-\t/* ISAKMP */\ndrivers/net/ethernet/airoha/airoha_eth.c:230:\tairoha_fe_wr(eth, REG_FE_VIP_PATN(10), 0x1f401f4);\ndrivers/net/ethernet/airoha/airoha_eth.c:231:\tairoha_fe_wr(eth, REG_FE_VIP_EN(10),\ndrivers/net/ethernet/airoha/airoha_eth.c-232-\t\t PATN_FCPU_EN_MASK | PATN_DP_EN_MASK | PATN_SP_EN_MASK |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-234-\ndrivers/net/ethernet/airoha/airoha_eth.c:235:\tairoha_fe_wr(eth, REG_FE_VIP_PATN(11), PPP_IPV6CP);\ndrivers/net/ethernet/airoha/airoha_eth.c:236:\tairoha_fe_wr(eth, REG_FE_VIP_EN(11),\ndrivers/net/ethernet/airoha/airoha_eth.c-237-\t\t PATN_FCPU_EN_MASK | FIELD_PREP(PATN_TYPE_MASK, 1) |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-240-\t/* DHCPv6 */\ndrivers/net/ethernet/airoha/airoha_eth.c:241:\tairoha_fe_wr(eth, REG_FE_VIP_PATN(12), 0x2220223);\ndrivers/net/ethernet/airoha/airoha_eth.c:242:\tairoha_fe_wr(eth, REG_FE_VIP_EN(12),\ndrivers/net/ethernet/airoha/airoha_eth.c-243-\t\t PATN_FCPU_EN_MASK | PATN_DP_EN_MASK | PATN_SP_EN_MASK |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-245-\ndrivers/net/ethernet/airoha/airoha_eth.c:246:\tairoha_fe_wr(eth, REG_FE_VIP_PATN(19), PPP_PAP);\ndrivers/net/ethernet/airoha/airoha_eth.c:247:\tairoha_fe_wr(eth, REG_FE_VIP_EN(19),\ndrivers/net/ethernet/airoha/airoha_eth.c-248-\t\t PATN_FCPU_EN_MASK | FIELD_PREP(PATN_TYPE_MASK, 1) |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-251-\t/* ETH-\u003eETH_P_1905 (0x893a) */\ndrivers/net/ethernet/airoha/airoha_eth.c:252:\tairoha_fe_wr(eth, REG_FE_VIP_PATN(20), 0x893a);\ndrivers/net/ethernet/airoha/airoha_eth.c:253:\tairoha_fe_wr(eth, REG_FE_VIP_EN(20),\ndrivers/net/ethernet/airoha/airoha_eth.c-254-\t\t PATN_FCPU_EN_MASK | PATN_EN_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c-255-\ndrivers/net/ethernet/airoha/airoha_eth.c:256:\tairoha_fe_wr(eth, REG_FE_VIP_PATN(21), ETH_P_LLDP);\ndrivers/net/ethernet/airoha/airoha_eth.c:257:\tairoha_fe_wr(eth, REG_FE_VIP_EN(21),\ndrivers/net/ethernet/airoha/airoha_eth.c-258-\t\t PATN_FCPU_EN_MASK | PATN_EN_MASK);\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-260-\ndrivers/net/ethernet/airoha/airoha_eth.c:261:static u32 airoha_fe_get_pse_queue_rsv_pages(struct airoha_eth *eth,\ndrivers/net/ethernet/airoha/airoha_eth.c-262-\t\t\t\t\t u32 port, u32 queue)\ndrivers/net/ethernet/airoha/airoha_eth.c-263-{\ndrivers/net/ethernet/airoha/airoha_eth.c:264:\tairoha_fe_rmw(eth, REG_FE_PSE_QUEUE_CFG_WR,\ndrivers/net/ethernet/airoha/airoha_eth.c-265-\t\t PSE_CFG_PORT_ID_MASK | PSE_CFG_QUEUE_ID_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-268-\ndrivers/net/ethernet/airoha/airoha_eth.c:269:\treturn airoha_fe_get(eth, REG_FE_PSE_QUEUE_CFG_VAL,\ndrivers/net/ethernet/airoha/airoha_eth.c-270-\t\t\t PSE_CFG_OQ_RSV_MASK);\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-272-\ndrivers/net/ethernet/airoha/airoha_eth.c:273:static void airoha_fe_set_pse_queue_rsv_pages(struct airoha_eth *eth,\ndrivers/net/ethernet/airoha/airoha_eth.c-274-\t\t\t\t\t u32 port, u32 queue, u32 val)\ndrivers/net/ethernet/airoha/airoha_eth.c-275-{\ndrivers/net/ethernet/airoha/airoha_eth.c:276:\tairoha_fe_rmw(eth, REG_FE_PSE_QUEUE_CFG_VAL, PSE_CFG_OQ_RSV_MASK,\ndrivers/net/ethernet/airoha/airoha_eth.c-277-\t\t FIELD_PREP(PSE_CFG_OQ_RSV_MASK, val));\ndrivers/net/ethernet/airoha/airoha_eth.c:278:\tairoha_fe_rmw(eth, REG_FE_PSE_QUEUE_CFG_WR,\ndrivers/net/ethernet/airoha/airoha_eth.c-279-\t\t PSE_CFG_PORT_ID_MASK | PSE_CFG_QUEUE_ID_MASK |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-285-\ndrivers/net/ethernet/airoha/airoha_eth.c:286:static u32 airoha_fe_get_pse_all_rsv(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_eth.c-287-{\ndrivers/net/ethernet/airoha/airoha_eth.c:288:\treturn airoha_fe_get(eth, REG_FE_PSE_BUF_SET, PSE_ALLRSV_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c-289-}\ndrivers/net/ethernet/airoha/airoha_eth.c-290-\ndrivers/net/ethernet/airoha/airoha_eth.c:291:static int airoha_fe_set_pse_oq_rsv(struct airoha_eth *eth,\ndrivers/net/ethernet/airoha/airoha_eth.c-292-\t\t\t\t u32 port, u32 queue, u32 val)\ndrivers/net/ethernet/airoha/airoha_eth.c-293-{\ndrivers/net/ethernet/airoha/airoha_eth.c:294:\tu32 orig_val = airoha_fe_get_pse_queue_rsv_pages(eth, port, queue);\ndrivers/net/ethernet/airoha/airoha_eth.c-295-\tu32 tmp, all_rsv, fq_limit;\ndrivers/net/ethernet/airoha/airoha_eth.c-296-\ndrivers/net/ethernet/airoha/airoha_eth.c:297:\tairoha_fe_set_pse_queue_rsv_pages(eth, port, queue, val);\ndrivers/net/ethernet/airoha/airoha_eth.c-298-\ndrivers/net/ethernet/airoha/airoha_eth.c-299-\t/* modify all rsv */\ndrivers/net/ethernet/airoha/airoha_eth.c:300:\tall_rsv = airoha_fe_get_pse_all_rsv(eth);\ndrivers/net/ethernet/airoha/airoha_eth.c-301-\tall_rsv += (val - orig_val);\ndrivers/net/ethernet/airoha/airoha_eth.c:302:\tairoha_fe_rmw(eth, REG_FE_PSE_BUF_SET, PSE_ALLRSV_MASK,\ndrivers/net/ethernet/airoha/airoha_eth.c-303-\t\t FIELD_PREP(PSE_ALLRSV_MASK, all_rsv));\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-305-\t/* modify hthd */\ndrivers/net/ethernet/airoha/airoha_eth.c:306:\tfq_limit = airoha_fe_get(eth, PSE_FQ_CFG, PSE_FQ_LIMIT_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c-307-\ttmp = fq_limit - all_rsv - 0x20;\ndrivers/net/ethernet/airoha/airoha_eth.c:308:\tairoha_fe_rmw(eth, REG_PSE_SHARE_USED_THD,\ndrivers/net/ethernet/airoha/airoha_eth.c-309-\t\t PSE_SHARE_USED_HTHD_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-312-\ttmp = fq_limit - all_rsv - 0x100;\ndrivers/net/ethernet/airoha/airoha_eth.c:313:\tairoha_fe_rmw(eth, REG_PSE_SHARE_USED_THD,\ndrivers/net/ethernet/airoha/airoha_eth.c-314-\t\t PSE_SHARE_USED_MTHD_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-316-\ttmp = (3 * tmp) \u003e\u003e 2;\ndrivers/net/ethernet/airoha/airoha_eth.c:317:\tairoha_fe_rmw(eth, REG_FE_PSE_BUF_SET,\ndrivers/net/ethernet/airoha/airoha_eth.c-318-\t\t PSE_SHARE_USED_LTHD_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-323-\ndrivers/net/ethernet/airoha/airoha_eth.c:324:static void airoha_fe_pse_ports_init(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_eth.c-325-{\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-340-\ndrivers/net/ethernet/airoha/airoha_eth.c:341:\tif (airoha_ppe_is_enabled(eth, 1)) {\ndrivers/net/ethernet/airoha/airoha_eth.c-342-\t\tu32 all_rsv;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-344-\t\t/* hw misses PPE2 oq rsv */\ndrivers/net/ethernet/airoha/airoha_eth.c:345:\t\tall_rsv = airoha_fe_get_pse_all_rsv(eth);\ndrivers/net/ethernet/airoha/airoha_eth.c-346-\t\tall_rsv += PSE_RSV_PAGES *\ndrivers/net/ethernet/airoha/airoha_eth.c-347-\t\t\t pse_port_num_queues[FE_PSE_PORT_PPE2];\ndrivers/net/ethernet/airoha/airoha_eth.c:348:\t\tairoha_fe_rmw(eth, REG_FE_PSE_BUF_SET, PSE_ALLRSV_MASK,\ndrivers/net/ethernet/airoha/airoha_eth.c-349-\t\t\t FIELD_PREP(PSE_ALLRSV_MASK, all_rsv));\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-353-\tfor (q = 0; q \u003c pse_port_num_queues[FE_PSE_PORT_CDM1]; q++)\ndrivers/net/ethernet/airoha/airoha_eth.c:354:\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM1, q,\ndrivers/net/ethernet/airoha/airoha_eth.c-355-\t\t\t\t\t PSE_QUEUE_RSV_PAGES);\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-357-\tfor (q = 0; q \u003c pse_port_num_queues[FE_PSE_PORT_GDM1]; q++)\ndrivers/net/ethernet/airoha/airoha_eth.c:358:\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM1, q,\ndrivers/net/ethernet/airoha/airoha_eth.c-359-\t\t\t\t\t PSE_QUEUE_RSV_PAGES);\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-361-\tfor (q = 6; q \u003c pse_port_num_queues[FE_PSE_PORT_GDM2]; q++)\ndrivers/net/ethernet/airoha/airoha_eth.c:362:\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM2, q, 0);\ndrivers/net/ethernet/airoha/airoha_eth.c-363-\t/* GDM3 */\ndrivers/net/ethernet/airoha/airoha_eth.c-364-\tfor (q = 0; q \u003c pse_port_num_queues[FE_PSE_PORT_GDM3]; q++)\ndrivers/net/ethernet/airoha/airoha_eth.c:365:\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM3, q,\ndrivers/net/ethernet/airoha/airoha_eth.c-366-\t\t\t\t\t PSE_QUEUE_RSV_PAGES);\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-369-\t\tif (q \u003c pse_port_num_queues[FE_PSE_PORT_PPE1] / 2)\ndrivers/net/ethernet/airoha/airoha_eth.c:370:\t\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE1, q,\ndrivers/net/ethernet/airoha/airoha_eth.c-371-\t\t\t\t\t\t PSE_QUEUE_RSV_PAGES);\ndrivers/net/ethernet/airoha/airoha_eth.c-372-\t\telse\ndrivers/net/ethernet/airoha/airoha_eth.c:373:\t\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE1, q, 0);\ndrivers/net/ethernet/airoha/airoha_eth.c-374-\t}\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-376-\tfor (q = 0; q \u003c pse_port_num_queues[FE_PSE_PORT_CDM2]; q++)\ndrivers/net/ethernet/airoha/airoha_eth.c:377:\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM2, q,\ndrivers/net/ethernet/airoha/airoha_eth.c-378-\t\t\t\t\t PSE_QUEUE_RSV_PAGES);\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-380-\tfor (q = 0; q \u003c pse_port_num_queues[FE_PSE_PORT_CDM3] - 1; q++)\ndrivers/net/ethernet/airoha/airoha_eth.c:381:\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM3, q, 0);\ndrivers/net/ethernet/airoha/airoha_eth.c-382-\t/* CDM4 */\ndrivers/net/ethernet/airoha/airoha_eth.c-383-\tfor (q = 4; q \u003c pse_port_num_queues[FE_PSE_PORT_CDM4]; q++)\ndrivers/net/ethernet/airoha/airoha_eth.c:384:\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM4, q,\ndrivers/net/ethernet/airoha/airoha_eth.c-385-\t\t\t\t\t PSE_QUEUE_RSV_PAGES);\ndrivers/net/ethernet/airoha/airoha_eth.c:386:\tif (airoha_ppe_is_enabled(eth, 1)) {\ndrivers/net/ethernet/airoha/airoha_eth.c-387-\t\t/* PPE2 */\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-389-\t\t\tif (q \u003c pse_port_num_queues[FE_PSE_PORT_PPE2] / 2)\ndrivers/net/ethernet/airoha/airoha_eth.c:390:\t\t\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE2,\ndrivers/net/ethernet/airoha/airoha_eth.c-391-\t\t\t\t\t\t\t q,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-393-\t\t\telse\ndrivers/net/ethernet/airoha/airoha_eth.c:394:\t\t\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_PPE2,\ndrivers/net/ethernet/airoha/airoha_eth.c-395-\t\t\t\t\t\t\t q, 0);\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-399-\tfor (q = 0; q \u003c pse_port_num_queues[FE_PSE_PORT_GDM4]; q++)\ndrivers/net/ethernet/airoha/airoha_eth.c:400:\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_GDM4, q,\ndrivers/net/ethernet/airoha/airoha_eth.c-401-\t\t\t\t\t PSE_QUEUE_RSV_PAGES);\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-403-\tfor (q = 0; q \u003c pse_port_num_queues[FE_PSE_PORT_CDM5]; q++)\ndrivers/net/ethernet/airoha/airoha_eth.c:404:\t\tairoha_fe_set_pse_oq_rsv(eth, FE_PSE_PORT_CDM5, q,\ndrivers/net/ethernet/airoha/airoha_eth.c-405-\t\t\t\t\t PSE_QUEUE_RSV_PAGES);\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-407-\ndrivers/net/ethernet/airoha/airoha_eth.c:408:static int airoha_fe_mc_vlan_clear(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_eth.c-409-{\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-415-\ndrivers/net/ethernet/airoha/airoha_eth.c:416:\t\tairoha_fe_wr(eth, REG_MC_VLAN_DATA, 0x0);\ndrivers/net/ethernet/airoha/airoha_eth.c-417-\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-419-\t\t MC_VLAN_CFG_TABLE_SEL_MASK | MC_VLAN_CFG_RW_MASK;\ndrivers/net/ethernet/airoha/airoha_eth.c:420:\t\tairoha_fe_wr(eth, REG_MC_VLAN_CFG, val);\ndrivers/net/ethernet/airoha/airoha_eth.c:421:\t\terr = read_poll_timeout(airoha_fe_rr, val,\ndrivers/net/ethernet/airoha/airoha_eth.c-422-\t\t\t\t\tval \u0026 MC_VLAN_CFG_CMD_DONE_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-428-\t\tfor (j = 0; j \u003c AIROHA_FE_MC_MAX_VLAN_PORT; j++) {\ndrivers/net/ethernet/airoha/airoha_eth.c:429:\t\t\tairoha_fe_wr(eth, REG_MC_VLAN_DATA, 0x0);\ndrivers/net/ethernet/airoha/airoha_eth.c-430-\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-433-\t\t\t MC_VLAN_CFG_RW_MASK;\ndrivers/net/ethernet/airoha/airoha_eth.c:434:\t\t\tairoha_fe_wr(eth, REG_MC_VLAN_CFG, val);\ndrivers/net/ethernet/airoha/airoha_eth.c:435:\t\t\terr = read_poll_timeout(airoha_fe_rr, val,\ndrivers/net/ethernet/airoha/airoha_eth.c-436-\t\t\t\t\t\tval \u0026 MC_VLAN_CFG_CMD_DONE_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-447-\ndrivers/net/ethernet/airoha/airoha_eth.c:448:static void airoha_fe_crsn_qsel_init(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_eth.c-449-{\ndrivers/net/ethernet/airoha/airoha_eth.c-450-\t/* CDM1_CRSN_QSEL */\ndrivers/net/ethernet/airoha/airoha_eth.c:451:\tairoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(1, CRSN_22 \u003e\u003e 2),\ndrivers/net/ethernet/airoha/airoha_eth.c-452-\t\t CDM_CRSN_QSEL_REASON_MASK(CRSN_22),\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-454-\t\t\t\t CDM_CRSN_QSEL_Q1));\ndrivers/net/ethernet/airoha/airoha_eth.c:455:\tairoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(1, CRSN_08 \u003e\u003e 2),\ndrivers/net/ethernet/airoha/airoha_eth.c-456-\t\t CDM_CRSN_QSEL_REASON_MASK(CRSN_08),\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-458-\t\t\t\t CDM_CRSN_QSEL_Q1));\ndrivers/net/ethernet/airoha/airoha_eth.c:459:\tairoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(1, CRSN_21 \u003e\u003e 2),\ndrivers/net/ethernet/airoha/airoha_eth.c-460-\t\t CDM_CRSN_QSEL_REASON_MASK(CRSN_21),\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-462-\t\t\t\t CDM_CRSN_QSEL_Q1));\ndrivers/net/ethernet/airoha/airoha_eth.c:463:\tairoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(1, CRSN_24 \u003e\u003e 2),\ndrivers/net/ethernet/airoha/airoha_eth.c-464-\t\t CDM_CRSN_QSEL_REASON_MASK(CRSN_24),\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-466-\t\t\t\t CDM_CRSN_QSEL_Q6));\ndrivers/net/ethernet/airoha/airoha_eth.c:467:\tairoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(1, CRSN_25 \u003e\u003e 2),\ndrivers/net/ethernet/airoha/airoha_eth.c-468-\t\t CDM_CRSN_QSEL_REASON_MASK(CRSN_25),\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-471-\t/* CDM2_CRSN_QSEL */\ndrivers/net/ethernet/airoha/airoha_eth.c:472:\tairoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(2, CRSN_08 \u003e\u003e 2),\ndrivers/net/ethernet/airoha/airoha_eth.c-473-\t\t CDM_CRSN_QSEL_REASON_MASK(CRSN_08),\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-475-\t\t\t\t CDM_CRSN_QSEL_Q1));\ndrivers/net/ethernet/airoha/airoha_eth.c:476:\tairoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(2, CRSN_21 \u003e\u003e 2),\ndrivers/net/ethernet/airoha/airoha_eth.c-477-\t\t CDM_CRSN_QSEL_REASON_MASK(CRSN_21),\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-479-\t\t\t\t CDM_CRSN_QSEL_Q1));\ndrivers/net/ethernet/airoha/airoha_eth.c:480:\tairoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(2, CRSN_22 \u003e\u003e 2),\ndrivers/net/ethernet/airoha/airoha_eth.c-481-\t\t CDM_CRSN_QSEL_REASON_MASK(CRSN_22),\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-483-\t\t\t\t CDM_CRSN_QSEL_Q1));\ndrivers/net/ethernet/airoha/airoha_eth.c:484:\tairoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(2, CRSN_24 \u003e\u003e 2),\ndrivers/net/ethernet/airoha/airoha_eth.c-485-\t\t CDM_CRSN_QSEL_REASON_MASK(CRSN_24),\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-487-\t\t\t\t CDM_CRSN_QSEL_Q6));\ndrivers/net/ethernet/airoha/airoha_eth.c:488:\tairoha_fe_rmw(eth, REG_CDM_CRSN_QSEL(2, CRSN_25 \u003e\u003e 2),\ndrivers/net/ethernet/airoha/airoha_eth.c-489-\t\t CDM_CRSN_QSEL_REASON_MASK(CRSN_25),\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-493-\ndrivers/net/ethernet/airoha/airoha_eth.c:494:static int airoha_fe_init(struct airoha_eth *eth)\ndrivers/net/ethernet/airoha/airoha_eth.c-495-{\ndrivers/net/ethernet/airoha/airoha_eth.c:496:\tairoha_fe_maccr_init(eth);\ndrivers/net/ethernet/airoha/airoha_eth.c-497-\ndrivers/net/ethernet/airoha/airoha_eth.c-498-\t/* PSE IQ reserve */\ndrivers/net/ethernet/airoha/airoha_eth.c:499:\tairoha_fe_rmw(eth, REG_PSE_IQ_REV1, PSE_IQ_RES1_P2_MASK,\ndrivers/net/ethernet/airoha/airoha_eth.c-500-\t\t FIELD_PREP(PSE_IQ_RES1_P2_MASK, 0x10));\ndrivers/net/ethernet/airoha/airoha_eth.c:501:\tairoha_fe_rmw(eth, REG_PSE_IQ_REV2,\ndrivers/net/ethernet/airoha/airoha_eth.c-502-\t\t PSE_IQ_RES2_P5_MASK | PSE_IQ_RES2_P4_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-506-\t/* enable FE copy engine for KA/DPI */\ndrivers/net/ethernet/airoha/airoha_eth.c:507:\tairoha_fe_wr(eth, REG_FE_PCE_CFG, PCE_DPI_EN_MASK | PCE_KA_EN_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c-508-\t/* set vip queue selection to ring 1 */\ndrivers/net/ethernet/airoha/airoha_eth.c:509:\tairoha_fe_rmw(eth, REG_CDM_FWD_CFG(1), CDM_VIP_QSEL_MASK,\ndrivers/net/ethernet/airoha/airoha_eth.c-510-\t\t FIELD_PREP(CDM_VIP_QSEL_MASK, 0x4));\ndrivers/net/ethernet/airoha/airoha_eth.c:511:\tairoha_fe_rmw(eth, REG_CDM_FWD_CFG(2), CDM_VIP_QSEL_MASK,\ndrivers/net/ethernet/airoha/airoha_eth.c-512-\t\t FIELD_PREP(CDM_VIP_QSEL_MASK, 0x4));\ndrivers/net/ethernet/airoha/airoha_eth.c-513-\t/* set GDM4 source interface offset to 8 */\ndrivers/net/ethernet/airoha/airoha_eth.c:514:\tairoha_fe_rmw(eth, REG_GDM_SRC_PORT_SET(4),\ndrivers/net/ethernet/airoha/airoha_eth.c-515-\t\t GDM_SPORT_OFF2_MASK |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-522-\t/* set PSE Page as 128B */\ndrivers/net/ethernet/airoha/airoha_eth.c:523:\tairoha_fe_rmw(eth, REG_FE_DMA_GLO_CFG,\ndrivers/net/ethernet/airoha/airoha_eth.c-524-\t\t FE_DMA_GLO_L2_SPACE_MASK | FE_DMA_GLO_PG_SZ_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-526-\t\t FE_DMA_GLO_PG_SZ_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c:527:\tairoha_fe_wr(eth, REG_FE_RST_GLO_CFG,\ndrivers/net/ethernet/airoha/airoha_eth.c-528-\t\t FE_RST_CORE_MASK | FE_RST_GDM3_MBI_ARB_MASK |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-534-\t */\ndrivers/net/ethernet/airoha/airoha_eth.c:535:\tairoha_fe_wr(eth, REG_FE_CDM1_OQ_MAP0, BIT(4));\ndrivers/net/ethernet/airoha/airoha_eth.c:536:\tairoha_fe_wr(eth, REG_FE_CDM1_OQ_MAP1, BIT(28));\ndrivers/net/ethernet/airoha/airoha_eth.c:537:\tairoha_fe_wr(eth, REG_FE_CDM1_OQ_MAP2, BIT(4));\ndrivers/net/ethernet/airoha/airoha_eth.c:538:\tairoha_fe_wr(eth, REG_FE_CDM1_OQ_MAP3, BIT(28));\ndrivers/net/ethernet/airoha/airoha_eth.c-539-\ndrivers/net/ethernet/airoha/airoha_eth.c:540:\tairoha_fe_vip_setup(eth);\ndrivers/net/ethernet/airoha/airoha_eth.c:541:\tairoha_fe_pse_ports_init(eth);\ndrivers/net/ethernet/airoha/airoha_eth.c-542-\ndrivers/net/ethernet/airoha/airoha_eth.c:543:\tairoha_fe_set(eth, REG_GDM_MISC_CFG,\ndrivers/net/ethernet/airoha/airoha_eth.c-544-\t\t GDM2_RDM_ACK_WAIT_PREF_MASK |\ndrivers/net/ethernet/airoha/airoha_eth.c-545-\t\t GDM2_CHN_VLD_MODE_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c:546:\tairoha_fe_rmw(eth, REG_CDM_FWD_CFG(2), CDM_OAM_QSEL_MASK,\ndrivers/net/ethernet/airoha/airoha_eth.c-547-\t\t FIELD_PREP(CDM_OAM_QSEL_MASK, 15));\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-550-\t/* NPU Core-3, NPU Bridge Channel-3 */\ndrivers/net/ethernet/airoha/airoha_eth.c:551:\tairoha_fe_rmw(eth, REG_IP_FRAG_FP,\ndrivers/net/ethernet/airoha/airoha_eth.c-552-\t\t IP_FRAGMENT_PORT_MASK | IP_FRAGMENT_NBQ_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-555-\t/* QDMA LAN, RX Ring-22 */\ndrivers/net/ethernet/airoha/airoha_eth.c:556:\tairoha_fe_rmw(eth, REG_IP_FRAG_FP,\ndrivers/net/ethernet/airoha/airoha_eth.c-557-\t\t IP_ASSEMBLE_PORT_MASK | IP_ASSEMBLE_NBQ_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-560-\ndrivers/net/ethernet/airoha/airoha_eth.c:561:\tairoha_fe_set(eth, REG_GDM_FWD_CFG(AIROHA_GDM3_IDX), GDM_PAD_EN_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c:562:\tairoha_fe_set(eth, REG_GDM_FWD_CFG(AIROHA_GDM4_IDX), GDM_PAD_EN_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c-563-\ndrivers/net/ethernet/airoha/airoha_eth.c-564-\t/* Enable split for MIB counters for GDM3 and GDM4 */\ndrivers/net/ethernet/airoha/airoha_eth.c:565:\tairoha_fe_set(eth, REG_FE_GDM_MIB_CFG(AIROHA_GDM3_IDX),\ndrivers/net/ethernet/airoha/airoha_eth.c-566-\t\t FE_GDM_TX_MIB_SPLIT_EN_MASK |\ndrivers/net/ethernet/airoha/airoha_eth.c-567-\t\t FE_GDM_RX_MIB_SPLIT_EN_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c:568:\tairoha_fe_set(eth, REG_FE_GDM_MIB_CFG(AIROHA_GDM4_IDX),\ndrivers/net/ethernet/airoha/airoha_eth.c-569-\t\t FE_GDM_TX_MIB_SPLIT_EN_MASK |\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-571-\ndrivers/net/ethernet/airoha/airoha_eth.c:572:\tairoha_fe_crsn_qsel_init(eth);\ndrivers/net/ethernet/airoha/airoha_eth.c-573-\ndrivers/net/ethernet/airoha/airoha_eth.c:574:\tairoha_fe_clear(eth, REG_FE_CPORT_CFG, FE_CPORT_QUEUE_XFC_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c:575:\tairoha_fe_set(eth, REG_FE_CPORT_CFG, FE_CPORT_PORT_XFC_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c-576-\ndrivers/net/ethernet/airoha/airoha_eth.c-577-\t/* default aging mode for mbi unlock issue */\ndrivers/net/ethernet/airoha/airoha_eth.c:578:\tairoha_fe_rmw(eth, REG_GDM_CHN_RLS(2),\ndrivers/net/ethernet/airoha/airoha_eth.c-579-\t\t MBI_RX_AGE_SEL_MASK | MBI_TX_AGE_SEL_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-583-\t/* disable IFC by default */\ndrivers/net/ethernet/airoha/airoha_eth.c:584:\tairoha_fe_clear(eth, REG_FE_CSR_IFC_CFG, FE_IFC_EN_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c-585-\ndrivers/net/ethernet/airoha/airoha_eth.c-586-\t/* enable 1:N vlan action, init vlan table */\ndrivers/net/ethernet/airoha/airoha_eth.c:587:\tairoha_fe_set(eth, REG_MC_VLAN_EN, MC_VLAN_EN_MASK);\ndrivers/net/ethernet/airoha/airoha_eth.c-588-\ndrivers/net/ethernet/airoha/airoha_eth.c:589:\treturn airoha_fe_mc_vlan_clear(eth);\ndrivers/net/ethernet/airoha/airoha_eth.c-590-}\ndrivers/net/ethernet/airoha/airoha_eth.c-591-\ndrivers/net/ethernet/airoha/airoha_eth.c:592:static int airoha_qdma_fill_rx_queue(struct airoha_queue *q)\ndrivers/net/ethernet/airoha/airoha_eth.c-593-{\ndrivers/net/ethernet/airoha/airoha_eth.c:594:\tstruct airoha_qdma *qdma = q-\u003eqdma;\ndrivers/net/ethernet/airoha/airoha_eth.c-595-\tint qid = q - \u0026qdma-\u003eq_rx[0];\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-598-\twhile (q-\u003equeued \u003c q-\u003endesc - 1) {\ndrivers/net/ethernet/airoha/airoha_eth.c:599:\t\tstruct airoha_queue_entry *e = \u0026q-\u003eentry[q-\u003ehead];\ndrivers/net/ethernet/airoha/airoha_eth.c:600:\t\tstruct airoha_qdma_desc *desc = \u0026q-\u003edesc[q-\u003ehead];\ndrivers/net/ethernet/airoha/airoha_eth.c-601-\t\tstruct page *page;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-630-\tif (nframes)\ndrivers/net/ethernet/airoha/airoha_eth.c:631:\t\tairoha_qdma_rmw(qdma, REG_RX_CPU_IDX(qid),\ndrivers/net/ethernet/airoha/airoha_eth.c-632-\t\t\t\tRX_RING_CPU_IDX_MASK,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-637-\ndrivers/net/ethernet/airoha/airoha_eth.c:638:static struct airoha_gdm_dev *\ndrivers/net/ethernet/airoha/airoha_eth.c:639:airoha_qdma_get_gdm_dev(struct airoha_eth *eth, struct airoha_qdma_desc *desc)\ndrivers/net/ethernet/airoha/airoha_eth.c-640-{\ndrivers/net/ethernet/airoha/airoha_eth.c:641:\tstruct airoha_gdm_port *port;\ndrivers/net/ethernet/airoha/airoha_eth.c-642-\tu16 p, d;\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-659-\ndrivers/net/ethernet/airoha/airoha_eth.c:660:static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)\ndrivers/net/ethernet/airoha/airoha_eth.c-661-{\ndrivers/net/ethernet/airoha/airoha_eth.c-662-\tenum dma_data_direction dir = page_pool_get_dma_dir(q-\u003epage_pool);\ndrivers/net/ethernet/airoha/airoha_eth.c:663:\tstruct airoha_qdma *qdma = q-\u003eqdma;\ndrivers/net/ethernet/airoha/airoha_eth.c:664:\tstruct airoha_eth *eth = qdma-\u003eeth;\ndrivers/net/ethernet/airoha/airoha_eth.c-665-\tint qid = q - \u0026qdma-\u003eq_rx[0];\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-668-\twhile (done \u003c budget) {\ndrivers/net/ethernet/airoha/airoha_eth.c:669:\t\tstruct airoha_queue_entry *e = \u0026q-\u003eentry[q-\u003etail];\ndrivers/net/ethernet/airoha/airoha_eth.c:670:\t\tstruct airoha_qdma_desc *desc = \u0026q-\u003edesc[q-\u003etail];\ndrivers/net/ethernet/airoha/airoha_eth.c-671-\t\tu32 hash, reason, msg1, desc_ctrl;\n\n"
} |
| 15/2 | 2026/07/21 07:04 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 81726 output: 110 thoughts: 940 Thoughts: **WorthFuzzing=false: Airoha Ethernet Driver** Okay, let's see. The prompt is asking if this patch is worth fuzzing. The key here is the Airoha Ethernet driver (`airoha_eth`). My initial thought is that since it's a platform driver, specifically for Airoha SoCs, it's very likely to be hardware-specific. I need to confirm this first; does syzbot even compile this driver, or is it just enabled, and does it require specific configuration? Alright, let's assume syzbot's `allyesconfig` setup compiles the module. The crux of the issue is whether it can be reached in virtualized environments like GCE or QEMU. Given that there's no software emulator for Airoha SoCs, this `airoha_eth` driver's probe is going to fail from the get-go. Code paths within `airoha_tc_setup_qdisc_htb`, `airoha_dev_xmit`, `airoha_dev_open`, etc., won't even be hit. The prompt explicitly says to return `WorthFuzzing=false` if these code paths are impossible to reach. Now, let's be thorough. Are there any other ways this code *could* be reached? Could it be instantiated via something like `netdevsim`, `dummy`, or `mac80211_hwsim`? No, those are all independent drivers. Could `syz_devlink` create a devlink instance? No, this uses standard platform driver probing. What about a device tree overlay? Syzkaller has some support for injecting device tree nodes. However, even if syzkaller could inject a device tree node, the driver will likely attempt to read/write MMIO registers. Since those registers are not backed by any actual hardware, the `read_poll_timeout` call will fail. That means the probe is going to abort early, and the functional code will remain unreachable. Wait a second, could syzkaller mock `read_poll_timeout`? No, Syzkaller doesn't do that. It can inject faults into `kmalloc`, but it doesn't mock arbitrary MMIO reads. What about the driver using `regmap` and syzkaller fuzzing the `regmap` interface? Let's check the code: no `regmap`! The driver uses `airoha_fe_rr` which is a direct `readl`. Syzkaller mapping a zeroed page means the driver will read 0, and the probe will fail. Okay, that confirms it. The code is unreachable in a virtualized environment. So, I will return `WorthFuzzing=false` with the reasoning that it's a hardware-specific platform driver without a software emulator. The driver will fail during the probe because of the MMIO registers. Let's double-check the final reasoning: "The patch modifies the Airoha ethernet driver (`airoha_eth`), which is a hardware-specific platform driver for Airoha SoCs. Since there is no software emulator for this hardware in the kernel or QEMU, the driver cannot successfully probe (it will fail on MMIO polling loops like `read_poll_timeout`), making the modified code paths unreachable in virtualized environments." Looks good. Now, just to be absolutely certain, let's confirm the files touched in the patch: `drivers/net/ethernet/airoha/airoha_eth.c`, `drivers/net/ethernet/airoha/airoha_eth.h`, `drivers/net/ethernet/airoha/airoha_ppe.c`, `drivers/net/ethernet/airoha/airoha_regs.h`. All those files belong to the `airoha_eth` driver, solidifying my conclusion. Time to use the `set-results` tool and move on. |
| 16/2 | 2026/07/21 07:05 | tool | set-results |
0mArgs:{
"EnableConfigs": [],
"FocusSymbols": [],
"Reasoning": "The patch modifies the Airoha ethernet driver (airoha_eth), which is a hardware-specific platform driver for Airoha SoCs. Since there is no software emulator for this hardware in the kernel or QEMU, the driver cannot successfully probe (it will fail on MMIO polling loops like read_poll_timeout), making the modified code paths unreachable in virtualized environments.",
"WorthFuzzing": false
}Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch modifies the Airoha ethernet driver (airoha_eth), which is a hardware-specific platform driver for Airoha SoCs. Since there is no software emulator for this hardware in the kernel or QEMU, the driver cannot successfully probe (it will fail on MMIO polling loops like read_poll_timeout), making the modified code paths unreachable in virtualized environments.",
"WorthFuzzing": false
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|