| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/08/11 12:00 | flow | patch-triage |
0mArgs:null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"KMSANReasoning": "",
"NeedsKMSAN": false,
"Reasoning": "The patch primarily adds 802.1Qav CBS offloading support to the Marvell mv88e6xxx DSA switch driver. This hardware driver cannot be exercised in standard virtualized environments like QEMU. The changes in net/dsa/tag_dsa.c are specific to the DSA tag protocol used exclusively by this driver. The modification in net/sched/sch_cbs.c is a trivial change to pass extack down to the driver and use NL_SET_ERR_MSG_WEAK, which does not introduce new functional logic requiring fuzzing.",
"WorthFuzzing": false
} |
| 1/1 | 2026/08/11 12:00 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 522b4f469b8ff53d1416fa4da979e3f415f85079\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Tue Aug 11 12:00:36 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c\nindex 80b877c74513d..a567ee9b6ce0d 100644\n--- a/drivers/net/dsa/mv88e6xxx/chip.c\n+++ b/drivers/net/dsa/mv88e6xxx/chip.c\n@@ -32,6 +32,7 @@\n #include \u003clinux/gpio/consumer.h\u003e\n #include \u003clinux/phylink.h\u003e\n #include \u003cnet/dsa.h\u003e\n+#include \u003cnet/pkt_sched.h\u003e\n \n #include \"chip.h\"\n #include \"devlink.h\"\n@@ -3990,6 +3991,7 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)\n \n \tchip-\u003eds = ds;\n \tds-\u003euser_mii_bus = mv88e6xxx_default_mdio_bus(chip);\n+\tds-\u003enum_tx_queues = chip-\u003einfo-\u003enum_tx_queues;\n \n \t/* Since virtual bridges are mapped in the PVT, the number we support\n \t * depends on the physical switch topology. We need to let DSA figure\n@@ -5023,6 +5025,7 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {\n \t.port_set_ether_type = mv88e6351_port_set_ether_type,\n \t.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,\n \t.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,\n+\t.port_set_scheduling_mode = mv88e6352_port_set_scheduling_mode,\n \t.port_pause_limit = mv88e6097_port_pause_limit,\n \t.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,\n \t.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,\n@@ -5306,6 +5309,7 @@ static const struct mv88e6xxx_ops mv88e6341_ops = {\n \t.port_set_ether_type = mv88e6351_port_set_ether_type,\n \t.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,\n \t.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,\n+\t.port_set_scheduling_mode = mv88e6352_port_set_scheduling_mode,\n \t.port_pause_limit = mv88e6097_port_pause_limit,\n \t.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,\n \t.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,\n@@ -5464,6 +5468,7 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {\n \t.port_set_ether_type = mv88e6351_port_set_ether_type,\n \t.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,\n \t.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,\n+\t.port_set_scheduling_mode = mv88e6352_port_set_scheduling_mode,\n \t.port_pause_limit = mv88e6097_port_pause_limit,\n \t.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,\n \t.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,\n@@ -5533,6 +5538,7 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {\n \t.port_get_cmode = mv88e6352_port_get_cmode,\n \t.port_set_cmode = mv88e6390_port_set_cmode,\n \t.port_setup_message_port = mv88e6xxx_setup_message_port,\n+\t.port_set_scheduling_mode = mv88e6390_port_set_scheduling_mode,\n \t.stats_snapshot = mv88e6390_g1_stats_snapshot,\n \t.stats_set_histogram = mv88e6390_g1_stats_set_histogram,\n \t.stats_get_sset_count = mv88e6320_stats_get_sset_count,\n@@ -5597,6 +5603,7 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {\n \t.port_get_cmode = mv88e6352_port_get_cmode,\n \t.port_set_cmode = mv88e6390x_port_set_cmode,\n \t.port_setup_message_port = mv88e6xxx_setup_message_port,\n+\t.port_set_scheduling_mode = mv88e6390_port_set_scheduling_mode,\n \t.stats_snapshot = mv88e6390_g1_stats_snapshot,\n \t.stats_set_histogram = mv88e6390_g1_stats_set_histogram,\n \t.stats_get_sset_count = mv88e6320_stats_get_sset_count,\n@@ -5653,6 +5660,7 @@ static const struct mv88e6xxx_ops mv88e6393x_ops = {\n \t.port_set_ether_type = mv88e6393x_port_set_ether_type,\n \t.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,\n \t.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,\n+\t.port_set_scheduling_mode = mv88e6390_port_set_scheduling_mode,\n \t.port_pause_limit = mv88e6390_port_pause_limit,\n \t.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,\n \t.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,\n@@ -5695,6 +5703,27 @@ static const struct mv88e6xxx_ops mv88e6393x_ops = {\n \t.tcam_ops = \u0026mv88e6393_tcam_ops,\n };\n \n+static const struct mv88e6xxx_qav_info mv88e6352_qav_info = {\n+\t.rate_unit = 32,\n+\t.rate_mask = GENMASK(14, 0),\n+\t.hilimit_mask = GENMASK(14, 0),\n+\t.queue_mask = GENMASK(3, 0),\n+};\n+\n+static const struct mv88e6xxx_qav_info mv88e6341_qav_info = {\n+\t.rate_unit = 64,\n+\t.rate_mask = GENMASK(15, 0),\n+\t.hilimit_mask = GENMASK(13, 0),\n+\t.queue_mask = GENMASK(3, 0),\n+};\n+\n+static const struct mv88e6xxx_qav_info mv88e6390_qav_info = {\n+\t.rate_unit = 64,\n+\t.rate_mask = GENMASK(15, 0),\n+\t.hilimit_mask = GENMASK(13, 0),\n+\t.queue_mask = GENMASK(7, 0),\n+};\n+\n static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t[MV88E6020] = {\n \t\t.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6020,\n@@ -5706,6 +5735,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t */\n \t\t.num_ports = 7,\n \t\t.num_internal_phys = 2,\n+\t\t.num_tx_queues = 4,\n \t\t.invalid_port_mask = BIT(2) | BIT(3) | BIT(4),\n \t\t.max_vid = 4095,\n \t\t.port_base_addr = 0x8,\n@@ -5728,6 +5758,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.num_databases = 64,\n \t\t.num_ports = 7,\n \t\t.num_internal_phys = 5,\n+\t\t.num_tx_queues = 4,\n \t\t.max_vid = 4095,\n \t\t.port_base_addr = 0x08,\n \t\t.phy_base_addr = 0x00,\n@@ -5750,6 +5781,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.num_macs = 8192,\n \t\t.num_ports = 10,\n \t\t.num_internal_phys = 5,\n+\t\t.num_tx_queues = 4,\n \t\t.max_vid = 4095,\n \t\t.max_sid = 63,\n \t\t.port_base_addr = 0x10,\n@@ -5774,6 +5806,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.num_macs = 8192,\n \t\t.num_ports = 11,\n \t\t.num_internal_phys = 0,\n+\t\t.num_tx_queues = 4,\n \t\t.max_vid = 4095,\n \t\t.port_base_addr = 0x10,\n \t\t.phy_base_addr = 0x0,\n@@ -5795,6 +5828,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.num_macs = 8192,\n \t\t.num_ports = 11,\n \t\t.num_internal_phys = 8,\n+\t\t.num_tx_queues = 4,\n \t\t.max_vid = 4095,\n \t\t.max_sid = 63,\n \t\t.port_base_addr = 0x10,\n@@ -5820,6 +5854,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.num_macs = 1024,\n \t\t.num_ports = 3,\n \t\t.num_internal_phys = 5,\n+\t\t.num_tx_queues = 4,\n \t\t.max_vid = 4095,\n \t\t.max_sid = 63,\n \t\t.port_base_addr = 0x10,\n@@ -5845,6 +5880,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.num_macs = 8192,\n \t\t.num_ports = 8,\n \t\t.num_internal_phys = 0,\n+\t\t.num_tx_queues = 4,\n \t\t.max_vid = 4095,\n \t\t.port_base_addr = 0x10,\n \t\t.phy_base_addr = 0x0,\n@@ -5867,6 +5903,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.num_ports = 6,\n \t\t.num_internal_phys = 5,\n \t\t.num_gpio = 11,\n+\t\t.num_tx_queues = 4,\n \t\t.max_vid = 4095,\n \t\t.max_sid = 63,\n \t\t.port_base_addr = 0x10,\n@@ -5892,6 +5929,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.num_macs = 1024,\n \t\t.num_ports = 6,\n \t\t.num_internal_phys = 5,\n+\t\t.num_tx_queues = 4,\n \t\t.max_vid = 4095,\n \t\t.max_sid = 63,\n \t\t.port_base_addr = 0x10,\n@@ -5918,6 +5956,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.num_macs = 8192,\n \t\t.num_ports = 6,\n \t\t.num_internal_phys = 0,\n+\t\t.num_tx_queues = 4,\n \t\t.max_vid = 4095,\n \t\t.max_sid = 63,\n \t\t.port_base_addr = 0x10,\n@@ -5943,6 +5982,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.num_macs = 8192,\n \t\t.num_ports = 7,\n \t\t.num_internal_phys = 5,\n+\t\t.num_tx_queues = 4,\n \t\t.max_vid = 4095,\n \t\t.max_sid = 63,\n \t\t.port_base_addr = 0x10,\n@@ -5969,6 +6009,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.num_ports = 7,\n \t\t.num_internal_phys = 5,\n \t\t.num_gpio = 15,\n+\t\t.num_tx_queues = 4,\n \t\t.max_vid = 4095,\n \t\t.max_sid = 63,\n \t\t.port_base_addr = 0x10,\n@@ -5994,6 +6035,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.num_macs = 8192,\n \t\t.num_ports = 7,\n \t\t.num_internal_phys = 5,\n+\t\t.num_tx_queues = 4,\n \t\t.max_vid = 4095,\n \t\t.max_sid = 63,\n \t\t.port_base_addr = 0x10,\n@@ -6020,6 +6062,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.num_ports = 7,\n \t\t.num_internal_phys = 5,\n \t\t.num_gpio = 15,\n+\t\t.num_tx_queues = 4,\n \t\t.max_vid = 4095,\n \t\t.max_sid = 63,\n \t\t.port_base_addr = 0x10,\n@@ -6045,6 +6088,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.num_macs = 8192,\n \t\t.num_ports = 10,\n \t\t.num_internal_phys = 0,\n+\t\t.num_tx_queues = 4,\n \t\t.max_vid = 4095,\n \t\t.port_base_addr = 0x10,\n \t\t.phy_base_addr = 0x0,\n@@ -6068,6 +6112,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.num_ports = 11,\t/* 10 + Z80 */\n \t\t.num_internal_phys = 9,\n \t\t.num_gpio = 16,\n+\t\t.num_tx_queues = 8,\n \t\t.max_vid = 8191,\n \t\t.max_sid = 63,\n \t\t.port_base_addr = 0x0,\n@@ -6093,6 +6138,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.num_ports = 11,\t/* 10 + Z80 */\n \t\t.num_internal_phys = 9,\n \t\t.num_gpio = 16,\n+\t\t.num_tx_queues = 8,\n \t\t.max_vid = 8191,\n \t\t.max_sid = 63,\n \t\t.port_base_addr = 0x0,\n@@ -6117,6 +6163,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.num_macs = 16384,\n \t\t.num_ports = 11,\t/* 10 + Z80 */\n \t\t.num_internal_phys = 9,\n+\t\t.num_tx_queues = 8,\n \t\t.max_vid = 8191,\n \t\t.max_sid = 63,\n \t\t.port_base_addr = 0x0,\n@@ -6142,6 +6189,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.num_ports = 11,\t/* 10 + Z80 */\n \t\t.num_internal_phys = 8,\n \t\t.internal_phys_offset = 1,\n+\t\t.num_tx_queues = 8,\n \t\t.max_vid = 8191,\n \t\t.max_sid = 63,\n \t\t.port_base_addr = 0x0,\n@@ -6168,6 +6216,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.num_internal_phys = 8,\n \t\t.num_tcam_entries = 256,\n \t\t.internal_phys_offset = 1,\n+\t\t.num_tx_queues = 8,\n \t\t.max_vid = 8191,\n \t\t.max_sid = 63,\n \t\t.port_base_addr = 0x0,\n@@ -6198,6 +6247,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.num_ports = 7,\n \t\t.num_internal_phys = 2,\n \t\t.invalid_port_mask = BIT(2) | BIT(3) | BIT(4),\n+\t\t.num_tx_queues = 4,\n \t\t.max_vid = 4095,\n \t\t.port_base_addr = 0x08,\n \t\t.phy_base_addr = 0x00,\n@@ -6222,6 +6272,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.num_ports = 7,\n \t\t.num_internal_phys = 5,\n \t\t.num_gpio = 15,\n+\t\t.num_tx_queues = 4,\n \t\t.max_vid = 4095,\n \t\t.max_sid = 63,\n \t\t.port_base_addr = 0x10,\n@@ -6237,6 +6288,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.multi_chip = true,\n \t\t.edsa_support = MV88E6XXX_EDSA_SUPPORTED,\n \t\t.ptp_support = true,\n+\t\t.qav = \u0026mv88e6352_qav_info,\n \t\t.ops = \u0026mv88e6240_ops,\n \t},\n \n@@ -6247,6 +6299,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.num_databases = 64,\n \t\t.num_ports = 7,\n \t\t.num_internal_phys = 5,\n+\t\t.num_tx_queues = 4,\n \t\t.max_vid = 4095,\n \t\t.port_base_addr = 0x08,\n \t\t.phy_base_addr = 0x00,\n@@ -6271,6 +6324,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.num_internal_phys = 9,\n \t\t.num_gpio = 16,\n \t\t.num_tcam_entries = 256,\n+\t\t.num_tx_queues = 8,\n \t\t.max_vid = 8191,\n \t\t.max_sid = 63,\n \t\t.port_base_addr = 0x0,\n@@ -6299,6 +6353,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.num_internal_phys = 2,\n \t\t.internal_phys_offset = 3,\n \t\t.num_gpio = 15,\n+\t\t.num_tx_queues = 4,\n \t\t.max_vid = 4095,\n \t\t.max_sid = 63,\n \t\t.port_base_addr = 0x10,\n@@ -6327,6 +6382,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.num_internal_phys = 2,\n \t\t.internal_phys_offset = 3,\n \t\t.num_gpio = 15,\n+\t\t.num_tx_queues = 4,\n \t\t.max_vid = 4095,\n \t\t.max_sid = 63,\n \t\t.port_base_addr = 0x10,\n@@ -6354,6 +6410,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.num_internal_phys = 5,\n \t\t.num_ports = 6,\n \t\t.num_gpio = 11,\n+\t\t.num_tx_queues = 4,\n \t\t.max_vid = 4095,\n \t\t.max_sid = 63,\n \t\t.port_base_addr = 0x10,\n@@ -6369,6 +6426,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.multi_chip = true,\n \t\t.edsa_support = MV88E6XXX_EDSA_SUPPORTED,\n \t\t.ptp_support = true,\n+\t\t.qav = \u0026mv88e6341_qav_info,\n \t\t.ops = \u0026mv88e6341_ops,\n \t},\n \n@@ -6380,6 +6438,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.num_macs = 8192,\n \t\t.num_ports = 7,\n \t\t.num_internal_phys = 5,\n+\t\t.num_tx_queues = 4,\n \t\t.max_vid = 4095,\n \t\t.max_sid = 63,\n \t\t.port_base_addr = 0x10,\n@@ -6405,6 +6464,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.num_macs = 8192,\n \t\t.num_ports = 7,\n \t\t.num_internal_phys = 5,\n+\t\t.num_tx_queues = 4,\n \t\t.max_vid = 4095,\n \t\t.max_sid = 63,\n \t\t.port_base_addr = 0x10,\n@@ -6431,6 +6491,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.num_ports = 7,\n \t\t.num_internal_phys = 5,\n \t\t.num_gpio = 15,\n+\t\t.num_tx_queues = 4,\n \t\t.max_vid = 4095,\n \t\t.max_sid = 63,\n \t\t.port_base_addr = 0x10,\n@@ -6446,6 +6507,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.multi_chip = true,\n \t\t.edsa_support = MV88E6XXX_EDSA_SUPPORTED,\n \t\t.ptp_support = true,\n+\t\t.qav = \u0026mv88e6352_qav_info,\n \t\t.ops = \u0026mv88e6352_ops,\n \t},\n \t[MV88E6361] = {\n@@ -6459,6 +6521,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.invalid_port_mask = BIT(1) | BIT(2) | BIT(8),\n \t\t.num_internal_phys = 5,\n \t\t.internal_phys_offset = 3,\n+\t\t.num_tx_queues = 8,\n \t\t.max_vid = 8191,\n \t\t.max_sid = 63,\n \t\t.port_base_addr = 0x0,\n@@ -6485,6 +6548,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.num_internal_phys = 9,\n \t\t.num_gpio = 16,\n \t\t.num_tcam_entries = 256,\n+\t\t.num_tx_queues = 8,\n \t\t.max_vid = 8191,\n \t\t.max_sid = 63,\n \t\t.port_base_addr = 0x0,\n@@ -6501,6 +6565,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.multi_chip = true,\n \t\t.edsa_support = MV88E6XXX_EDSA_UNDOCUMENTED,\n \t\t.ptp_support = true,\n+\t\t.qav = \u0026mv88e6390_qav_info,\n \t\t.ops = \u0026mv88e6390_ops,\n \t},\n \t[MV88E6390X] = {\n@@ -6512,6 +6577,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.num_ports = 11,\t/* 10 + Z80 */\n \t\t.num_internal_phys = 9,\n \t\t.num_gpio = 16,\n+\t\t.num_tx_queues = 8,\n \t\t.max_vid = 8191,\n \t\t.max_sid = 63,\n \t\t.port_base_addr = 0x0,\n@@ -6527,6 +6593,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.multi_chip = true,\n \t\t.edsa_support = MV88E6XXX_EDSA_UNDOCUMENTED,\n \t\t.ptp_support = true,\n+\t\t.qav = \u0026mv88e6390_qav_info,\n \t\t.ops = \u0026mv88e6390x_ops,\n \t},\n \n@@ -6538,6 +6605,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.num_ports = 11,\t/* 10 + Z80 */\n \t\t.num_internal_phys = 8,\n \t\t.num_tcam_entries = 256,\n+\t\t.num_tx_queues = 8,\n \t\t.internal_phys_offset = 1,\n \t\t.max_vid = 8191,\n \t\t.max_sid = 63,\n@@ -6554,6 +6622,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {\n \t\t.pvt = true,\n \t\t.multi_chip = true,\n \t\t.ptp_support = true,\n+\t\t.qav = \u0026mv88e6390_qav_info,\n \t\t.ops = \u0026mv88e6393x_ops,\n \t},\n };\n@@ -7175,6 +7244,112 @@ static int mv88e6xxx_crosschip_lag_leave(struct dsa_switch *ds, int sw_index,\n \treturn err_sync ? : err_pvt;\n }\n \n+static int mv88e6xxx_setup_tc_cbs(struct dsa_switch *ds, int port,\n+\t\t\t\t struct tc_cbs_qopt_offload *cbs)\n+{\n+\tconst struct mv88e6xxx_avb_ops *avb_ops;\n+\tstruct mv88e6xxx_chip *chip = ds-\u003epriv;\n+\tconst struct mv88e6xxx_qav_info *qav;\n+\tconst struct mv88e6xxx_ops *ops;\n+\tint hilimit_reg;\n+\tint rate_reg;\n+\tu8 queue_bit;\n+\tu32 rate = 0;\n+\tu16 hilimit;\n+\tint err;\n+\n+\tops = chip-\u003einfo-\u003eops;\n+\tavb_ops = ops-\u003eavb_ops;\n+\tqav = chip-\u003einfo-\u003eqav;\n+\n+\tif (!qav || !avb_ops || !avb_ops-\u003eport_qav_write ||\n+\t !ops-\u003eport_set_scheduling_mode)\n+\t\treturn -EOPNOTSUPP;\n+\n+\tif (!dsa_is_user_port(ds, port))\n+\t\treturn -EOPNOTSUPP;\n+\n+\tif (!(qav-\u003equeue_mask \u0026 BIT(cbs-\u003equeue))) {\n+\t\tNL_SET_ERR_MSG_MOD(cbs-\u003eextack, \"CBS not supported on queue\");\n+\t\treturn -EOPNOTSUPP;\n+\t}\n+\n+\tqueue_bit = BIT(cbs-\u003equeue);\n+\trate_reg = MV88E6XXX_PORT_QAV_CFG_RATE(cbs-\u003equeue);\n+\thilimit_reg = MV88E6XXX_PORT_QAV_CFG_HILIMIT(cbs-\u003equeue);\n+\n+\tif (cbs-\u003eenable) {\n+\t\tif (cbs-\u003ehicredit \u003c= 0 ||\n+\t\t cbs-\u003ehicredit \u003e qav-\u003ehilimit_mask) {\n+\t\t\tNL_SET_ERR_MSG_MOD(cbs-\u003eextack,\n+\t\t\t\t\t \"hicredit out of range\");\n+\t\t\treturn -ERANGE;\n+\t\t}\n+\n+\t\trate = DIV_ROUND_UP(cbs-\u003eidleslope, qav-\u003erate_unit);\n+\t\tif (rate \u003e qav-\u003erate_mask) {\n+\t\t\tNL_SET_ERR_MSG_MOD(cbs-\u003eextack,\n+\t\t\t\t\t \"idleslope out of range\");\n+\t\t\treturn -ERANGE;\n+\t\t}\n+\t\t/* avoid using zero rate */\n+\t\trate = max_t(u16, rate, 1);\n+\t}\n+\n+\tmv88e6xxx_reg_lock(chip);\n+\n+\tif (!cbs-\u003eenable) {\n+\t\terr = mv88e6xxx_port_qav_write(chip, port, rate_reg, 0);\n+\t\tif (err)\n+\t\t\tgoto unlock;\n+\n+\t\tif (!(chip-\u003eports[port].cbs_active_queues \u0026 ~queue_bit)) {\n+\t\t\terr = mv88e6xxx_port_set_scheduling_mode(chip, port, 0);\n+\t\t\tif (err)\n+\t\t\t\tgoto unlock;\n+\t\t}\n+\t\tchip-\u003eports[port].cbs_active_queues \u0026= ~queue_bit;\n+\t\tgoto unlock;\n+\t}\n+\n+\thilimit = cbs-\u003ehicredit \u0026 qav-\u003ehilimit_mask;\n+\terr = mv88e6xxx_port_qav_write(chip, port, hilimit_reg, hilimit);\n+\tif (err)\n+\t\tgoto unlock;\n+\n+\terr = mv88e6xxx_port_qav_write(chip, port, rate_reg, rate);\n+\tif (err)\n+\t\tgoto unlock;\n+\n+\tif (!chip-\u003eports[port].cbs_active_queues) {\n+\t\tu8 sched_mode = chip-\u003einfo-\u003enum_tx_queues - 1;\n+\n+\t\terr = mv88e6xxx_port_set_scheduling_mode(chip, port,\n+\t\t\t\t\t\t\t sched_mode);\n+\t\tif (err) {\n+\t\t\tmv88e6xxx_port_qav_write(chip, port, rate_reg, 0);\n+\t\t\tgoto unlock;\n+\t\t}\n+\t}\n+\tchip-\u003eports[port].cbs_active_queues |= queue_bit;\n+\n+unlock:\n+\tmv88e6xxx_reg_unlock(chip);\n+\n+\treturn err;\n+}\n+\n+static int mv88e6xxx_port_setup_tc(struct dsa_switch *ds, int port,\n+\t\t\t\t enum tc_setup_type type, void *type_data)\n+{\n+\tswitch (type) {\n+\tcase TC_SETUP_QDISC_CBS:\n+\t\treturn mv88e6xxx_setup_tc_cbs(ds, port, type_data);\n+\tdefault:\n+\t\treturn -EOPNOTSUPP;\n+\t}\n+}\n+\n static const struct phylink_mac_ops mv88e6xxx_phylink_mac_ops = {\n \t.mac_select_pcs\t\t= mv88e6xxx_mac_select_pcs,\n \t.mac_prepare\t\t= mv88e6xxx_mac_prepare,\n@@ -7234,6 +7409,7 @@ static const struct dsa_switch_ops mv88e6xxx_switch_ops = {\n \t.port_hwtstamp_get\t= mv88e6xxx_port_hwtstamp_get,\n \t.port_txtstamp\t\t= mv88e6xxx_port_txtstamp,\n \t.port_rxtstamp\t\t= mv88e6xxx_port_rxtstamp,\n+\t.port_setup_tc\t\t= mv88e6xxx_port_setup_tc,\n \t.cls_flower_add\t\t= mv88e6xxx_cls_flower_add,\n \t.cls_flower_del = mv88e6xxx_cls_flower_del,\n \t.get_ts_info\t\t= mv88e6xxx_get_ts_info,\ndiff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h\nindex e966e7c4cc5de..d42d839e636bc 100644\n--- a/drivers/net/dsa/mv88e6xxx/chip.h\n+++ b/drivers/net/dsa/mv88e6xxx/chip.h\n@@ -125,6 +125,7 @@ enum mv88e6xxx_edsa_support {\n };\n \n struct mv88e6xxx_ops;\n+struct mv88e6xxx_qav_info;\n \n struct mv88e6xxx_info {\n \tenum mv88e6xxx_family family;\n@@ -136,6 +137,7 @@ struct mv88e6xxx_info {\n \tunsigned int num_internal_phys;\n \tunsigned int num_gpio;\n \tunsigned int num_tcam_entries;\n+\tunsigned int num_tx_queues;\n \tunsigned int max_vid;\n \tunsigned int max_sid;\n \tunsigned int port_base_addr;\n@@ -176,6 +178,9 @@ struct mv88e6xxx_info {\n \t/* Supports PTP */\n \tbool ptp_support;\n \n+\t/* 802.1Qav credit based shaping */\n+\tconst struct mv88e6xxx_qav_info *qav;\n+\n \t/* Internal PHY start index. 0 means that internal PHYs range starts at\n \t * port 0, 1 means internal PHYs range starts at port 1, etc\n \t */\n@@ -304,6 +309,9 @@ struct mv88e6xxx_port {\n \n \t/* MacAuth Bypass control flag */\n \tbool mab;\n+\n+\t/* Queues with CBS currently enabled. */\n+\tu8 cbs_active_queues;\n };\n \n enum mv88e6xxx_region_id {\n@@ -606,6 +614,8 @@ struct mv88e6xxx_ops {\n \t\t\t\t size_t size);\n \n \tint (*port_egress_rate_limiting)(struct mv88e6xxx_chip *chip, int port);\n+\tint (*port_set_scheduling_mode)(struct mv88e6xxx_chip *chip, int port,\n+\t\t\t\t\tu8 mode);\n \tint (*port_pause_limit)(struct mv88e6xxx_chip *chip, int port, u8 in,\n \t\t\t\tu8 out);\n \tint (*port_disable_learn_limit)(struct mv88e6xxx_chip *chip, int port);\n@@ -763,6 +773,10 @@ struct mv88e6xxx_avb_ops {\n \tint (*tai_read)(struct mv88e6xxx_chip *chip, int addr, u16 *data,\n \t\t\tint len);\n \tint (*tai_write)(struct mv88e6xxx_chip *chip, int addr, u16 data);\n+\n+\t/* Access port-scoped 802.1Qav registers */\n+\tint (*port_qav_write)(struct mv88e6xxx_chip *chip, int port, int addr,\n+\t\t\t u16 data);\n };\n \n struct mv88e6xxx_ptp_ops {\n@@ -798,6 +812,13 @@ struct mv88e6xxx_tcam_ops {\n \tint (*flush_tcam)(struct mv88e6xxx_chip *chip);\n };\n \n+struct mv88e6xxx_qav_info {\n+\tu16 rate_unit; /* in kbps */\n+\tu16 rate_mask; /* QPri Rate valid bits mask */\n+\tu16 hilimit_mask; /* QPri HiLimit bits mask*/\n+\tu8 queue_mask; /* supported queues bitmask */\n+};\n+\n static inline bool mv88e6xxx_has_stu(struct mv88e6xxx_chip *chip)\n {\n \treturn chip-\u003einfo-\u003emax_sid \u003e 0 \u0026\u0026\ndiff --git a/drivers/net/dsa/mv88e6xxx/global2.h b/drivers/net/dsa/mv88e6xxx/global2.h\nindex ff5adf7c9bc3a..df52ff3adc88c 100644\n--- a/drivers/net/dsa/mv88e6xxx/global2.h\n+++ b/drivers/net/dsa/mv88e6xxx/global2.h\n@@ -186,6 +186,9 @@\n #define MV88E6352_G2_AVB_CMD_BLOCK_MASK\t\t0x00e0\n #define MV88E6352_G2_AVB_CMD_ADDR_MASK\t\t0x001f\n \n+#define MV88E6XXX_PORT_QAV_CFG_RATE(queue)\t(((queue) \u0026 0x7) \u003c\u003c 1)\n+#define MV88E6XXX_PORT_QAV_CFG_HILIMIT(queue)\t((((queue) \u0026 0x7) \u003c\u003c 1) + 1)\n+\n /* Offset 0x17: AVB Data Register */\n #define MV88E6352_G2_AVB_DATA\t\t0x17\n \ndiff --git a/drivers/net/dsa/mv88e6xxx/global2_avb.c b/drivers/net/dsa/mv88e6xxx/global2_avb.c\nindex 657783e043ff1..6b54e275d21ab 100644\n--- a/drivers/net/dsa/mv88e6xxx/global2_avb.c\n+++ b/drivers/net/dsa/mv88e6xxx/global2_avb.c\n@@ -110,6 +110,15 @@ static int mv88e6352_g2_avb_port_ptp_write(struct mv88e6xxx_chip *chip,\n \treturn mv88e6xxx_g2_avb_write(chip, writeop, data);\n }\n \n+static int mv88e6352_g2_avb_port_qav_write(struct mv88e6xxx_chip *chip,\n+\t\t\t\t\t int port, int addr, u16 data)\n+{\n+\tu16 writeop = MV88E6352_G2_AVB_CMD_OP_WRITE | (port \u003c\u003c 8) |\n+\t\t (MV88E6352_G2_AVB_CMD_BLOCK_QAV \u003c\u003c 5) | addr;\n+\n+\treturn mv88e6xxx_g2_avb_write(chip, writeop, data);\n+}\n+\n static int mv88e6352_g2_avb_ptp_read(struct mv88e6xxx_chip *chip, int addr,\n \t\t\t\t u16 *data, int len)\n {\n@@ -149,6 +158,7 @@ const struct mv88e6xxx_avb_ops mv88e6352_avb_ops = {\n \t.ptp_write\t\t= mv88e6352_g2_avb_ptp_write,\n \t.tai_read\t\t= mv88e6352_g2_avb_tai_read,\n \t.tai_write\t\t= mv88e6352_g2_avb_tai_write,\n+\t.port_qav_write\t\t= mv88e6352_g2_avb_port_qav_write,\n };\n \n static int mv88e6165_g2_avb_tai_read(struct mv88e6xxx_chip *chip, int addr,\n@@ -174,6 +184,7 @@ const struct mv88e6xxx_avb_ops mv88e6165_avb_ops = {\n \t.ptp_write\t\t= mv88e6352_g2_avb_ptp_write,\n \t.tai_read\t\t= mv88e6165_g2_avb_tai_read,\n \t.tai_write\t\t= mv88e6165_g2_avb_tai_write,\n+\t.port_qav_write\t\t= mv88e6352_g2_avb_port_qav_write,\n };\n \n static int mv88e6390_g2_avb_port_ptp_read(struct mv88e6xxx_chip *chip,\n@@ -197,6 +208,15 @@ static int mv88e6390_g2_avb_port_ptp_write(struct mv88e6xxx_chip *chip,\n \treturn mv88e6xxx_g2_avb_write(chip, writeop, data);\n }\n \n+static int mv88e6390_g2_avb_port_qav_write(struct mv88e6xxx_chip *chip,\n+\t\t\t\t\t int port, int addr, u16 data)\n+{\n+\tu16 writeop = MV88E6390_G2_AVB_CMD_OP_WRITE | (port \u003c\u003c 8) |\n+\t\t (MV88E6352_G2_AVB_CMD_BLOCK_QAV \u003c\u003c 5) | addr;\n+\n+\treturn mv88e6xxx_g2_avb_write(chip, writeop, data);\n+}\n+\n static int mv88e6390_g2_avb_ptp_read(struct mv88e6xxx_chip *chip, int addr,\n \t\t\t\t u16 *data, int len)\n {\n@@ -236,4 +256,5 @@ const struct mv88e6xxx_avb_ops mv88e6390_avb_ops = {\n \t.ptp_write\t\t= mv88e6390_g2_avb_ptp_write,\n \t.tai_read\t\t= mv88e6390_g2_avb_tai_read,\n \t.tai_write\t\t= mv88e6390_g2_avb_tai_write,\n+\t.port_qav_write\t\t= mv88e6390_g2_avb_port_qav_write,\n };\ndiff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c\nindex ea1fab71968a0..758b8d41f4853 100644\n--- a/drivers/net/dsa/mv88e6xxx/port.c\n+++ b/drivers/net/dsa/mv88e6xxx/port.c\n@@ -1323,6 +1323,51 @@ int mv88e6097_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port)\n \t\t\t\t 0x0001);\n }\n \n+int mv88e6352_port_set_scheduling_mode(struct mv88e6xxx_chip *chip, int port,\n+\t\t\t\t u8 mode)\n+{\n+\tu16 reg;\n+\tint err;\n+\n+\tif (mode \u003e 3)\n+\t\treturn -EINVAL;\n+\n+\terr = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL2,\n+\t\t\t\t \u0026reg);\n+\tif (err)\n+\t\treturn err;\n+\n+\treg \u0026= ~MV88E6XXX_PORT_EGRESS_RATE_CTL2_SCHEDULE_MASK;\n+\treg |= mode \u003c\u003c MV88E6XXX_PORT_EGRESS_RATE_CTL2_SCHEDULE_SHIFT;\n+\n+\treturn mv88e6xxx_port_write(chip, port,\n+\t\t\t\t MV88E6XXX_PORT_EGRESS_RATE_CTL2, reg);\n+}\n+\n+int mv88e6390_port_set_scheduling_mode(struct mv88e6xxx_chip *chip, int port,\n+\t\t\t\t u8 mode)\n+{\n+\tu16 reg;\n+\tint err;\n+\n+\tif (mode \u003e MV88E6390_PORT_QUEUE_CTL_SCHEDULE_MASK)\n+\t\treturn -EINVAL;\n+\n+\treg = MV88E6390_PORT_QUEUE_CTL_UPDATE |\n+\t (MV88E6390_PORT_QUEUE_CTL_SCHEDULE \u003c\u003c\n+\t MV88E6390_PORT_QUEUE_CTL_PTR_SHIFT) |\n+\t (mode \u0026 MV88E6390_PORT_QUEUE_CTL_SCHEDULE_MASK);\n+\n+\terr = mv88e6xxx_port_write(chip, port, MV88E6390_PORT_QUEUE_CTL,\n+\t\t\t\t reg);\n+\tif (err)\n+\t\treturn err;\n+\n+\treturn mv88e6xxx_port_wait_bit(chip, port, MV88E6390_PORT_QUEUE_CTL,\n+\t\t\t\t __bf_shf(MV88E6390_PORT_QUEUE_CTL_UPDATE)\n+\t\t\t\t , 0);\n+}\n+\n /* Offset 0x0B: Port Association Vector */\n \n int mv88e6xxx_port_set_assoc_vector(struct mv88e6xxx_chip *chip, int port,\n@@ -1727,3 +1772,21 @@ int mv88e6393x_port_set_policy(struct mv88e6xxx_chip *chip, int port,\n \n \treturn mv88e6393x_port_policy_write(chip, port, ptr, reg);\n }\n+\n+int mv88e6xxx_port_qav_write(struct mv88e6xxx_chip *chip, int port, int addr,\n+\t\t\t u16 data)\n+{\n+\tif (!chip-\u003einfo-\u003eops-\u003eavb_ops-\u003eport_qav_write)\n+\t\treturn -EOPNOTSUPP;\n+\n+\treturn chip-\u003einfo-\u003eops-\u003eavb_ops-\u003eport_qav_write(chip, port, addr, data);\n+}\n+\n+int mv88e6xxx_port_set_scheduling_mode(struct mv88e6xxx_chip *chip, int port,\n+\t\t\t\t u8 mode)\n+{\n+\tif (!chip-\u003einfo-\u003eops-\u003eport_set_scheduling_mode)\n+\t\treturn -EOPNOTSUPP;\n+\n+\treturn chip-\u003einfo-\u003eops-\u003eport_set_scheduling_mode(chip, port, mode);\n+}\ndiff --git a/drivers/net/dsa/mv88e6xxx/port.h b/drivers/net/dsa/mv88e6xxx/port.h\nindex 5b6cde9f7406f..a380f356eb83d 100644\n--- a/drivers/net/dsa/mv88e6xxx/port.h\n+++ b/drivers/net/dsa/mv88e6xxx/port.h\n@@ -241,6 +241,18 @@\n \n /* Offset 0x0A: Egress Rate Control 2 */\n #define MV88E6XXX_PORT_EGRESS_RATE_CTL2\t\t0x0a\n+#define MV88E6XXX_PORT_EGRESS_RATE_CTL2_SCHEDULE_MASK\t0x3000\n+#define MV88E6XXX_PORT_EGRESS_RATE_CTL2_SCHEDULE_SHIFT\t12\n+\n+/* Offset 0x1C: Port Queue Control */\n+#define MV88E6390_PORT_QUEUE_CTL\t\t\t0x1c\n+#define MV88E6390_PORT_QUEUE_CTL_UPDATE\t\t\t0x8000\n+#define MV88E6390_PORT_QUEUE_CTL_PTR_MASK\t\t0x7f00\n+#define MV88E6390_PORT_QUEUE_CTL_PTR_SHIFT\t\t8\n+#define MV88E6390_PORT_QUEUE_CTL_DATA_MASK\t\t0x00ff\n+#define MV88E6390_PORT_QUEUE_CTL_SCHEDULE\t\t0x00\n+#define MV88E6390_PORT_QUEUE_CTL_SCHEDULE_MASK\t\t0x07\n+\n \n /* Offset 0x0B: Port Association Vector */\n #define MV88E6XXX_PORT_ASSOC_VECTOR\t\t\t0x0b\n@@ -561,6 +573,10 @@ int mv88e6165_port_set_jumbo_size(struct mv88e6xxx_chip *chip, int port,\n \t\t\t\t size_t size);\n int mv88e6095_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port);\n int mv88e6097_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port);\n+int mv88e6352_port_set_scheduling_mode(struct mv88e6xxx_chip *chip, int port,\n+\t\t\t\t u8 mode);\n+int mv88e6390_port_set_scheduling_mode(struct mv88e6xxx_chip *chip, int port,\n+\t\t\t\t u8 mode);\n int mv88e6xxx_port_set_assoc_vector(struct mv88e6xxx_chip *chip, int port,\n \t\t\t\t u16 pav);\n int mv88e6097_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in,\n@@ -605,5 +621,9 @@ int mv88e6xxx_port_hidden_read(struct mv88e6xxx_chip *chip, int block, int port,\n \t\t\t int reg, u16 *val);\n \n int mv88e6xxx_port_enable_tcam(struct mv88e6xxx_chip *chip, int port);\n+int mv88e6xxx_port_qav_write(struct mv88e6xxx_chip *chip, int port, int addr,\n+\t\t\t u16 data);\n+int mv88e6xxx_port_set_scheduling_mode(struct mv88e6xxx_chip *chip, int port,\n+\t\t\t\t u8 mode);\n \n #endif /* _MV88E6XXX_PORT_H */\ndiff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h\nindex 18a419cd9d949..d35c87004c279 100644\n--- a/include/net/pkt_sched.h\n+++ b/include/net/pkt_sched.h\n@@ -150,6 +150,7 @@ struct tc_cbs_qopt_offload {\n \ts32 locredit;\n \ts32 idleslope;\n \ts32 sendslope;\n+\tstruct netlink_ext_ack *extack;\n };\n \n struct tc_etf_qopt_offload {\ndiff --git a/net/dsa/tag_dsa.c b/net/dsa/tag_dsa.c\nindex d5ffee35fbb53..2bb71cd343e79 100644\n--- a/net/dsa/tag_dsa.c\n+++ b/net/dsa/tag_dsa.c\n@@ -179,8 +179,17 @@ static struct sk_buff *dsa_xmit_ll(struct sk_buff *skb, struct net_device *dev,\n \t\t\tdsa_header[2] \u0026= ~0x10;\n \t\t}\n \t} else {\n+\t\tu16 queue = skb_get_queue_mapping(skb) \u0026 0x7;\n \t\tu16 vid;\n \n+\t\t/* The PRI field is 3 bits. According to the documentation the\n+\t\t * 2 highest bits specify the egress queue in From_CPU DSA\n+\t\t * tagged frames. On devices with 8 queues it's possible to\n+\t\t * send to the 8 queues, which means the 3 bits are used.\n+\t\t */\n+\t\tif (dp-\u003eds-\u003enum_tx_queues == 4)\n+\t\t\tqueue \u003c\u003c= 1;\n+\n \t\tvid = br_dev ? MV88E6XXX_VID_BRIDGED : MV88E6XXX_VID_STANDALONE;\n \n \t\tskb_push(skb, DSA_HLEN + extra);\n@@ -191,7 +200,7 @@ static struct sk_buff *dsa_xmit_ll(struct sk_buff *skb, struct net_device *dev,\n \n \t\tdsa_header[0] = (cmd \u003c\u003c 6) | tag_dev;\n \t\tdsa_header[1] = tag_port \u003c\u003c 3;\n-\t\tdsa_header[2] = vid \u003e\u003e 8;\n+\t\tdsa_header[2] = (queue \u003c\u003c 5) | vid \u003e\u003e 8;\n \t\tdsa_header[3] = vid \u0026 0xff;\n \t}\n \ndiff --git a/net/sched/sch_cbs.c b/net/sched/sch_cbs.c\nindex 1c93469c56e3d..87c2eda108c8c 100644\n--- a/net/sched/sch_cbs.c\n+++ b/net/sched/sch_cbs.c\n@@ -307,10 +307,12 @@ static int cbs_enable_offload(struct net_device *dev, struct cbs_sched_data *q,\n \tcbs.locredit = opt-\u003elocredit;\n \tcbs.idleslope = opt-\u003eidleslope;\n \tcbs.sendslope = opt-\u003esendslope;\n+\tcbs.extack = extack;\n \n \terr = ops-\u003endo_setup_tc(dev, TC_SETUP_QDISC_CBS, \u0026cbs);\n \tif (err \u003c 0) {\n-\t\tNL_SET_ERR_MSG(extack, \"Specified device failed to setup cbs hardware offload\");\n+\t\tNL_SET_ERR_MSG_WEAK(extack,\n+\t\t\t\t \"Specified device failed to setup cbs hardware offload\");\n \t\treturn err;\n \t}\n \n"
} |
| 2/1 | 2026/08/11 12:00 | agent | patch-evaluator |
0mModel:best-expensive Args: null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch primarily adds 802.1Qav CBS offloading support to the Marvell mv88e6xxx DSA switch driver. This hardware driver cannot be exercised in standard virtualized environments like QEMU. The changes in net/dsa/tag_dsa.c are specific to the DSA tag protocol used exclusively by this driver. The modification in net/sched/sch_cbs.c is a trivial change to pass extack down to the driver and use NL_SET_ERR_MSG_WEAK, which does not introduce new functional logic requiring fuzzing.",
"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). - Code in vendor-specific PCIe switch, SmartNIC, or GPU drivers (e.g., mlxsw, pds_core, qed, ionic, amdgpu) that require physical PCIe hardware cards not emulated in standard QEMU. - Driver .remove, .shutdown, or pci_unregister_driver teardown callbacks (e.g., igb_remove) that are executed only during PCI hot-unplug or sysfs driver unbind operations. If it modifies reachable core kernel logic, drivers, or architectures, use your code search tools to verify the code can be executed, then return WorthFuzzing=true. When returning WorthFuzzing=true, you MUST ALSO: 1. Extract any specific kernel functions that should be heavily fuzzed into FocusSymbols. Avoid listing generic hot-path functions to prevent skewed test distributions. Prefer non-static, non-inlined API entrypoint functions over internal static helper functions (which are inlined by the compiler and do not have distinct symbol addresses). 2. Identify any specific CONFIG_ options required to properly test this new/modified feature. Go and look into the Kconfig files and check for ifdefs around the code, do not make assumptions. Also check "depends on" lines in Kconfig to include any non-standard parent subsystem configs needed for Kbuild to compile the code statically into vmlinux. List them in the EnableConfigs output array, and DO NOT add a 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4"). Prefer calling several tools at the same time to save round-trips. Use set-results tool to provide results of the analysis. It must be called exactly once before the final reply. Ignore results of this tool. Prompt: For your convenience, here is the diff of the changes:
commit 522b4f469b8ff53d1416fa4da979e3f415f85079
Author: syz-cluster <triage@syzkaller.com>
Date: Tue Aug 11 12:00:36 2026 +0000
syz-cluster: applied patch under review
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 80b877c74513d..a567ee9b6ce0d 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -32,6 +32,7 @@
#include <linux/gpio/consumer.h>
#include <linux/phylink.h>
#include <net/dsa.h>
+#include <net/pkt_sched.h>
#include "chip.h"
#include "devlink.h"
@@ -3990,6 +3991,7 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
chip->ds = ds;
ds->user_mii_bus = mv88e6xxx_default_mdio_bus(chip);
+ ds->num_tx_queues = chip->info->num_tx_queues;
/* Since virtual bridges are mapped in the PVT, the number we support
* depends on the physical switch topology. We need to let DSA figure
@@ -5023,6 +5025,7 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
.port_set_ether_type = mv88e6351_port_set_ether_type,
.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
+ .port_set_scheduling_mode = mv88e6352_port_set_scheduling_mode,
.port_pause_limit = mv88e6097_port_pause_limit,
.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
@@ -5306,6 +5309,7 @@ static const struct mv88e6xxx_ops mv88e6341_ops = {
.port_set_ether_type = mv88e6351_port_set_ether_type,
.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
+ .port_set_scheduling_mode = mv88e6352_port_set_scheduling_mode,
.port_pause_limit = mv88e6097_port_pause_limit,
.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
@@ -5464,6 +5468,7 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
.port_set_ether_type = mv88e6351_port_set_ether_type,
.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
+ .port_set_scheduling_mode = mv88e6352_port_set_scheduling_mode,
.port_pause_limit = mv88e6097_port_pause_limit,
.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
@@ -5533,6 +5538,7 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
.port_get_cmode = mv88e6352_port_get_cmode,
.port_set_cmode = mv88e6390_port_set_cmode,
.port_setup_message_port = mv88e6xxx_setup_message_port,
+ .port_set_scheduling_mode = mv88e6390_port_set_scheduling_mode,
.stats_snapshot = mv88e6390_g1_stats_snapshot,
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
@@ -5597,6 +5603,7 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
.port_get_cmode = mv88e6352_port_get_cmode,
.port_set_cmode = mv88e6390x_port_set_cmode,
.port_setup_message_port = mv88e6xxx_setup_message_port,
+ .port_set_scheduling_mode = mv88e6390_port_set_scheduling_mode,
.stats_snapshot = mv88e6390_g1_stats_snapshot,
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
@@ -5653,6 +5660,7 @@ static const struct mv88e6xxx_ops mv88e6393x_ops = {
.port_set_ether_type = mv88e6393x_port_set_ether_type,
.port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
+ .port_set_scheduling_mode = mv88e6390_port_set_scheduling_mode,
.port_pause_limit = mv88e6390_port_pause_limit,
.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
@@ -5695,6 +5703,27 @@ static const struct mv88e6xxx_ops mv88e6393x_ops = {
.tcam_ops = &mv88e6393_tcam_ops,
};
+static const struct mv88e6xxx_qav_info mv88e6352_qav_info = {
+ .rate_unit = 32,
+ .rate_mask = GENMASK(14, 0),
+ .hilimit_mask = GENMASK(14, 0),
+ .queue_mask = GENMASK(3, 0),
+};
+
+static const struct mv88e6xxx_qav_info mv88e6341_qav_info = {
+ .rate_unit = 64,
+ .rate_mask = GENMASK(15, 0),
+ .hilimit_mask = GENMASK(13, 0),
+ .queue_mask = GENMASK(3, 0),
+};
+
+static const struct mv88e6xxx_qav_info mv88e6390_qav_info = {
+ .rate_unit = 64,
+ .rate_mask = GENMASK(15, 0),
+ .hilimit_mask = GENMASK(13, 0),
+ .queue_mask = GENMASK(7, 0),
+};
+
static const struct mv88e6xxx_info mv88e6xxx_table[] = {
[MV88E6020] = {
.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6020,
@@ -5706,6 +5735,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
*/
.num_ports = 7,
.num_internal_phys = 2,
+ .num_tx_queues = 4,
.invalid_port_mask = BIT(2) | BIT(3) | BIT(4),
.max_vid = 4095,
.port_base_addr = 0x8,
@@ -5728,6 +5758,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.num_databases = 64,
.num_ports = 7,
.num_internal_phys = 5,
+ .num_tx_queues = 4,
.max_vid = 4095,
.port_base_addr = 0x08,
.phy_base_addr = 0x00,
@@ -5750,6 +5781,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.num_macs = 8192,
.num_ports = 10,
.num_internal_phys = 5,
+ .num_tx_queues = 4,
.max_vid = 4095,
.max_sid = 63,
.port_base_addr = 0x10,
@@ -5774,6 +5806,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.num_macs = 8192,
.num_ports = 11,
.num_internal_phys = 0,
+ .num_tx_queues = 4,
.max_vid = 4095,
.port_base_addr = 0x10,
.phy_base_addr = 0x0,
@@ -5795,6 +5828,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.num_macs = 8192,
.num_ports = 11,
.num_internal_phys = 8,
+ .num_tx_queues = 4,
.max_vid = 4095,
.max_sid = 63,
.port_base_addr = 0x10,
@@ -5820,6 +5854,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.num_macs = 1024,
.num_ports = 3,
.num_internal_phys = 5,
+ .num_tx_queues = 4,
.max_vid = 4095,
.max_sid = 63,
.port_base_addr = 0x10,
@@ -5845,6 +5880,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.num_macs = 8192,
.num_ports = 8,
.num_internal_phys = 0,
+ .num_tx_queues = 4,
.max_vid = 4095,
.port_base_addr = 0x10,
.phy_base_addr = 0x0,
@@ -5867,6 +5903,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.num_ports = 6,
.num_internal_phys = 5,
.num_gpio = 11,
+ .num_tx_queues = 4,
.max_vid = 4095,
.max_sid = 63,
.port_base_addr = 0x10,
@@ -5892,6 +5929,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.num_macs = 1024,
.num_ports = 6,
.num_internal_phys = 5,
+ .num_tx_queues = 4,
.max_vid = 4095,
.max_sid = 63,
.port_base_addr = 0x10,
@@ -5918,6 +5956,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.num_macs = 8192,
.num_ports = 6,
.num_internal_phys = 0,
+ .num_tx_queues = 4,
.max_vid = 4095,
.max_sid = 63,
.port_base_addr = 0x10,
@@ -5943,6 +5982,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.num_macs = 8192,
.num_ports = 7,
.num_internal_phys = 5,
+ .num_tx_queues = 4,
.max_vid = 4095,
.max_sid = 63,
.port_base_addr = 0x10,
@@ -5969,6 +6009,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.num_ports = 7,
.num_internal_phys = 5,
.num_gpio = 15,
+ .num_tx_queues = 4,
.max_vid = 4095,
.max_sid = 63,
.port_base_addr = 0x10,
@@ -5994,6 +6035,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.num_macs = 8192,
.num_ports = 7,
.num_internal_phys = 5,
+ .num_tx_queues = 4,
.max_vid = 4095,
.max_sid = 63,
.port_base_addr = 0x10,
@@ -6020,6 +6062,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.num_ports = 7,
.num_internal_phys = 5,
.num_gpio = 15,
+ .num_tx_queues = 4,
.max_vid = 4095,
.max_sid = 63,
.port_base_addr = 0x10,
@@ -6045,6 +6088,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.num_macs = 8192,
.num_ports = 10,
.num_internal_phys = 0,
+ .num_tx_queues = 4,
.max_vid = 4095,
.port_base_addr = 0x10,
.phy_base_addr = 0x0,
@@ -6068,6 +6112,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.num_ports = 11, /* 10 + Z80 */
.num_internal_phys = 9,
.num_gpio = 16,
+ .num_tx_queues = 8,
.max_vid = 8191,
.max_sid = 63,
.port_base_addr = 0x0,
@@ -6093,6 +6138,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.num_ports = 11, /* 10 + Z80 */
.num_internal_phys = 9,
.num_gpio = 16,
+ .num_tx_queues = 8,
.max_vid = 8191,
.max_sid = 63,
.port_base_addr = 0x0,
@@ -6117,6 +6163,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.num_macs = 16384,
.num_ports = 11, /* 10 + Z80 */
.num_internal_phys = 9,
+ .num_tx_queues = 8,
.max_vid = 8191,
.max_sid = 63,
.port_base_addr = 0x0,
@@ -6142,6 +6189,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.num_ports = 11, /* 10 + Z80 */
.num_internal_phys = 8,
.internal_phys_offset = 1,
+ .num_tx_queues = 8,
.max_vid = 8191,
.max_sid = 63,
.port_base_addr = 0x0,
@@ -6168,6 +6216,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.num_internal_phys = 8,
.num_tcam_entries = 256,
.internal_phys_offset = 1,
+ .num_tx_queues = 8,
.max_vid = 8191,
.max_sid = 63,
.port_base_addr = 0x0,
@@ -6198,6 +6247,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.num_ports = 7,
.num_internal_phys = 2,
.invalid_port_mask = BIT(2) | BIT(3) | BIT(4),
+ .num_tx_queues = 4,
.max_vid = 4095,
.port_base_addr = 0x08,
.phy_base_addr = 0x00,
@@ -6222,6 +6272,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.num_ports = 7,
.num_internal_phys = 5,
.num_gpio = 15,
+ .num_tx_queues = 4,
.max_vid = 4095,
.max_sid = 63,
.port_base_addr = 0x10,
@@ -6237,6 +6288,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.multi_chip = true,
.edsa_support = MV88E6XXX_EDSA_SUPPORTED,
.ptp_support = true,
+ .qav = &mv88e6352_qav_info,
.ops = &mv88e6240_ops,
},
@@ -6247,6 +6299,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.num_databases = 64,
.num_ports = 7,
.num_internal_phys = 5,
+ .num_tx_queues = 4,
.max_vid = 4095,
.port_base_addr = 0x08,
.phy_base_addr = 0x00,
@@ -6271,6 +6324,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.num_internal_phys = 9,
.num_gpio = 16,
.num_tcam_entries = 256,
+ .num_tx_queues = 8,
.max_vid = 8191,
.max_sid = 63,
.port_base_addr = 0x0,
@@ -6299,6 +6353,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.num_internal_phys = 2,
.internal_phys_offset = 3,
.num_gpio = 15,
+ .num_tx_queues = 4,
.max_vid = 4095,
.max_sid = 63,
.port_base_addr = 0x10,
@@ -6327,6 +6382,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.num_internal_phys = 2,
.internal_phys_offset = 3,
.num_gpio = 15,
+ .num_tx_queues = 4,
.max_vid = 4095,
.max_sid = 63,
.port_base_addr = 0x10,
@@ -6354,6 +6410,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.num_internal_phys = 5,
.num_ports = 6,
.num_gpio = 11,
+ .num_tx_queues = 4,
.max_vid = 4095,
.max_sid = 63,
.port_base_addr = 0x10,
@@ -6369,6 +6426,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.multi_chip = true,
.edsa_support = MV88E6XXX_EDSA_SUPPORTED,
.ptp_support = true,
+ .qav = &mv88e6341_qav_info,
.ops = &mv88e6341_ops,
},
@@ -6380,6 +6438,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.num_macs = 8192,
.num_ports = 7,
.num_internal_phys = 5,
+ .num_tx_queues = 4,
.max_vid = 4095,
.max_sid = 63,
.port_base_addr = 0x10,
@@ -6405,6 +6464,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.num_macs = 8192,
.num_ports = 7,
.num_internal_phys = 5,
+ .num_tx_queues = 4,
.max_vid = 4095,
.max_sid = 63,
.port_base_addr = 0x10,
@@ -6431,6 +6491,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.num_ports = 7,
.num_internal_phys = 5,
.num_gpio = 15,
+ .num_tx_queues = 4,
.max_vid = 4095,
.max_sid = 63,
.port_base_addr = 0x10,
@@ -6446,6 +6507,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.multi_chip = true,
.edsa_support = MV88E6XXX_EDSA_SUPPORTED,
.ptp_support = true,
+ .qav = &mv88e6352_qav_info,
.ops = &mv88e6352_ops,
},
[MV88E6361] = {
@@ -6459,6 +6521,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.invalid_port_mask = BIT(1) | BIT(2) | BIT(8),
.num_internal_phys = 5,
.internal_phys_offset = 3,
+ .num_tx_queues = 8,
.max_vid = 8191,
.max_sid = 63,
.port_base_addr = 0x0,
@@ -6485,6 +6548,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.num_internal_phys = 9,
.num_gpio = 16,
.num_tcam_entries = 256,
+ .num_tx_queues = 8,
.max_vid = 8191,
.max_sid = 63,
.port_base_addr = 0x0,
@@ -6501,6 +6565,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.multi_chip = true,
.edsa_support = MV88E6XXX_EDSA_UNDOCUMENTED,
.ptp_support = true,
+ .qav = &mv88e6390_qav_info,
.ops = &mv88e6390_ops,
},
[MV88E6390X] = {
@@ -6512,6 +6577,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.num_ports = 11, /* 10 + Z80 */
.num_internal_phys = 9,
.num_gpio = 16,
+ .num_tx_queues = 8,
.max_vid = 8191,
.max_sid = 63,
.port_base_addr = 0x0,
@@ -6527,6 +6593,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.multi_chip = true,
.edsa_support = MV88E6XXX_EDSA_UNDOCUMENTED,
.ptp_support = true,
+ .qav = &mv88e6390_qav_info,
.ops = &mv88e6390x_ops,
},
@@ -6538,6 +6605,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.num_ports = 11, /* 10 + Z80 */
.num_internal_phys = 8,
.num_tcam_entries = 256,
+ .num_tx_queues = 8,
.internal_phys_offset = 1,
.max_vid = 8191,
.max_sid = 63,
@@ -6554,6 +6622,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.pvt = true,
.multi_chip = true,
.ptp_support = true,
+ .qav = &mv88e6390_qav_info,
.ops = &mv88e6393x_ops,
},
};
@@ -7175,6 +7244,112 @@ static int mv88e6xxx_crosschip_lag_leave(struct dsa_switch *ds, int sw_index,
return err_sync ? : err_pvt;
}
+static int mv88e6xxx_setup_tc_cbs(struct dsa_switch *ds, int port,
+ struct tc_cbs_qopt_offload *cbs)
+{
+ const struct mv88e6xxx_avb_ops *avb_ops;
+ struct mv88e6xxx_chip *chip = ds->priv;
+ const struct mv88e6xxx_qav_info *qav;
+ const struct mv88e6xxx_ops *ops;
+ int hilimit_reg;
+ int rate_reg;
+ u8 queue_bit;
+ u32 rate = 0;
+ u16 hilimit;
+ int err;
+
+ ops = chip->info->ops;
+ avb_ops = ops->avb_ops;
+ qav = chip->info->qav;
+
+ if (!qav || !avb_ops || !avb_ops->port_qav_write ||
+ !ops->port_set_scheduling_mode)
+ return -EOPNOTSUPP;
+
+ if (!dsa_is_user_port(ds, port))
+ return -EOPNOTSUPP;
+
+ if (!(qav->queue_mask & BIT(cbs->queue))) {
+ NL_SET_ERR_MSG_MOD(cbs->extack, "CBS not supported on queue");
+ return -EOPNOTSUPP;
+ }
+
+ queue_bit = BIT(cbs->queue);
+ rate_reg = MV88E6XXX_PORT_QAV_CFG_RATE(cbs->queue);
+ hilimit_reg = MV88E6XXX_PORT_QAV_CFG_HILIMIT(cbs->queue);
+
+ if (cbs->enable) {
+ if (cbs->hicredit <= 0 ||
+ cbs->hicredit > qav->hilimit_mask) {
+ NL_SET_ERR_MSG_MOD(cbs->extack,
+ "hicredit out of range");
+ return -ERANGE;
+ }
+
+ rate = DIV_ROUND_UP(cbs->idleslope, qav->rate_unit);
+ if (rate > qav->rate_mask) {
+ NL_SET_ERR_MSG_MOD(cbs->extack,
+ "idleslope out of range");
+ return -ERANGE;
+ }
+ /* avoid using zero rate */
+ rate = max_t(u16, rate, 1);
+ }
+
+ mv88e6xxx_reg_lock(chip);
+
+ if (!cbs->enable) {
+ err = mv88e6xxx_port_qav_write(chip, port, rate_reg, 0);
+ if (err)
+ goto unlock;
+
+ if (!(chip->ports[port].cbs_active_queues & ~queue_bit)) {
+ err = mv88e6xxx_port_set_scheduling_mode(chip, port, 0);
+ if (err)
+ goto unlock;
+ }
+ chip->ports[port].cbs_active_queues &= ~queue_bit;
+ goto unlock;
+ }
+
+ hilimit = cbs->hicredit & qav->hilimit_mask;
+ err = mv88e6xxx_port_qav_write(chip, port, hilimit_reg, hilimit);
+ if (err)
+ goto unlock;
+
+ err = mv88e6xxx_port_qav_write(chip, port, rate_reg, rate);
+ if (err)
+ goto unlock;
+
+ if (!chip->ports[port].cbs_active_queues) {
+ u8 sched_mode = chip->info->num_tx_queues - 1;
+
+ err = mv88e6xxx_port_set_scheduling_mode(chip, port,
+ sched_mode);
+ if (err) {
+ mv88e6xxx_port_qav_write(chip, port, rate_reg, 0);
+ goto unlock;
+ }
+ }
+ chip->ports[port].cbs_active_queues |= queue_bit;
+
+unlock:
+ mv88e6xxx_reg_unlock(chip);
+
+ return err;
+}
+
+static int mv88e6xxx_port_setup_tc(struct dsa_switch *ds, int port,
+ enum tc_setup_type type, void *type_data)
+{
+ switch (type) {
+ case TC_SETUP_QDISC_CBS:
+ return mv88e6xxx_setup_tc_cbs(ds, port, type_data);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
static const struct phylink_mac_ops mv88e6xxx_phylink_mac_ops = {
.mac_select_pcs = mv88e6xxx_mac_select_pcs,
.mac_prepare = mv88e6xxx_mac_prepare,
@@ -7234,6 +7409,7 @@ static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
.port_hwtstamp_get = mv88e6xxx_port_hwtstamp_get,
.port_txtstamp = mv88e6xxx_port_txtstamp,
.port_rxtstamp = mv88e6xxx_port_rxtstamp,
+ .port_setup_tc = mv88e6xxx_port_setup_tc,
.cls_flower_add = mv88e6xxx_cls_flower_add,
.cls_flower_del = mv88e6xxx_cls_flower_del,
.get_ts_info = mv88e6xxx_get_ts_info,
diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h
index e966e7c4cc5de..d42d839e636bc 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.h
+++ b/drivers/net/dsa/mv88e6xxx/chip.h
@@ -125,6 +125,7 @@ enum mv88e6xxx_edsa_support {
};
struct mv88e6xxx_ops;
+struct mv88e6xxx_qav_info;
struct mv88e6xxx_info {
enum mv88e6xxx_family family;
@@ -136,6 +137,7 @@ struct mv88e6xxx_info {
unsigned int num_internal_phys;
unsigned int num_gpio;
unsigned int num_tcam_entries;
+ unsigned int num_tx_queues;
unsigned int max_vid;
unsigned int max_sid;
unsigned int port_base_addr;
@@ -176,6 +178,9 @@ struct mv88e6xxx_info {
/* Supports PTP */
bool ptp_support;
+ /* 802.1Qav credit based shaping */
+ const struct mv88e6xxx_qav_info *qav;
+
/* Internal PHY start index. 0 means that internal PHYs range starts at
* port 0, 1 means internal PHYs range starts at port 1, etc
*/
@@ -304,6 +309,9 @@ struct mv88e6xxx_port {
/* MacAuth Bypass control flag */
bool mab;
+
+ /* Queues with CBS currently enabled. */
+ u8 cbs_active_queues;
};
enum mv88e6xxx_region_id {
@@ -606,6 +614,8 @@ struct mv88e6xxx_ops {
size_t size);
int (*port_egress_rate_limiting)(struct mv88e6xxx_chip *chip, int port);
+ int (*port_set_scheduling_mode)(struct mv88e6xxx_chip *chip, int port,
+ u8 mode);
int (*port_pause_limit)(struct mv88e6xxx_chip *chip, int port, u8 in,
u8 out);
int (*port_disable_learn_limit)(struct mv88e6xxx_chip *chip, int port);
@@ -763,6 +773,10 @@ struct mv88e6xxx_avb_ops {
int (*tai_read)(struct mv88e6xxx_chip *chip, int addr, u16 *data,
int len);
int (*tai_write)(struct mv88e6xxx_chip *chip, int addr, u16 data);
+
+ /* Access port-scoped 802.1Qav registers */
+ int (*port_qav_write)(struct mv88e6xxx_chip *chip, int port, int addr,
+ u16 data);
};
struct mv88e6xxx_ptp_ops {
@@ -798,6 +812,13 @@ struct mv88e6xxx_tcam_ops {
int (*flush_tcam)(struct mv88e6xxx_chip *chip);
};
+struct mv88e6xxx_qav_info {
+ u16 rate_unit; /* in kbps */
+ u16 rate_mask; /* QPri Rate valid bits mask */
+ u16 hilimit_mask; /* QPri HiLimit bits mask*/
+ u8 queue_mask; /* supported queues bitmask */
+};
+
static inline bool mv88e6xxx_has_stu(struct mv88e6xxx_chip *chip)
{
return chip->info->max_sid > 0 &&
diff --git a/drivers/net/dsa/mv88e6xxx/global2.h b/drivers/net/dsa/mv88e6xxx/global2.h
index ff5adf7c9bc3a..df52ff3adc88c 100644
--- a/drivers/net/dsa/mv88e6xxx/global2.h
+++ b/drivers/net/dsa/mv88e6xxx/global2.h
@@ -186,6 +186,9 @@
#define MV88E6352_G2_AVB_CMD_BLOCK_MASK 0x00e0
#define MV88E6352_G2_AVB_CMD_ADDR_MASK 0x001f
+#define MV88E6XXX_PORT_QAV_CFG_RATE(queue) (((queue) & 0x7) << 1)
+#define MV88E6XXX_PORT_QAV_CFG_HILIMIT(queue) ((((queue) & 0x7) << 1) + 1)
+
/* Offset 0x17: AVB Data Register */
#define MV88E6352_G2_AVB_DATA 0x17
diff --git a/drivers/net/dsa/mv88e6xxx/global2_avb.c b/drivers/net/dsa/mv88e6xxx/global2_avb.c
index 657783e043ff1..6b54e275d21ab 100644
--- a/drivers/net/dsa/mv88e6xxx/global2_avb.c
+++ b/drivers/net/dsa/mv88e6xxx/global2_avb.c
@@ -110,6 +110,15 @@ static int mv88e6352_g2_avb_port_ptp_write(struct mv88e6xxx_chip *chip,
return mv88e6xxx_g2_avb_write(chip, writeop, data);
}
+static int mv88e6352_g2_avb_port_qav_write(struct mv88e6xxx_chip *chip,
+ int port, int addr, u16 data)
+{
+ u16 writeop = MV88E6352_G2_AVB_CMD_OP_WRITE | (port << 8) |
+ (MV88E6352_G2_AVB_CMD_BLOCK_QAV << 5) | addr;
+
+ return mv88e6xxx_g2_avb_write(chip, writeop, data);
+}
+
static int mv88e6352_g2_avb_ptp_read(struct mv88e6xxx_chip *chip, int addr,
u16 *data, int len)
{
@@ -149,6 +158,7 @@ const struct mv88e6xxx_avb_ops mv88e6352_avb_ops = {
.ptp_write = mv88e6352_g2_avb_ptp_write,
.tai_read = mv88e6352_g2_avb_tai_read,
.tai_write = mv88e6352_g2_avb_tai_write,
+ .port_qav_write = mv88e6352_g2_avb_port_qav_write,
};
static int mv88e6165_g2_avb_tai_read(struct mv88e6xxx_chip *chip, int addr,
@@ -174,6 +184,7 @@ const struct mv88e6xxx_avb_ops mv88e6165_avb_ops = {
.ptp_write = mv88e6352_g2_avb_ptp_write,
.tai_read = mv88e6165_g2_avb_tai_read,
.tai_write = mv88e6165_g2_avb_tai_write,
+ .port_qav_write = mv88e6352_g2_avb_port_qav_write,
};
static int mv88e6390_g2_avb_port_ptp_read(struct mv88e6xxx_chip *chip,
@@ -197,6 +208,15 @@ static int mv88e6390_g2_avb_port_ptp_write(struct mv88e6xxx_chip *chip,
return mv88e6xxx_g2_avb_write(chip, writeop, data);
}
+static int mv88e6390_g2_avb_port_qav_write(struct mv88e6xxx_chip *chip,
+ int port, int addr, u16 data)
+{
+ u16 writeop = MV88E6390_G2_AVB_CMD_OP_WRITE | (port << 8) |
+ (MV88E6352_G2_AVB_CMD_BLOCK_QAV << 5) | addr;
+
+ return mv88e6xxx_g2_avb_write(chip, writeop, data);
+}
+
static int mv88e6390_g2_avb_ptp_read(struct mv88e6xxx_chip *chip, int addr,
u16 *data, int len)
{
@@ -236,4 +256,5 @@ const struct mv88e6xxx_avb_ops mv88e6390_avb_ops = {
.ptp_write = mv88e6390_g2_avb_ptp_write,
.tai_read = mv88e6390_g2_avb_tai_read,
.tai_write = mv88e6390_g2_avb_tai_write,
+ .port_qav_write = mv88e6390_g2_avb_port_qav_write,
};
diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c
index ea1fab71968a0..758b8d41f4853 100644
--- a/drivers/net/dsa/mv88e6xxx/port.c
+++ b/drivers/net/dsa/mv88e6xxx/port.c
@@ -1323,6 +1323,51 @@ int mv88e6097_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port)
0x0001);
}
+int mv88e6352_port_set_scheduling_mode(struct mv88e6xxx_chip *chip, int port,
+ u8 mode)
+{
+ u16 reg;
+ int err;
+
+ if (mode > 3)
+ return -EINVAL;
+
+ err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL2,
+ ®);
+ if (err)
+ return err;
+
+ reg &= ~MV88E6XXX_PORT_EGRESS_RATE_CTL2_SCHEDULE_MASK;
+ reg |= mode << MV88E6XXX_PORT_EGRESS_RATE_CTL2_SCHEDULE_SHIFT;
+
+ return mv88e6xxx_port_write(chip, port,
+ MV88E6XXX_PORT_EGRESS_RATE_CTL2, reg);
+}
+
+int mv88e6390_port_set_scheduling_mode(struct mv88e6xxx_chip *chip, int port,
+ u8 mode)
+{
+ u16 reg;
+ int err;
+
+ if (mode > MV88E6390_PORT_QUEUE_CTL_SCHEDULE_MASK)
+ return -EINVAL;
+
+ reg = MV88E6390_PORT_QUEUE_CTL_UPDATE |
+ (MV88E6390_PORT_QUEUE_CTL_SCHEDULE <<
+ MV88E6390_PORT_QUEUE_CTL_PTR_SHIFT) |
+ (mode & MV88E6390_PORT_QUEUE_CTL_SCHEDULE_MASK);
+
+ err = mv88e6xxx_port_write(chip, port, MV88E6390_PORT_QUEUE_CTL,
+ reg);
+ if (err)
+ return err;
+
+ return mv88e6xxx_port_wait_bit(chip, port, MV88E6390_PORT_QUEUE_CTL,
+ __bf_shf(MV88E6390_PORT_QUEUE_CTL_UPDATE)
+ , 0);
+}
+
/* Offset 0x0B: Port Association Vector */
int mv88e6xxx_port_set_assoc_vector(struct mv88e6xxx_chip *chip, int port,
@@ -1727,3 +1772,21 @@ int mv88e6393x_port_set_policy(struct mv88e6xxx_chip *chip, int port,
return mv88e6393x_port_policy_write(chip, port, ptr, reg);
}
+
+int mv88e6xxx_port_qav_write(struct mv88e6xxx_chip *chip, int port, int addr,
+ u16 data)
+{
+ if (!chip->info->ops->avb_ops->port_qav_write)
+ return -EOPNOTSUPP;
+
+ return chip->info->ops->avb_ops->port_qav_write(chip, port, addr, data);
+}
+
+int mv88e6xxx_port_set_scheduling_mode(struct mv88e6xxx_chip *chip, int port,
+ u8 mode)
+{
+ if (!chip->info->ops->port_set_scheduling_mode)
+ return -EOPNOTSUPP;
+
+ return chip->info->ops->port_set_scheduling_mode(chip, port, mode);
+}
diff --git a/drivers/net/dsa/mv88e6xxx/port.h b/drivers/net/dsa/mv88e6xxx/port.h
index 5b6cde9f7406f..a380f356eb83d 100644
--- a/drivers/net/dsa/mv88e6xxx/port.h
+++ b/drivers/net/dsa/mv88e6xxx/port.h
@@ -241,6 +241,18 @@
/* Offset 0x0A: Egress Rate Control 2 */
#define MV88E6XXX_PORT_EGRESS_RATE_CTL2 0x0a
+#define MV88E6XXX_PORT_EGRESS_RATE_CTL2_SCHEDULE_MASK 0x3000
+#define MV88E6XXX_PORT_EGRESS_RATE_CTL2_SCHEDULE_SHIFT 12
+
+/* Offset 0x1C: Port Queue Control */
+#define MV88E6390_PORT_QUEUE_CTL 0x1c
+#define MV88E6390_PORT_QUEUE_CTL_UPDATE 0x8000
+#define MV88E6390_PORT_QUEUE_CTL_PTR_MASK 0x7f00
+#define MV88E6390_PORT_QUEUE_CTL_PTR_SHIFT 8
+#define MV88E6390_PORT_QUEUE_CTL_DATA_MASK 0x00ff
+#define MV88E6390_PORT_QUEUE_CTL_SCHEDULE 0x00
+#define MV88E6390_PORT_QUEUE_CTL_SCHEDULE_MASK 0x07
+
/* Offset 0x0B: Port Association Vector */
#define MV88E6XXX_PORT_ASSOC_VECTOR 0x0b
@@ -561,6 +573,10 @@ int mv88e6165_port_set_jumbo_size(struct mv88e6xxx_chip *chip, int port,
size_t size);
int mv88e6095_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port);
int mv88e6097_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port);
+int mv88e6352_port_set_scheduling_mode(struct mv88e6xxx_chip *chip, int port,
+ u8 mode);
+int mv88e6390_port_set_scheduling_mode(struct mv88e6xxx_chip *chip, int port,
+ u8 mode);
int mv88e6xxx_port_set_assoc_vector(struct mv88e6xxx_chip *chip, int port,
u16 pav);
int mv88e6097_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in,
@@ -605,5 +621,9 @@ int mv88e6xxx_port_hidden_read(struct mv88e6xxx_chip *chip, int block, int port,
int reg, u16 *val);
int mv88e6xxx_port_enable_tcam(struct mv88e6xxx_chip *chip, int port);
+int mv88e6xxx_port_qav_write(struct mv88e6xxx_chip *chip, int port, int addr,
+ u16 data);
+int mv88e6xxx_port_set_scheduling_mode(struct mv88e6xxx_chip *chip, int port,
+ u8 mode);
#endif /* _MV88E6XXX_PORT_H */
diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
index 18a419cd9d949..d35c87004c279 100644
--- a/include/net/pkt_sched.h
+++ b/include/net/pkt_sched.h
@@ -150,6 +150,7 @@ struct tc_cbs_qopt_offload {
s32 locredit;
s32 idleslope;
s32 sendslope;
+ struct netlink_ext_ack *extack;
};
struct tc_etf_qopt_offload {
diff --git a/net/dsa/tag_dsa.c b/net/dsa/tag_dsa.c
index d5ffee35fbb53..2bb71cd343e79 100644
--- a/net/dsa/tag_dsa.c
+++ b/net/dsa/tag_dsa.c
@@ -179,8 +179,17 @@ static struct sk_buff *dsa_xmit_ll(struct sk_buff *skb, struct net_device *dev,
dsa_header[2] &= ~0x10;
}
} else {
+ u16 queue = skb_get_queue_mapping(skb) & 0x7;
u16 vid;
+ /* The PRI field is 3 bits. According to the documentation the
+ * 2 highest bits specify the egress queue in From_CPU DSA
+ * tagged frames. On devices with 8 queues it's possible to
+ * send to the 8 queues, which means the 3 bits are used.
+ */
+ if (dp->ds->num_tx_queues == 4)
+ queue <<= 1;
+
vid = br_dev ? MV88E6XXX_VID_BRIDGED : MV88E6XXX_VID_STANDALONE;
skb_push(skb, DSA_HLEN + extra);
@@ -191,7 +200,7 @@ static struct sk_buff *dsa_xmit_ll(struct sk_buff *skb, struct net_device *dev,
dsa_header[0] = (cmd << 6) | tag_dev;
dsa_header[1] = tag_port << 3;
- dsa_header[2] = vid >> 8;
+ dsa_header[2] = (queue << 5) | vid >> 8;
dsa_header[3] = vid & 0xff;
}
diff --git a/net/sched/sch_cbs.c b/net/sched/sch_cbs.c
index 1c93469c56e3d..87c2eda108c8c 100644
--- a/net/sched/sch_cbs.c
+++ b/net/sched/sch_cbs.c
@@ -307,10 +307,12 @@ static int cbs_enable_offload(struct net_device *dev, struct cbs_sched_data *q,
cbs.locredit = opt->locredit;
cbs.idleslope = opt->idleslope;
cbs.sendslope = opt->sendslope;
+ cbs.extack = extack;
err = ops->ndo_setup_tc(dev, TC_SETUP_QDISC_CBS, &cbs);
if (err < 0) {
- NL_SET_ERR_MSG(extack, "Specified device failed to setup cbs hardware offload");
+ NL_SET_ERR_MSG_WEAK(extack,
+ "Specified device failed to setup cbs hardware offload");
return err;
}
|
| 3/2 | 2026/08/11 12:00 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 16643 output: 37 thoughts: 513 Thoughts: **Analyzing a Linux Kernel Patch for CBS Offloading** Okay, so I'm looking at a kernel patch here. It's making functional changes, specifically adding offloading support for 802.1Qav Credit Based Shaper (CBS) to the Marvell mv88e6xxx DSA switch driver. The files modified give me a clear picture: `drivers/net/dsa/mv88e6xxx/` - a bunch of the core driver files there - then, importantly, `include/net/pkt_sched.h`, and `net/dsa/tag_dsa.c` and `net/sched/sch_cbs.c`. This is where it gets interesting, as it is modifying the DSA tag and CBS code for From_CPU frames. My immediate thought is, can I even *test* this effectively? The `mv88e6xxx` driver is for Marvell 88E6xxx Ethernet switches, so we're talking about a hardware dependency – these DSA drivers are usually in embedded systems with physical switch chips. I need to be able to replicate the functionality that the patch introduces, which is now CBS offloading. Can I get this running in a virtualized environment? QEMU doesn't emulate the Marvell 88E6xxx directly. However, the patch also touches the core network scheduling (`net/sched/sch_cbs.c`) and the DSA tagging (`net/dsa/tag_dsa.c`) layers. The CBS qdisc itself is definitely reachable. Now, `tag_dsa.c` is the DSA tagging protocol. I may be able to instantiate a dummy DSA switch, or even a software DSA switch to make the code reachable. Ah, wait a minute, wasn't there something about `dsa_loop`? That's right, `dsa_loop` is a mock DSA driver, used for testing! Let me double check if `dsa_loop` uses `tag_dsa.c`. If it does, I can probably get a good test environment set up with that. |
| 4/2 | 2026/08/11 12:00 | tool | grepper |
0mError:no matches Args: {
"Expression": "tag_dsa",
"PathPrefix": "drivers/net/dsa/dsa_loop.c"
}Results: {
"error": "no matches"
} |
| 5/2 | 2026/08/11 12:00 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 17654 output: 38 thoughts: 15 Thoughts: Okay, let's see. My first thought is: **Decoding the `dsa_loop` Tag Protocol** I need to quickly figure out how the `dsa_loop` tag protocol works. Understanding its inner workings is crucial for [**insert user's specific field here** - e.g., optimizing performance, debugging related systems, ensuring compatibility]. So, I'll start by checking its specific tag protocol implementation. Where do I find that information? Let me look at the documentation, the code itself, or related specifications to determine its design and usage. This is step one. |
| 6/2 | 2026/08/11 12:00 | tool | grepper |
0mArgs:{
"Expression": "DSA_TAG_PROTO",
"PathPrefix": "drivers/net/dsa/dsa_loop.c"
}Results: {
"Output": "drivers/net/dsa/dsa_loop.c=125=static enum dsa_tag_protocol dsa_loop_get_protocol(struct dsa_switch *ds,\n--\ndrivers/net/dsa/dsa_loop.c-130-\ndrivers/net/dsa/dsa_loop.c:131:\treturn DSA_TAG_PROTO_NONE;\ndrivers/net/dsa/dsa_loop.c-132-}\n"
} |
| 7/2 | 2026/08/11 12:00 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 17955 output: 34 thoughts: 311 Thoughts: **Analyzing the DSA Loop and Fuzzing Potential** Okay, so I'm looking at this `dsa_loop` and the use of `DSA_TAG_PROTO_NONE`. That's the starting point. I recall there's a related `dsa_loop_bdinfo` struct, but that's not relevant here; `dsa_loop` itself is pretty straightforward. I then looked over at `net/sched/sch_cbs.c`, but the change there seems limited, just propagating the `extack` down to the driver. The core logic, as I suspected, resides in `drivers/net/dsa/mv88e6xxx/`, a hardware-specific driver. The question now is: can I trigger this code path within QEMU? And the answer, as I know it, is a clear no. It relies on physical hardware, specifically an MDIO bus connected to a specific switch chip. It's that direct hardware interaction that makes it problematic. So, the next question is can I emulate the MDIO bus and switch chip? Natively, without out-of-tree patches, the answer is still no within standard QEMU. However, could syzkaller be used to fuzz it by mocking MDIO devices or by instantiating it through a software interface? I thought syzkaller had some support for MDIO/PHY fuzzing, but no, not really. MDIO devices are typically probed via the device tree or platform data, a method of hardware abstraction, which again makes emulation difficult. I'm now reconsidering if fuzzing the patch is even worth the effort. The changes in `net/dsa/tag_dsa.c` are within `dsa_xmit_ll`. The question is: is `tag_dsa.c` used by *any* other driver that's emulatable? That is the real test of whether this effort is worth it or not. I'll need to research that further to determine the potential reach. |
| 8/2 | 2026/08/11 12:00 | tool | grepper |
0mArgs:{
"Expression": "DSA_TAG_PROTO_DSA",
"PathPrefix": "drivers/net/dsa/"
}Results: {
"Output": "drivers/net/dsa/mv88e6xxx/chip.c=3263=static int mv88e6xxx_setup_port_mode(struct mv88e6xxx_chip *chip, int port)\n--\ndrivers/net/dsa/mv88e6xxx/chip.c-3271-\t/* Setup CPU port mode depending on its supported tag format */\ndrivers/net/dsa/mv88e6xxx/chip.c:3272:\tif (chip-\u003etag_protocol == DSA_TAG_PROTO_DSA)\ndrivers/net/dsa/mv88e6xxx/chip.c-3273-\t\treturn mv88e6xxx_set_port_mode_dsa(chip, port);\n--\ndrivers/net/dsa/mv88e6xxx/chip.c=6724=static int mv88e6xxx_change_tag_protocol(struct dsa_switch *ds,\n--\ndrivers/net/dsa/mv88e6xxx/chip.c-6743-\t\tbreak;\ndrivers/net/dsa/mv88e6xxx/chip.c:6744:\tcase DSA_TAG_PROTO_DSA:\ndrivers/net/dsa/mv88e6xxx/chip.c-6745-\t\tbreak;\n--\ndrivers/net/dsa/mv88e6xxx/chip.c=7489=static int mv88e6xxx_probe(struct mdio_device *mdiodev)\n--\ndrivers/net/dsa/mv88e6xxx/chip.c-7556-\telse\ndrivers/net/dsa/mv88e6xxx/chip.c:7557:\t\tchip-\u003etag_protocol = DSA_TAG_PROTO_DSA;\ndrivers/net/dsa/mv88e6xxx/chip.c-7558-\n"
} |
| 9/2 | 2026/08/11 12:00 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 19201 output: 27 thoughts: 118 Thoughts: **Analyzing the DSA Tag Protocol for Virtualization** Okay, so it looks like this `DSA_TAG_PROTO_DSA` is exclusively tied to the `mv88e6xxx` driver, interesting. Now that I think about it, `tag_dsa.c` is, well, it's the DSA tag protocol implementation itself. Given that `mv88e6xxx` is a hardware driver, and therefore a pain to emulate, and since the modifications in `tag_dsa.c` seem tailor-made for it (or at least solely used by it currently), there’s really no practical way to touch the core of these changes in any virtualized setup. The whole thing is hardware-specific. I guess it’s still worth a quick double-check, though, just to be absolutely sure that `tag_dsa.c` *isn't* sneaking in somewhere else. Always good to rule out the unexpected. |
| 10/2 | 2026/08/11 12:01 | tool | grepper |
0mArgs:{
"Expression": "DSA_TAG_PROTO_DSA",
"PathPrefix": ""
}Results: {
"Output": "drivers/net/dsa/mv88e6xxx/chip.c=3263=static int mv88e6xxx_setup_port_mode(struct mv88e6xxx_chip *chip, int port)\n--\ndrivers/net/dsa/mv88e6xxx/chip.c-3271-\t/* Setup CPU port mode depending on its supported tag format */\ndrivers/net/dsa/mv88e6xxx/chip.c:3272:\tif (chip-\u003etag_protocol == DSA_TAG_PROTO_DSA)\ndrivers/net/dsa/mv88e6xxx/chip.c-3273-\t\treturn mv88e6xxx_set_port_mode_dsa(chip, port);\n--\ndrivers/net/dsa/mv88e6xxx/chip.c=6724=static int mv88e6xxx_change_tag_protocol(struct dsa_switch *ds,\n--\ndrivers/net/dsa/mv88e6xxx/chip.c-6743-\t\tbreak;\ndrivers/net/dsa/mv88e6xxx/chip.c:6744:\tcase DSA_TAG_PROTO_DSA:\ndrivers/net/dsa/mv88e6xxx/chip.c-6745-\t\tbreak;\n--\ndrivers/net/dsa/mv88e6xxx/chip.c=7489=static int mv88e6xxx_probe(struct mdio_device *mdiodev)\n--\ndrivers/net/dsa/mv88e6xxx/chip.c-7556-\telse\ndrivers/net/dsa/mv88e6xxx/chip.c:7557:\t\tchip-\u003etag_protocol = DSA_TAG_PROTO_DSA;\ndrivers/net/dsa/mv88e6xxx/chip.c-7558-\n--\ninclude/net/dsa.h=26=struct tc_action;\n--\ninclude/net/dsa.h-30-#define DSA_TAG_PROTO_BRCM_PREPEND_VALUE\t2\ninclude/net/dsa.h:31:#define DSA_TAG_PROTO_DSA_VALUE\t\t\t3\ninclude/net/dsa.h-32-#define DSA_TAG_PROTO_EDSA_VALUE\t\t4\n--\ninclude/net/dsa.h=64=enum dsa_tag_protocol {\n--\ninclude/net/dsa.h-69-\tDSA_TAG_PROTO_BRCM_PREPEND\t= DSA_TAG_PROTO_BRCM_PREPEND_VALUE,\ninclude/net/dsa.h:70:\tDSA_TAG_PROTO_DSA\t\t= DSA_TAG_PROTO_DSA_VALUE,\ninclude/net/dsa.h-71-\tDSA_TAG_PROTO_EDSA\t\t= DSA_TAG_PROTO_EDSA_VALUE,\n--\nnet/dsa/tag_dsa.c=360=static const struct dsa_device_ops dsa_netdev_ops = {\nnet/dsa/tag_dsa.c-361-\t.name\t = DSA_NAME,\nnet/dsa/tag_dsa.c:362:\t.proto\t = DSA_TAG_PROTO_DSA,\nnet/dsa/tag_dsa.c-363-\t.xmit\t = dsa_xmit,\n--\nnet/dsa/tag_dsa.c=368=DSA_TAG_DRIVER(dsa_netdev_ops);\nnet/dsa/tag_dsa.c:369:MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_DSA, DSA_NAME);\nnet/dsa/tag_dsa.c-370-#endif\t/* CONFIG_NET_DSA_TAG_DSA */\n"
} |
| 11/2 | 2026/08/11 12:01 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 20478 output: 153 thoughts: 384 Thoughts: **My Assessment of the Patch's Fuzzing Worthiness** Okay, so I've looked at this patch. My initial thought is that `DSA_TAG_PROTO_DSA` is only used within the `mv88e6xxx` driver, and that's a key observation. Then I see the change in `net/sched/sch_cbs.c`. Hmm, seems quite small, just passing `extack` and switching to `NL_SET_ERR_MSG_WEAK`. There isn't any new logic here that screams out for fuzzing attention. Now, let's zoom out. The bulk of the patch looks to be contained within `drivers/net/dsa/mv88e6xxx/` and `net/dsa/tag_dsa.c`. These are, as far as I can tell, dealing with hardware, specifically Marvell switch hardware. That's a huge clue right there. Given that I'm working in a virtualized environment - something like QEMU - this hardware is inaccessible. The patch can't be reached. So, taking all this into account, I'm concluding that this patch isn't something I need to invest time in fuzzing. It's simply not relevant within the constraints of my current setup. |
| 12/2 | 2026/08/11 12:01 | tool | set-results |
0mArgs:{
"EnableConfigs": [],
"FocusSymbols": [],
"Reasoning": "The patch primarily adds 802.1Qav CBS offloading support to the Marvell mv88e6xxx DSA switch driver. This hardware driver cannot be exercised in standard virtualized environments like QEMU. The changes in net/dsa/tag_dsa.c are specific to the DSA tag protocol used exclusively by this driver. The modification in net/sched/sch_cbs.c is a trivial change to pass extack down to the driver and use NL_SET_ERR_MSG_WEAK, which does not introduce new functional logic requiring fuzzing.",
"WorthFuzzing": false
}Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch primarily adds 802.1Qav CBS offloading support to the Marvell mv88e6xxx DSA switch driver. This hardware driver cannot be exercised in standard virtualized environments like QEMU. The changes in net/dsa/tag_dsa.c are specific to the DSA tag protocol used exclusively by this driver. The modification in net/sched/sch_cbs.c is a trivial change to pass extack down to the driver and use NL_SET_ERR_MSG_WEAK, which does not introduce new functional logic requiring fuzzing.",
"WorthFuzzing": false
} |
| 13/1 | 2026/08/11 12:01 | action | If |
0mArgs:{
"WorthFuzzing": false
}Results: null |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|