From: Cedric Jehasse When transmitting fill in the PRI field in the dsa tag to select the egress queue is sent to. From the datasheets i've looked at these switches have 4 or 8 transmit queues per port. Note: skbs with skb->fw_offload_fwd_mark set use the DSA_CMD_FORWARD tag. These are processed as normal ingress frames, meaning the queue they end up in can still be altered by other switch config. eg. priority overrides, tcam policies. This isn't done for vlan tagged frames because this would overwrite the PCP value in the vlan tag (The PRI field in the dsa tag is used as the PCP value in the vlan tag). Signed-off-by: Cedric Jehasse --- drivers/net/dsa/mv88e6xxx/chip.c | 35 +++++++++++++++++++++++++++++++++++ drivers/net/dsa/mv88e6xxx/chip.h | 1 + net/dsa/tag_dsa.c | 11 ++++++++++- 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 8ca5fd40df92..ffd4fa41b7c5 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -3979,6 +3979,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 @@ -5689,6 +5690,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, @@ -5711,6 +5713,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, @@ -5733,6 +5736,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, @@ -5757,6 +5761,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, @@ -5778,6 +5783,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, @@ -5803,6 +5809,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, @@ -5828,6 +5835,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, @@ -5850,6 +5858,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, @@ -5875,6 +5884,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, @@ -5901,6 +5911,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, @@ -5926,6 +5937,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, @@ -5952,6 +5964,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, @@ -5977,6 +5990,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, @@ -6003,6 +6017,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, @@ -6028,6 +6043,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, @@ -6051,6 +6067,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, @@ -6076,6 +6093,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, @@ -6100,6 +6118,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, @@ -6125,6 +6144,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, @@ -6151,6 +6171,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, @@ -6181,6 +6202,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, @@ -6205,6 +6227,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, @@ -6230,6 +6253,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, @@ -6254,6 +6278,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, @@ -6282,6 +6307,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, @@ -6310,6 +6336,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, @@ -6337,6 +6364,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, @@ -6363,6 +6391,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, @@ -6388,6 +6417,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, @@ -6414,6 +6444,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, @@ -6442,6 +6473,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, @@ -6468,6 +6500,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, @@ -6495,6 +6528,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, @@ -6521,6 +6555,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, diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h index cde71828e9d9..19d8eda19b78 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.h +++ b/drivers/net/dsa/mv88e6xxx/chip.h @@ -136,6 +136,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; diff --git a/net/dsa/tag_dsa.c b/net/dsa/tag_dsa.c index 2a2c4fb61a65..cc27b2994c6b 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; } -- 2.43.0