1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2024 Pengutronix, Oleksij Rempel <kernel@pengutronix.de>
3
4 #include <linux/dsa/ksz_common.h>
5 #include <net/dsa.h>
6 #include <net/dscp.h>
7 #include <net/ieee8021q.h>
8
9 #include "ksz_common.h"
10 #include "ksz_dcb.h"
11 #include "ksz8.h"
12
13 #define KSZ8_REG_PORT_1_CTRL_0 0x10
14 #define KSZ8_PORT_DIFFSERV_ENABLE BIT(6)
15 #define KSZ8_PORT_802_1P_ENABLE BIT(5)
16 #define KSZ8_PORT_BASED_PRIO_M GENMASK(4, 3)
17
18 #define KSZ88X3_REG_TOS_DSCP_CTRL 0x60
19 #define KSZ8765_REG_TOS_DSCP_CTRL 0x90
20
21 #define KSZ9477_REG_SW_MAC_TOS_CTRL 0x033e
22 #define KSZ9477_SW_TOS_DSCP_REMAP BIT(0)
23 #define KSZ9477_SW_TOS_DSCP_DEFAULT_PRIO_M GENMASK(5, 3)
24
25 #define KSZ9477_REG_DIFFSERV_PRIO_MAP 0x0340
26
27 #define KSZ9477_REG_PORT_MRI_PRIO_CTRL 0x0801
28 #define KSZ9477_PORT_HIGHEST_PRIO BIT(7)
29 #define KSZ9477_PORT_OR_PRIO BIT(6)
30 #define KSZ9477_PORT_MAC_PRIO_ENABLE BIT(4)
31 #define KSZ9477_PORT_VLAN_PRIO_ENABLE BIT(3)
32 #define KSZ9477_PORT_802_1P_PRIO_ENABLE BIT(2)
33 #define KSZ9477_PORT_DIFFSERV_PRIO_ENABLE BIT(1)
34 #define KSZ9477_PORT_ACL_PRIO_ENABLE BIT(0)
35
36 #define KSZ9477_REG_PORT_MRI_MAC_CTRL 0x0802
37 #define KSZ9477_PORT_BASED_PRIO_M GENMASK(2, 0)
38
39 struct ksz_apptrust_map {
40 u8 apptrust;
41 u8 bit;
42 };
43
44 static const struct ksz_apptrust_map ksz8_apptrust_map_to_bit[] = {
45 { DCB_APP_SEL_PCP, KSZ8_PORT_802_1P_ENABLE },
46 { IEEE_8021QAZ_APP_SEL_DSCP, KSZ8_PORT_DIFFSERV_ENABLE },
47 };
48
49 static const struct ksz_apptrust_map ksz9477_apptrust_map_to_bit[] = {
50 { DCB_APP_SEL_PCP, KSZ9477_PORT_802_1P_PRIO_ENABLE },
51 { IEEE_8021QAZ_APP_SEL_DSCP, KSZ9477_PORT_DIFFSERV_PRIO_ENABLE },
52 };
53
54 /* ksz_supported_apptrust[] - Supported apptrust selectors and Priority Order
55 * of Internal Priority Map (IPM) sources.
56 *
57 * This array defines the apptrust selectors supported by the hardware, where
58 * the index within the array indicates the priority of the selector - lower
59 * indices correspond to higher priority. This fixed priority scheme is due to
60 * the hardware's design, which does not support configurable priority among
61 * different priority sources.
62 *
63 * The priority sources, including Tail Tag, ACL, VLAN PCP and DSCP are ordered
64 * by the hardware's fixed logic, as detailed below. The order reflects a
65 * non-configurable precedence where certain types of priority information
66 * override others:
67 *
68 * 1. Tail Tag - Highest priority, overrides ACL, VLAN PCP, and DSCP priorities.
69 * 2. ACL - Overrides VLAN PCP and DSCP priorities.
70 * 3. VLAN PCP - Overrides DSCP priority.
71 * 4. DSCP - Lowest priority, does not override any other priority source.
72 *
73 * In this context, the array's lower index (higher priority) for
74 * 'DCB_APP_SEL_PCP' suggests its relative priority over
75 * 'IEEE_8021QAZ_APP_SEL_DSCP' within the system's fixed priority scheme.
76 *
77 * DCB_APP_SEL_PCP - Priority Code Point selector
78 * IEEE_8021QAZ_APP_SEL_DSCP - Differentiated Services Code Point selector
79 */
80 static const u8 ksz_supported_apptrust[] = {
81 DCB_APP_SEL_PCP,
82 IEEE_8021QAZ_APP_SEL_DSCP,
83 };
84
85 static const char * const ksz_supported_apptrust_variants[] = {
86 "empty", "dscp", "pcp", "dscp pcp"
87 };
88
ksz_get_default_port_prio_reg(struct ksz_device * dev,int * reg,u8 * mask,int * shift)89 static void ksz_get_default_port_prio_reg(struct ksz_device *dev, int *reg,
90 u8 *mask, int *shift)
91 {
92 if (is_ksz8(dev)) {
93 *reg = KSZ8_REG_PORT_1_CTRL_0;
94 *mask = KSZ8_PORT_BASED_PRIO_M;
95 *shift = __bf_shf(KSZ8_PORT_BASED_PRIO_M);
96 } else {
97 *reg = KSZ9477_REG_PORT_MRI_MAC_CTRL;
98 *mask = KSZ9477_PORT_BASED_PRIO_M;
99 *shift = __bf_shf(KSZ9477_PORT_BASED_PRIO_M);
100 }
101 }
102
103 /**
104 * ksz_get_dscp_prio_reg - Retrieves the DSCP-to-priority-mapping register
105 * @dev: Pointer to the KSZ switch device structure
106 * @reg: Pointer to the register address to be set
107 * @per_reg: Pointer to the number of DSCP values per register
108 * @mask: Pointer to the mask to be set
109 *
110 * This function retrieves the DSCP to priority mapping register, the number of
111 * DSCP values per register, and the mask to be set.
112 */
ksz_get_dscp_prio_reg(struct ksz_device * dev,int * reg,int * per_reg,u8 * mask)113 static void ksz_get_dscp_prio_reg(struct ksz_device *dev, int *reg,
114 int *per_reg, u8 *mask)
115 {
116 if (ksz_is_ksz87xx(dev) || ksz_is_8895_family(dev)) {
117 *reg = KSZ8765_REG_TOS_DSCP_CTRL;
118 *per_reg = 4;
119 *mask = GENMASK(1, 0);
120 } else if (ksz_is_ksz88x3(dev)) {
121 *reg = KSZ88X3_REG_TOS_DSCP_CTRL;
122 *per_reg = 4;
123 *mask = GENMASK(1, 0);
124 } else {
125 *reg = KSZ9477_REG_DIFFSERV_PRIO_MAP;
126 *per_reg = 2;
127 *mask = GENMASK(2, 0);
128 }
129 }
130
131 /**
132 * ksz_get_apptrust_map_and_reg - Retrieves the apptrust map and register
133 * @dev: Pointer to the KSZ switch device structure
134 * @map: Pointer to the apptrust map to be set
135 * @reg: Pointer to the register address to be set
136 * @mask: Pointer to the mask to be set
137 *
138 * This function retrieves the apptrust map and register address for the
139 * apptrust configuration.
140 */
ksz_get_apptrust_map_and_reg(struct ksz_device * dev,const struct ksz_apptrust_map ** map,int * reg,u8 * mask)141 static void ksz_get_apptrust_map_and_reg(struct ksz_device *dev,
142 const struct ksz_apptrust_map **map,
143 int *reg, u8 *mask)
144 {
145 if (is_ksz8(dev)) {
146 *map = ksz8_apptrust_map_to_bit;
147 *reg = KSZ8_REG_PORT_1_CTRL_0;
148 *mask = KSZ8_PORT_DIFFSERV_ENABLE | KSZ8_PORT_802_1P_ENABLE;
149 } else {
150 *map = ksz9477_apptrust_map_to_bit;
151 *reg = KSZ9477_REG_PORT_MRI_PRIO_CTRL;
152 *mask = KSZ9477_PORT_802_1P_PRIO_ENABLE |
153 KSZ9477_PORT_DIFFSERV_PRIO_ENABLE;
154 }
155 }
156
157 /**
158 * ksz_port_get_default_prio - Retrieves the default priority for a port on a
159 * KSZ switch
160 * @ds: Pointer to the DSA switch structure
161 * @port: Port number from which to get the default priority
162 *
163 * This function fetches the default priority for the specified port on a KSZ
164 * switch.
165 *
166 * Return: The default priority of the port on success, or a negative error
167 * code on failure.
168 */
ksz_port_get_default_prio(struct dsa_switch * ds,int port)169 int ksz_port_get_default_prio(struct dsa_switch *ds, int port)
170 {
171 struct ksz_device *dev = ds->priv;
172 int ret, reg, shift;
173 u8 data, mask;
174
175 ksz_get_default_port_prio_reg(dev, ®, &mask, &shift);
176
177 ret = ksz_pread8(dev, port, reg, &data);
178 if (ret)
179 return ret;
180
181 return (data & mask) >> shift;
182 }
183
184 /**
185 * ksz88x3_port_set_default_prio_quirks - Quirks for default priority
186 * @dev: Pointer to the KSZ switch device structure
187 * @port: Port number for which to set the default priority
188 * @prio: Priority value to set
189 *
190 * This function implements quirks for setting the default priority on KSZ88x3
191 * devices. On Port 2, no other priority providers are working
192 * except of PCP. So, configuring default priority on Port 2 is not possible.
193 * On Port 1, it is not possible to configure port priority if PCP
194 * apptrust on Port 2 is disabled. Since we disable multiple queues on the
195 * switch to disable PCP on Port 2, we need to ensure that the default priority
196 * configuration on Port 1 is in agreement with the configuration on Port 2.
197 *
198 * Return: 0 on success, or a negative error code on failure
199 */
ksz88x3_port_set_default_prio_quirks(struct ksz_device * dev,int port,u8 prio)200 static int ksz88x3_port_set_default_prio_quirks(struct ksz_device *dev, int port,
201 u8 prio)
202 {
203 if (!prio)
204 return 0;
205
206 if (port == KSZ_PORT_2) {
207 dev_err(dev->dev, "Port priority configuration is not working on Port 2\n");
208 return -EINVAL;
209 } else if (port == KSZ_PORT_1) {
210 u8 port2_data;
211 int ret;
212
213 ret = ksz_pread8(dev, KSZ_PORT_2, KSZ8_REG_PORT_1_CTRL_0,
214 &port2_data);
215 if (ret)
216 return ret;
217
218 if (!(port2_data & KSZ8_PORT_802_1P_ENABLE)) {
219 dev_err(dev->dev, "Not possible to configure port priority on Port 1 if PCP apptrust on Port 2 is disabled\n");
220 return -EINVAL;
221 }
222 }
223
224 return 0;
225 }
226
227 /**
228 * ksz_port_set_default_prio - Sets the default priority for a port on a KSZ
229 * switch
230 * @ds: Pointer to the DSA switch structure
231 * @port: Port number for which to set the default priority
232 * @prio: Priority value to set
233 *
234 * This function sets the default priority for the specified port on a KSZ
235 * switch.
236 *
237 * Return: 0 on success, or a negative error code on failure.
238 */
ksz_port_set_default_prio(struct dsa_switch * ds,int port,u8 prio)239 int ksz_port_set_default_prio(struct dsa_switch *ds, int port, u8 prio)
240 {
241 struct ksz_device *dev = ds->priv;
242 int reg, shift, ret;
243 u8 mask;
244
245 if (prio >= dev->info->num_ipms)
246 return -EINVAL;
247
248 if (ksz_is_ksz88x3(dev)) {
249 ret = ksz88x3_port_set_default_prio_quirks(dev, port, prio);
250 if (ret)
251 return ret;
252 }
253
254 ksz_get_default_port_prio_reg(dev, ®, &mask, &shift);
255
256 return ksz_prmw8(dev, port, reg, mask, (prio << shift) & mask);
257 }
258
259 /**
260 * ksz_port_get_dscp_prio - Retrieves the priority for a DSCP value on a KSZ
261 * switch
262 * @ds: Pointer to the DSA switch structure
263 * @port: Port number for which to get the priority
264 * @dscp: DSCP value for which to get the priority
265 *
266 * This function fetches the priority value from switch global DSCP-to-priorty
267 * mapping table for the specified DSCP value.
268 *
269 * Return: The priority value for the DSCP on success, or a negative error
270 * code on failure.
271 */
ksz_port_get_dscp_prio(struct dsa_switch * ds,int port,u8 dscp)272 int ksz_port_get_dscp_prio(struct dsa_switch *ds, int port, u8 dscp)
273 {
274 struct ksz_device *dev = ds->priv;
275 int reg, per_reg, ret, shift;
276 u8 data, mask;
277
278 ksz_get_dscp_prio_reg(dev, ®, &per_reg, &mask);
279
280 /* If DSCP remapping is disabled, DSCP bits 3-5 are used as Internal
281 * Priority Map (IPM)
282 */
283 if (!is_ksz8(dev)) {
284 ret = ksz_read8(dev, KSZ9477_REG_SW_MAC_TOS_CTRL, &data);
285 if (ret)
286 return ret;
287
288 /* If DSCP remapping is disabled, DSCP bits 3-5 are used as
289 * Internal Priority Map (IPM)
290 */
291 if (!(data & KSZ9477_SW_TOS_DSCP_REMAP))
292 return FIELD_GET(KSZ9477_SW_TOS_DSCP_DEFAULT_PRIO_M,
293 dscp);
294 }
295
296 /* In case DSCP remapping is enabled, we need to write the DSCP to
297 * priority mapping table.
298 */
299 reg += dscp / per_reg;
300 ret = ksz_read8(dev, reg, &data);
301 if (ret)
302 return ret;
303
304 shift = (dscp % per_reg) * (8 / per_reg);
305
306 return (data >> shift) & mask;
307 }
308
309 /**
310 * ksz_set_global_dscp_entry - Sets the global DSCP-to-priority mapping entry
311 * @dev: Pointer to the KSZ switch device structure
312 * @dscp: DSCP value for which to set the priority
313 * @ipm: Priority value to set
314 *
315 * This function sets the global DSCP-to-priority mapping entry for the
316 * specified DSCP value.
317 *
318 * Return: 0 on success, or a negative error code on failure.
319 */
ksz_set_global_dscp_entry(struct ksz_device * dev,u8 dscp,u8 ipm)320 static int ksz_set_global_dscp_entry(struct ksz_device *dev, u8 dscp, u8 ipm)
321 {
322 int reg, per_reg, shift;
323 u8 mask;
324
325 ksz_get_dscp_prio_reg(dev, ®, &per_reg, &mask);
326
327 shift = (dscp % per_reg) * (8 / per_reg);
328
329 return ksz_rmw8(dev, reg + (dscp / per_reg), mask << shift,
330 ipm << shift);
331 }
332
333 /**
334 * ksz_init_global_dscp_map - Initializes the global DSCP-to-priority mapping
335 * @dev: Pointer to the KSZ switch device structure
336 *
337 * This function initializes the global DSCP-to-priority mapping table for the
338 * switch.
339 *
340 * Return: 0 on success, or a negative error code on failure
341 */
ksz_init_global_dscp_map(struct ksz_device * dev)342 static int ksz_init_global_dscp_map(struct ksz_device *dev)
343 {
344 int ret, dscp;
345
346 /* On KSZ9xxx variants, DSCP remapping is disabled by default.
347 * Enable to have, predictable and reproducible behavior across
348 * different devices.
349 */
350 if (!is_ksz8(dev)) {
351 ret = ksz_rmw8(dev, KSZ9477_REG_SW_MAC_TOS_CTRL,
352 KSZ9477_SW_TOS_DSCP_REMAP,
353 KSZ9477_SW_TOS_DSCP_REMAP);
354 if (ret)
355 return ret;
356 }
357
358 for (dscp = 0; dscp < DSCP_MAX; dscp++) {
359 int ipm, tt;
360
361 /* Map DSCP to Traffic Type, which is corresponding to the
362 * Internal Priority Map (IPM) in the switch.
363 */
364 if (!is_ksz8(dev)) {
365 ipm = ietf_dscp_to_ieee8021q_tt(dscp);
366 } else {
367 /* On KSZ8xxx variants we do not have IPM to queue
368 * remapping table. We need to convert DSCP to Traffic
369 * Type and then to queue.
370 */
371 tt = ietf_dscp_to_ieee8021q_tt(dscp);
372 if (tt < 0)
373 return tt;
374
375 ipm = ieee8021q_tt_to_tc(tt, dev->info->num_tx_queues);
376 }
377
378 if (ipm < 0)
379 return ipm;
380
381 ret = ksz_set_global_dscp_entry(dev, dscp, ipm);
382 }
383
384 return 0;
385 }
386
387 /**
388 * ksz_port_add_dscp_prio - Adds a DSCP-to-priority mapping entry for a port on
389 * a KSZ switch.
390 * @ds: Pointer to the DSA switch structure
391 * @port: Port number for which to add the DSCP-to-priority mapping entry
392 * @dscp: DSCP value for which to add the priority
393 * @prio: Priority value to set
394 *
395 * Return: 0 on success, or a negative error code on failure
396 */
ksz_port_add_dscp_prio(struct dsa_switch * ds,int port,u8 dscp,u8 prio)397 int ksz_port_add_dscp_prio(struct dsa_switch *ds, int port, u8 dscp, u8 prio)
398 {
399 struct ksz_device *dev = ds->priv;
400
401 if (prio >= dev->info->num_ipms)
402 return -ERANGE;
403
404 return ksz_set_global_dscp_entry(dev, dscp, prio);
405 }
406
407 /**
408 * ksz_port_del_dscp_prio - Deletes a DSCP-to-priority mapping entry for a port
409 * on a KSZ switch.
410 * @ds: Pointer to the DSA switch structure
411 * @port: Port number for which to delete the DSCP-to-priority mapping entry
412 * @dscp: DSCP value for which to delete the priority
413 * @prio: Priority value to delete
414 *
415 * Return: 0 on success, or a negative error code on failure
416 */
ksz_port_del_dscp_prio(struct dsa_switch * ds,int port,u8 dscp,u8 prio)417 int ksz_port_del_dscp_prio(struct dsa_switch *ds, int port, u8 dscp, u8 prio)
418 {
419 struct ksz_device *dev = ds->priv;
420 int ipm;
421
422 if (ksz_port_get_dscp_prio(ds, port, dscp) != prio)
423 return 0;
424
425 if (is_ksz8(dev)) {
426 ipm = ieee8021q_tt_to_tc(IEEE8021Q_TT_BE,
427 dev->info->num_tx_queues);
428 if (ipm < 0)
429 return ipm;
430 } else {
431 ipm = IEEE8021Q_TT_BE;
432 }
433
434 return ksz_set_global_dscp_entry(dev, dscp, ipm);
435 }
436
437 /**
438 * ksz_apptrust_error - Prints an error message for an invalid apptrust selector
439 * @dev: Pointer to the KSZ switch device structure
440 *
441 * This function prints an error message when an invalid apptrust selector is
442 * provided.
443 */
ksz_apptrust_error(struct ksz_device * dev)444 static void ksz_apptrust_error(struct ksz_device *dev)
445 {
446 char supported_apptrust_variants[64];
447 int i;
448
449 supported_apptrust_variants[0] = '\0';
450 for (i = 0; i < ARRAY_SIZE(ksz_supported_apptrust_variants); i++) {
451 if (i > 0)
452 strlcat(supported_apptrust_variants, ", ",
453 sizeof(supported_apptrust_variants));
454 strlcat(supported_apptrust_variants,
455 ksz_supported_apptrust_variants[i],
456 sizeof(supported_apptrust_variants));
457 }
458
459 dev_err(dev->dev, "Invalid apptrust selector or priority order. Supported: %s\n",
460 supported_apptrust_variants);
461 }
462
463 /**
464 * ksz_port_set_apptrust_validate - Validates the apptrust selectors
465 * @dev: Pointer to the KSZ switch device structure
466 * @port: Port number for which to set the apptrust selectors
467 * @sel: Array of apptrust selectors to validate
468 * @nsel: Number of apptrust selectors in the array
469 *
470 * This function validates the apptrust selectors provided and ensures that
471 * they are in the correct order.
472 *
473 * This family of switches supports two apptrust selectors: DCB_APP_SEL_PCP and
474 * IEEE_8021QAZ_APP_SEL_DSCP. The priority order of the selectors is fixed and
475 * cannot be changed. The order is as follows:
476 * 1. DCB_APP_SEL_PCP - Priority Code Point selector (highest priority)
477 * 2. IEEE_8021QAZ_APP_SEL_DSCP - Differentiated Services Code Point selector
478 * (lowest priority)
479 *
480 * Return: 0 on success, or a negative error code on failure
481 */
ksz_port_set_apptrust_validate(struct ksz_device * dev,int port,const u8 * sel,int nsel)482 static int ksz_port_set_apptrust_validate(struct ksz_device *dev, int port,
483 const u8 *sel, int nsel)
484 {
485 int i, j, found;
486 int j_prev = 0;
487
488 /* Iterate through the requested selectors */
489 for (i = 0; i < nsel; i++) {
490 found = 0;
491
492 /* Check if the current selector is supported by the hardware */
493 for (j = 0; j < sizeof(ksz_supported_apptrust); j++) {
494 if (sel[i] != ksz_supported_apptrust[j])
495 continue;
496
497 found = 1;
498
499 /* Ensure that no higher priority selector (lower index)
500 * precedes a lower priority one
501 */
502 if (i > 0 && j <= j_prev)
503 goto err_sel_not_vaild;
504
505 j_prev = j;
506 break;
507 }
508
509 if (!found)
510 goto err_sel_not_vaild;
511 }
512
513 return 0;
514
515 err_sel_not_vaild:
516 ksz_apptrust_error(dev);
517
518 return -EINVAL;
519 }
520
521 /**
522 * ksz88x3_port1_apptrust_quirk - Quirk for apptrust configuration on Port 1
523 * of KSZ88x3 devices
524 * @dev: Pointer to the KSZ switch device structure
525 * @port: Port number for which to set the apptrust selectors
526 * @reg: Register address for the apptrust configuration
527 * @port1_data: Data to set for the apptrust configuration
528 *
529 * This function implements a quirk for apptrust configuration on Port 1 of
530 * KSZ88x3 devices. It ensures that apptrust configuration on Port 1 is not
531 * possible if PCP apptrust on Port 2 is disabled. This is because the Port 2
532 * seems to be permanently hardwired to PCP classification, so we need to
533 * do Port 1 configuration always in agreement with Port 2 configuration.
534 *
535 * Return: 0 on success, or a negative error code on failure
536 */
ksz88x3_port1_apptrust_quirk(struct ksz_device * dev,int port,int reg,u8 port1_data)537 static int ksz88x3_port1_apptrust_quirk(struct ksz_device *dev, int port,
538 int reg, u8 port1_data)
539 {
540 u8 port2_data;
541 int ret;
542
543 /* If no apptrust is requested for Port 1, no need to care about Port 2
544 * configuration.
545 */
546 if (!(port1_data & (KSZ8_PORT_802_1P_ENABLE | KSZ8_PORT_DIFFSERV_ENABLE)))
547 return 0;
548
549 /* We got request to enable any apptrust on Port 1. To make it possible,
550 * we need to enable multiple queues on the switch. If we enable
551 * multiqueue support, PCP classification on Port 2 will be
552 * automatically activated by HW.
553 */
554 ret = ksz_pread8(dev, KSZ_PORT_2, reg, &port2_data);
555 if (ret)
556 return ret;
557
558 /* If KSZ8_PORT_802_1P_ENABLE bit is set on Port 2, the driver showed
559 * the interest in PCP classification on Port 2. In this case,
560 * multiqueue support is enabled and we can enable any apptrust on
561 * Port 1.
562 * If KSZ8_PORT_802_1P_ENABLE bit is not set on Port 2, the PCP
563 * classification on Port 2 is still active, but the driver disabled
564 * multiqueue support and made frame prioritization inactive for
565 * all ports. In this case, we can't enable any apptrust on Port 1.
566 */
567 if (!(port2_data & KSZ8_PORT_802_1P_ENABLE)) {
568 dev_err(dev->dev, "Not possible to enable any apptrust on Port 1 if PCP apptrust on Port 2 is disabled\n");
569 return -EINVAL;
570 }
571
572 return 0;
573 }
574
575 /**
576 * ksz88x3_port2_apptrust_quirk - Quirk for apptrust configuration on Port 2
577 * of KSZ88x3 devices
578 * @dev: Pointer to the KSZ switch device structure
579 * @port: Port number for which to set the apptrust selectors
580 * @reg: Register address for the apptrust configuration
581 * @port2_data: Data to set for the apptrust configuration
582 *
583 * This function implements a quirk for apptrust configuration on Port 2 of
584 * KSZ88x3 devices. It ensures that DSCP apptrust is not working on Port 2 and
585 * that it is not possible to disable PCP on Port 2. The only way to disable PCP
586 * on Port 2 is to disable multiple queues on the switch.
587 *
588 * Return: 0 on success, or a negative error code on failure
589 */
ksz88x3_port2_apptrust_quirk(struct ksz_device * dev,int port,int reg,u8 port2_data)590 static int ksz88x3_port2_apptrust_quirk(struct ksz_device *dev, int port,
591 int reg, u8 port2_data)
592 {
593 struct dsa_switch *ds = dev->ds;
594 u8 port1_data;
595 int ret;
596
597 /* First validate Port 2 configuration. DiffServ/DSCP is not working
598 * on this port.
599 */
600 if (port2_data & KSZ8_PORT_DIFFSERV_ENABLE) {
601 dev_err(dev->dev, "DSCP apptrust is not working on Port 2\n");
602 return -EINVAL;
603 }
604
605 /* If PCP support is requested, we need to enable all queues on the
606 * switch to make PCP priority working on Port 2.
607 */
608 if (port2_data & KSZ8_PORT_802_1P_ENABLE)
609 return ksz8_all_queues_split(dev, dev->info->num_tx_queues);
610
611 /* We got request to disable PCP priority on Port 2.
612 * Now, we need to compare Port 2 configuration with Port 1
613 * configuration.
614 */
615 ret = ksz_pread8(dev, KSZ_PORT_1, reg, &port1_data);
616 if (ret)
617 return ret;
618
619 /* If Port 1 has any apptrust enabled, we can't disable multiple queues
620 * on the switch, so we can't disable PCP on Port 2.
621 */
622 if (port1_data & (KSZ8_PORT_802_1P_ENABLE | KSZ8_PORT_DIFFSERV_ENABLE)) {
623 dev_err(dev->dev, "Not possible to disable PCP on Port 2 if any apptrust is enabled on Port 1\n");
624 return -EINVAL;
625 }
626
627 /* Now we need to ensure that default priority on Port 1 is set to 0
628 * otherwise we can't disable multiqueue support on the switch.
629 */
630 ret = ksz_port_get_default_prio(ds, KSZ_PORT_1);
631 if (ret < 0) {
632 return ret;
633 } else if (ret) {
634 dev_err(dev->dev, "Not possible to disable PCP on Port 2 if non zero default priority is set on Port 1\n");
635 return -EINVAL;
636 }
637
638 /* Port 1 has no apptrust or default priority set and we got request to
639 * disable PCP on Port 2. We can disable multiqueue support to disable
640 * PCP on Port 2.
641 */
642 return ksz8_all_queues_split(dev, 1);
643 }
644
645 /**
646 * ksz88x3_port_apptrust_quirk - Quirk for apptrust configuration on KSZ88x3
647 * devices
648 * @dev: Pointer to the KSZ switch device structure
649 * @port: Port number for which to set the apptrust selectors
650 * @reg: Register address for the apptrust configuration
651 * @data: Data to set for the apptrust configuration
652 *
653 * This function implements a quirk for apptrust configuration on KSZ88x3
654 * devices. It ensures that apptrust configuration on Port 1 and
655 * Port 2 is done in agreement with each other.
656 *
657 * Return: 0 on success, or a negative error code on failure
658 */
ksz88x3_port_apptrust_quirk(struct ksz_device * dev,int port,int reg,u8 data)659 static int ksz88x3_port_apptrust_quirk(struct ksz_device *dev, int port,
660 int reg, u8 data)
661 {
662 if (port == KSZ_PORT_1)
663 return ksz88x3_port1_apptrust_quirk(dev, port, reg, data);
664 else if (port == KSZ_PORT_2)
665 return ksz88x3_port2_apptrust_quirk(dev, port, reg, data);
666
667 return 0;
668 }
669
670 /**
671 * ksz_port_set_apptrust - Sets the apptrust selectors for a port on a KSZ
672 * switch
673 * @ds: Pointer to the DSA switch structure
674 * @port: Port number for which to set the apptrust selectors
675 * @sel: Array of apptrust selectors to set
676 * @nsel: Number of apptrust selectors in the array
677 *
678 * This function sets the apptrust selectors for the specified port on a KSZ
679 * switch.
680 *
681 * Return: 0 on success, or a negative error code on failure
682 */
ksz_port_set_apptrust(struct dsa_switch * ds,int port,const u8 * sel,int nsel)683 int ksz_port_set_apptrust(struct dsa_switch *ds, int port,
684 const u8 *sel, int nsel)
685 {
686 const struct ksz_apptrust_map *map;
687 struct ksz_device *dev = ds->priv;
688 int reg, i, ret;
689 u8 data = 0;
690 u8 mask;
691
692 ret = ksz_port_set_apptrust_validate(dev, port, sel, nsel);
693 if (ret)
694 return ret;
695
696 ksz_get_apptrust_map_and_reg(dev, &map, ®, &mask);
697
698 for (i = 0; i < nsel; i++) {
699 int j;
700
701 for (j = 0; j < ARRAY_SIZE(ksz_supported_apptrust); j++) {
702 if (sel[i] != ksz_supported_apptrust[j])
703 continue;
704
705 data |= map[j].bit;
706 break;
707 }
708 }
709
710 if (ksz_is_ksz88x3(dev)) {
711 ret = ksz88x3_port_apptrust_quirk(dev, port, reg, data);
712 if (ret)
713 return ret;
714 }
715
716 return ksz_prmw8(dev, port, reg, mask, data);
717 }
718
719 /**
720 * ksz_port_get_apptrust - Retrieves the apptrust selectors for a port on a KSZ
721 * switch
722 * @ds: Pointer to the DSA switch structure
723 * @port: Port number for which to get the apptrust selectors
724 * @sel: Array to store the apptrust selectors
725 * @nsel: Number of apptrust selectors in the array
726 *
727 * This function fetches the apptrust selectors for the specified port on a KSZ
728 * switch.
729 *
730 * Return: 0 on success, or a negative error code on failure
731 */
ksz_port_get_apptrust(struct dsa_switch * ds,int port,u8 * sel,int * nsel)732 int ksz_port_get_apptrust(struct dsa_switch *ds, int port, u8 *sel, int *nsel)
733 {
734 const struct ksz_apptrust_map *map;
735 struct ksz_device *dev = ds->priv;
736 int reg, i, ret;
737 u8 data;
738 u8 mask;
739
740 ksz_get_apptrust_map_and_reg(dev, &map, ®, &mask);
741
742 ret = ksz_pread8(dev, port, reg, &data);
743 if (ret)
744 return ret;
745
746 *nsel = 0;
747 for (i = 0; i < ARRAY_SIZE(ksz_supported_apptrust); i++) {
748 if (data & map[i].bit)
749 sel[(*nsel)++] = ksz_supported_apptrust[i];
750 }
751
752 return 0;
753 }
754
755 /**
756 * ksz_dcb_init_port - Initializes the DCB configuration for a port on a KSZ
757 * @dev: Pointer to the KSZ switch device structure
758 * @port: Port number for which to initialize the DCB configuration
759 *
760 * This function initializes the DCB configuration for the specified port on a
761 * KSZ switch. Particular DCB configuration is set for the port, including the
762 * default priority and apptrust selectors.
763 * The default priority is set to Best Effort, and the apptrust selectors are
764 * set to all supported selectors.
765 *
766 * Return: 0 on success, or a negative error code on failure
767 */
ksz_dcb_init_port(struct ksz_device * dev,int port)768 int ksz_dcb_init_port(struct ksz_device *dev, int port)
769 {
770 const u8 ksz_default_apptrust[] = { DCB_APP_SEL_PCP };
771 int ret, ipm;
772
773 if (is_ksz8(dev)) {
774 ipm = ieee8021q_tt_to_tc(IEEE8021Q_TT_BE,
775 dev->info->num_tx_queues);
776 if (ipm < 0)
777 return ipm;
778 } else {
779 ipm = IEEE8021Q_TT_BE;
780 }
781
782 /* Set the default priority for the port to Best Effort */
783 ret = ksz_port_set_default_prio(dev->ds, port, ipm);
784 if (ret)
785 return ret;
786
787 return ksz_port_set_apptrust(dev->ds, port, ksz_default_apptrust,
788 ARRAY_SIZE(ksz_default_apptrust));
789 }
790
791 /**
792 * ksz_dcb_init - Initializes the DCB configuration for a KSZ switch
793 * @dev: Pointer to the KSZ switch device structure
794 *
795 * This function initializes the DCB configuration for a KSZ switch. The global
796 * DSCP-to-priority mapping table is initialized.
797 *
798 * Return: 0 on success, or a negative error code on failure
799 */
ksz_dcb_init(struct ksz_device * dev)800 int ksz_dcb_init(struct ksz_device *dev)
801 {
802 int ret;
803
804 ret = ksz_init_global_dscp_map(dev);
805 if (ret)
806 return ret;
807
808 /* Enable 802.1p priority control on Port 2 during switch initialization.
809 * This setup is critical for the apptrust functionality on Port 1, which
810 * relies on the priority settings of Port 2. Note: Port 1 is naturally
811 * configured before Port 2, necessitating this configuration order.
812 */
813 if (ksz_is_ksz88x3(dev))
814 return ksz_prmw8(dev, KSZ_PORT_2, KSZ8_REG_PORT_1_CTRL_0,
815 KSZ8_PORT_802_1P_ENABLE,
816 KSZ8_PORT_802_1P_ENABLE);
817
818 return 0;
819 }
820