Skip to content

Commit 328de46

Browse files
oleremdavem330
authored andcommitted
net: dsa: microchip: add multi queue support for KSZ88X3 variants
KSZ88X3 switches support up to 4 queues. Rework ksz8795_set_prio_queue() to support KSZ8795 and KSZ88X3 families of switches. Per default, configure KSZ88X3 to use one queue, since it need special handling due to priority related errata. Errata handling is implemented in a separate patch. Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de> Acked-by: Arun Ramadoss <arun.ramadoss@microchip.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 768cf84 commit 328de46

File tree

2 files changed

+61
-35
lines changed

2 files changed

+61
-35
lines changed

drivers/net/dsa/microchip/ksz8795.c

Lines changed: 57 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -127,37 +127,56 @@ int ksz8_change_mtu(struct ksz_device *dev, int port, int mtu)
127127
return -EOPNOTSUPP;
128128
}
129129

130-
static void ksz8795_set_prio_queue(struct ksz_device *dev, int port, int queue)
130+
static int ksz8_port_queue_split(struct ksz_device *dev, int port, int queues)
131131
{
132-
u8 hi, lo;
132+
u8 mask_4q, mask_2q;
133+
u8 reg_4q, reg_2q;
134+
u8 data_4q = 0;
135+
u8 data_2q = 0;
136+
int ret;
133137

134-
/* Number of queues can only be 1, 2, or 4. */
135-
switch (queue) {
136-
case 4:
137-
case 3:
138-
queue = PORT_QUEUE_SPLIT_4;
139-
break;
140-
case 2:
141-
queue = PORT_QUEUE_SPLIT_2;
142-
break;
143-
default:
144-
queue = PORT_QUEUE_SPLIT_1;
138+
if (ksz_is_ksz88x3(dev)) {
139+
mask_4q = KSZ8873_PORT_4QUEUE_SPLIT_EN;
140+
mask_2q = KSZ8873_PORT_2QUEUE_SPLIT_EN;
141+
reg_4q = REG_PORT_CTRL_0;
142+
reg_2q = REG_PORT_CTRL_2;
143+
144+
/* KSZ8795 family switches have Weighted Fair Queueing (WFQ)
145+
* enabled by default. Enable it for KSZ8873 family switches
146+
* too. Default value for KSZ8873 family is strict priority,
147+
* which should be enabled by using TC_SETUP_QDISC_ETS, not
148+
* by default.
149+
*/
150+
ret = ksz_rmw8(dev, REG_SW_CTRL_3, WEIGHTED_FAIR_QUEUE_ENABLE,
151+
WEIGHTED_FAIR_QUEUE_ENABLE);
152+
if (ret)
153+
return ret;
154+
} else {
155+
mask_4q = KSZ8795_PORT_4QUEUE_SPLIT_EN;
156+
mask_2q = KSZ8795_PORT_2QUEUE_SPLIT_EN;
157+
reg_4q = REG_PORT_CTRL_13;
158+
reg_2q = REG_PORT_CTRL_0;
159+
160+
/* TODO: this is legacy from initial KSZ8795 driver, should be
161+
* moved to appropriate place in the future.
162+
*/
163+
ret = ksz_rmw8(dev, REG_SW_CTRL_19,
164+
SW_OUT_RATE_LIMIT_QUEUE_BASED,
165+
SW_OUT_RATE_LIMIT_QUEUE_BASED);
166+
if (ret)
167+
return ret;
145168
}
146-
ksz_pread8(dev, port, REG_PORT_CTRL_0, &lo);
147-
ksz_pread8(dev, port, P_DROP_TAG_CTRL, &hi);
148-
lo &= ~PORT_QUEUE_SPLIT_L;
149-
if (queue & PORT_QUEUE_SPLIT_2)
150-
lo |= PORT_QUEUE_SPLIT_L;
151-
hi &= ~PORT_QUEUE_SPLIT_H;
152-
if (queue & PORT_QUEUE_SPLIT_4)
153-
hi |= PORT_QUEUE_SPLIT_H;
154-
ksz_pwrite8(dev, port, REG_PORT_CTRL_0, lo);
155-
ksz_pwrite8(dev, port, P_DROP_TAG_CTRL, hi);
156-
157-
/* Default is port based for egress rate limit. */
158-
if (queue != PORT_QUEUE_SPLIT_1)
159-
ksz_cfg(dev, REG_SW_CTRL_19, SW_OUT_RATE_LIMIT_QUEUE_BASED,
160-
true);
169+
170+
if (queues == 4)
171+
data_4q = mask_4q;
172+
else if (queues == 2)
173+
data_2q = mask_2q;
174+
175+
ret = ksz_prmw8(dev, port, reg_4q, mask_4q, data_4q);
176+
if (ret)
177+
return ret;
178+
179+
return ksz_prmw8(dev, port, reg_2q, mask_2q, data_2q);
161180
}
162181

163182
void ksz8_r_mib_cnt(struct ksz_device *dev, int port, u16 addr, u64 *cnt)
@@ -1513,15 +1532,23 @@ void ksz8_port_setup(struct ksz_device *dev, int port, bool cpu_port)
15131532
{
15141533
struct dsa_switch *ds = dev->ds;
15151534
const u32 *masks;
1535+
int queues;
15161536
u8 member;
15171537

15181538
masks = dev->info->masks;
15191539

15201540
/* enable broadcast storm limit */
15211541
ksz_port_cfg(dev, port, P_BCAST_STORM_CTRL, PORT_BROADCAST_STORM, true);
15221542

1523-
if (!ksz_is_ksz88x3(dev))
1524-
ksz8795_set_prio_queue(dev, port, 4);
1543+
/* For KSZ88x3 enable only one queue by default, otherwise we won't
1544+
* be able to get rid of PCP prios on Port 2.
1545+
*/
1546+
if (ksz_is_ksz88x3(dev))
1547+
queues = 1;
1548+
else
1549+
queues = dev->info->num_tx_queues;
1550+
1551+
ksz8_port_queue_split(dev, port, queues);
15251552

15261553
/* disable DiffServ priority */
15271554
ksz_port_cfg(dev, port, P_PRIO_CTRL, PORT_DIFFSERV_ENABLE, false);

drivers/net/dsa/microchip/ksz8795_reg.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,8 @@
124124
#define PORT_BASED_PRIO_3 3
125125
#define PORT_INSERT_TAG BIT(2)
126126
#define PORT_REMOVE_TAG BIT(1)
127-
#define PORT_QUEUE_SPLIT_L BIT(0)
127+
#define KSZ8795_PORT_2QUEUE_SPLIT_EN BIT(0)
128+
#define KSZ8873_PORT_4QUEUE_SPLIT_EN BIT(0)
128129

129130
#define REG_PORT_1_CTRL_1 0x11
130131
#define REG_PORT_2_CTRL_1 0x21
@@ -143,6 +144,7 @@
143144
#define REG_PORT_4_CTRL_2 0x42
144145
#define REG_PORT_5_CTRL_2 0x52
145146

147+
#define KSZ8873_PORT_2QUEUE_SPLIT_EN BIT(7)
146148
#define PORT_INGRESS_FILTER BIT(6)
147149
#define PORT_DISCARD_NON_VID BIT(5)
148150
#define PORT_FORCE_FLOW_CTRL BIT(4)
@@ -463,10 +465,7 @@
463465
#define REG_PORT_4_CTRL_13 0xE1
464466
#define REG_PORT_5_CTRL_13 0xF1
465467

466-
#define PORT_QUEUE_SPLIT_H BIT(1)
467-
#define PORT_QUEUE_SPLIT_1 0
468-
#define PORT_QUEUE_SPLIT_2 1
469-
#define PORT_QUEUE_SPLIT_4 2
468+
#define KSZ8795_PORT_4QUEUE_SPLIT_EN BIT(1)
470469
#define PORT_DROP_TAG BIT(0)
471470

472471
#define REG_PORT_1_CTRL_14 0xB2

0 commit comments

Comments
 (0)