xref: /linux/drivers/net/dsa/microchip/ksz_dcb.c (revision 2d7eaeb05ae265bd64270376e6a2c0d80244771f)
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 /* Port X Control 0 register.
14  * The datasheet specifies: Port 1 - 0x10, Port 2 - 0x20, Port 3 - 0x30.
15  * However, the driver uses get_port_addr(), which maps Port 1 to offset 0.
16  * Therefore, we define the base offset as 0x00 here to align with that logic.
17  */
18 #define KSZ8_REG_PORT_1_CTRL_0			0x00
19 #define KSZ8463_REG_PORT_1_CTRL_0		0x6C
20 #define KSZ8_PORT_DIFFSERV_ENABLE		BIT(6)
21 #define KSZ8_PORT_802_1P_ENABLE			BIT(5)
22 #define KSZ8_PORT_BASED_PRIO_M			GENMASK(4, 3)
23 #define KSZ8995XA_PORT_BASED_PRIO		BIT(4)
24 
25 #define KSZ8463_REG_TOS_DSCP_CTRL		0x16
26 #define KSZ88X3_REG_TOS_DSCP_CTRL		0x60
27 #define KSZ8765_REG_TOS_DSCP_CTRL		0x90
28 #define KSZ8995XA_REG_TOS_DSCP_CTRL_7		0x67
29 
30 #define KSZ9477_REG_SW_MAC_TOS_CTRL		0x033e
31 #define KSZ9477_SW_TOS_DSCP_REMAP		BIT(0)
32 #define KSZ9477_SW_TOS_DSCP_DEFAULT_PRIO_M	GENMASK(5, 3)
33 
34 #define KSZ9477_REG_DIFFSERV_PRIO_MAP		0x0340
35 
36 #define KSZ9477_REG_PORT_MRI_PRIO_CTRL		0x0801
37 #define KSZ9477_PORT_HIGHEST_PRIO		BIT(7)
38 #define KSZ9477_PORT_OR_PRIO			BIT(6)
39 #define KSZ9477_PORT_MAC_PRIO_ENABLE		BIT(4)
40 #define KSZ9477_PORT_VLAN_PRIO_ENABLE		BIT(3)
41 #define KSZ9477_PORT_802_1P_PRIO_ENABLE		BIT(2)
42 #define KSZ9477_PORT_DIFFSERV_PRIO_ENABLE	BIT(1)
43 #define KSZ9477_PORT_ACL_PRIO_ENABLE		BIT(0)
44 
45 #define KSZ9477_REG_PORT_MRI_MAC_CTRL		0x0802
46 #define KSZ9477_PORT_BASED_PRIO_M		GENMASK(2, 0)
47 
48 struct ksz_apptrust_map {
49 	u8 apptrust;
50 	u8 bit;
51 };
52 
53 static const struct ksz_apptrust_map ksz8_apptrust_map_to_bit[] = {
54 	{ DCB_APP_SEL_PCP, KSZ8_PORT_802_1P_ENABLE },
55 	{ IEEE_8021QAZ_APP_SEL_DSCP, KSZ8_PORT_DIFFSERV_ENABLE },
56 };
57 
58 static const struct ksz_apptrust_map ksz9477_apptrust_map_to_bit[] = {
59 	{ DCB_APP_SEL_PCP, KSZ9477_PORT_802_1P_PRIO_ENABLE },
60 	{ IEEE_8021QAZ_APP_SEL_DSCP, KSZ9477_PORT_DIFFSERV_PRIO_ENABLE },
61 };
62 
63 /* ksz_supported_apptrust[] - Supported apptrust selectors and Priority Order
64  *			      of Internal Priority Map (IPM) sources.
65  *
66  * This array defines the apptrust selectors supported by the hardware, where
67  * the index within the array indicates the priority of the selector - lower
68  * indices correspond to higher priority. This fixed priority scheme is due to
69  * the hardware's design, which does not support configurable priority among
70  * different priority sources.
71  *
72  * The priority sources, including Tail Tag, ACL, VLAN PCP and DSCP are ordered
73  * by the hardware's fixed logic, as detailed below. The order reflects a
74  * non-configurable precedence where certain types of priority information
75  * override others:
76  *
77  * 1. Tail Tag - Highest priority, overrides ACL, VLAN PCP, and DSCP priorities.
78  * 2. ACL - Overrides VLAN PCP and DSCP priorities.
79  * 3. VLAN PCP - Overrides DSCP priority.
80  * 4. DSCP - Lowest priority, does not override any other priority source.
81  *
82  * In this context, the array's lower index (higher priority) for
83  * 'DCB_APP_SEL_PCP' suggests its relative priority over
84  * 'IEEE_8021QAZ_APP_SEL_DSCP' within the system's fixed priority scheme.
85  *
86  * DCB_APP_SEL_PCP - Priority Code Point selector
87  * IEEE_8021QAZ_APP_SEL_DSCP - Differentiated Services Code Point selector
88  */
89 static const u8 ksz_supported_apptrust[] = {
90 	DCB_APP_SEL_PCP,
91 	IEEE_8021QAZ_APP_SEL_DSCP,
92 };
93 
94 static const char * const ksz_supported_apptrust_variants[] = {
95 	"empty", "dscp", "pcp", "dscp pcp"
96 };
97 
98 static void ksz_get_default_port_prio_reg(struct ksz_device *dev, int *reg,
99 					  u8 *mask, int *shift)
100 {
101 	if (is_ksz8(dev)) {
102 		*reg = KSZ8_REG_PORT_1_CTRL_0;
103 		if (ksz_is_ksz8995xa(dev))
104 			*mask = KSZ8995XA_PORT_BASED_PRIO;
105 		else
106 			*mask = KSZ8_PORT_BASED_PRIO_M;
107 		*shift = __bf_shf(*mask);
108 		if (ksz_is_ksz8463(dev))
109 			*reg = KSZ8463_REG_PORT_1_CTRL_0;
110 	} else {
111 		*reg = KSZ9477_REG_PORT_MRI_MAC_CTRL;
112 		*mask = KSZ9477_PORT_BASED_PRIO_M;
113 		*shift = __bf_shf(KSZ9477_PORT_BASED_PRIO_M);
114 	}
115 }
116 
117 /**
118  * ksz_get_dscp_prio_reg - Retrieves the DSCP-to-priority-mapping register
119  * @dev: Pointer to the KSZ switch device structure
120  * @dscp: DSCP value for which to retrieve the register
121  * @reg: Pointer to the register address to be set
122  * @mask: Pointer to the mask to be set
123  * @shift: Pointer to the bit shift to be set
124  *
125  * This function retrieves the register, mask and shift for a DSCP to priority
126  * mapping entry.
127  */
128 static void ksz_get_dscp_prio_reg(struct ksz_device *dev, u8 dscp, int *reg,
129 				  u8 *mask, int *shift)
130 {
131 	int per_reg;
132 
133 	if (ksz_is_ksz8995xa(dev)) {
134 		/* KSZ8995XA stores DSCP groups in descending register order. */
135 		*reg = KSZ8995XA_REG_TOS_DSCP_CTRL_7 - dscp / 8;
136 		*mask = BIT(0);
137 		*shift = dscp % 8;
138 		return;
139 	}
140 
141 	if (ksz_is_ksz87xx(dev) || ksz_is_8895_family(dev)) {
142 		*reg = KSZ8765_REG_TOS_DSCP_CTRL;
143 		per_reg = 4;
144 		*mask = GENMASK(1, 0);
145 	} else if (ksz_is_ksz88x3(dev) || ksz_is_ksz8463(dev)) {
146 		*reg = KSZ88X3_REG_TOS_DSCP_CTRL;
147 		per_reg = 4;
148 		*mask = GENMASK(1, 0);
149 		if (ksz_is_ksz8463(dev))
150 			*reg = KSZ8463_REG_TOS_DSCP_CTRL;
151 	} else {
152 		*reg = KSZ9477_REG_DIFFSERV_PRIO_MAP;
153 		per_reg = 2;
154 		*mask = GENMASK(2, 0);
155 	}
156 
157 	*reg += dscp / per_reg;
158 	*shift = (dscp % per_reg) * (8 / per_reg);
159 }
160 
161 /**
162  * ksz_get_apptrust_map_and_reg - Retrieves the apptrust map and register
163  * @dev: Pointer to the KSZ switch device structure
164  * @map: Pointer to the apptrust map to be set
165  * @reg: Pointer to the register address to be set
166  * @mask: Pointer to the mask to be set
167  *
168  * This function retrieves the apptrust map and register address for the
169  * apptrust configuration.
170  */
171 static void ksz_get_apptrust_map_and_reg(struct ksz_device *dev,
172 					 const struct ksz_apptrust_map **map,
173 					 int *reg, u8 *mask)
174 {
175 	if (is_ksz8(dev)) {
176 		*map = ksz8_apptrust_map_to_bit;
177 		*reg = KSZ8_REG_PORT_1_CTRL_0;
178 		*mask = KSZ8_PORT_DIFFSERV_ENABLE | KSZ8_PORT_802_1P_ENABLE;
179 		if (ksz_is_ksz8463(dev))
180 			*reg = KSZ8463_REG_PORT_1_CTRL_0;
181 	} else {
182 		*map = ksz9477_apptrust_map_to_bit;
183 		*reg = KSZ9477_REG_PORT_MRI_PRIO_CTRL;
184 		*mask = KSZ9477_PORT_802_1P_PRIO_ENABLE |
185 			KSZ9477_PORT_DIFFSERV_PRIO_ENABLE;
186 	}
187 }
188 
189 /**
190  * ksz_port_get_default_prio - Retrieves the default priority for a port on a
191  *			       KSZ switch
192  * @ds: Pointer to the DSA switch structure
193  * @port: Port number from which to get the default priority
194  *
195  * This function fetches the default priority for the specified port on a KSZ
196  * switch.
197  *
198  * Return: The default priority of the port on success, or a negative error
199  * code on failure.
200  */
201 int ksz_port_get_default_prio(struct dsa_switch *ds, int port)
202 {
203 	struct ksz_device *dev = ds->priv;
204 	int ret, reg, shift;
205 	u8 data, mask;
206 
207 	ksz_get_default_port_prio_reg(dev, &reg, &mask, &shift);
208 
209 	ret = ksz_pread8(dev, port, reg, &data);
210 	if (ret)
211 		return ret;
212 
213 	return (data & mask) >> shift;
214 }
215 
216 /**
217  * ksz_port_set_default_prio - Sets the default priority for a port on a KSZ
218  *			       switch
219  * @ds: Pointer to the DSA switch structure
220  * @port: Port number for which to set the default priority
221  * @prio: Priority value to set
222  *
223  * This function sets the default priority for the specified port on a KSZ
224  * switch.
225  *
226  * Return: 0 on success, or a negative error code on failure.
227  */
228 int ksz_port_set_default_prio(struct dsa_switch *ds, int port, u8 prio)
229 {
230 	struct ksz_device *dev = ds->priv;
231 	int reg, shift;
232 	u8 mask;
233 
234 	if (prio >= dev->info->num_ipms)
235 		return -EINVAL;
236 
237 	ksz_get_default_port_prio_reg(dev, &reg, &mask, &shift);
238 
239 	return ksz_prmw8(dev, port, reg, mask, (prio << shift) & mask);
240 }
241 
242 /**
243  * ksz_port_get_dscp_prio - Retrieves the priority for a DSCP value on a KSZ
244  *			    switch
245  * @ds: Pointer to the DSA switch structure
246  * @port: Port number for which to get the priority
247  * @dscp: DSCP value for which to get the priority
248  *
249  * This function fetches the priority value from switch global DSCP-to-priorty
250  * mapping table for the specified DSCP value.
251  *
252  * Return: The priority value for the DSCP on success, or a negative error
253  * code on failure.
254  */
255 int ksz_port_get_dscp_prio(struct dsa_switch *ds, int port, u8 dscp)
256 {
257 	struct ksz_device *dev = ds->priv;
258 	int reg, ret, shift;
259 	u8 data, mask;
260 
261 	ksz_get_dscp_prio_reg(dev, dscp, &reg, &mask, &shift);
262 
263 	/* If DSCP remapping is disabled, DSCP bits 3-5 are used as Internal
264 	 * Priority Map (IPM)
265 	 */
266 	if (!is_ksz8(dev)) {
267 		ret = ksz_read8(dev, KSZ9477_REG_SW_MAC_TOS_CTRL, &data);
268 		if (ret)
269 			return ret;
270 
271 		/* If DSCP remapping is disabled, DSCP bits 3-5 are used as
272 		 * Internal Priority Map (IPM)
273 		 */
274 		if (!(data & KSZ9477_SW_TOS_DSCP_REMAP))
275 			return FIELD_GET(KSZ9477_SW_TOS_DSCP_DEFAULT_PRIO_M,
276 					 dscp);
277 	}
278 
279 	/* In case DSCP remapping is enabled, we need to write the DSCP to
280 	 * priority mapping table.
281 	 */
282 	ret = ksz_read8(dev, reg, &data);
283 	if (ret)
284 		return ret;
285 
286 	return (data >> shift) & mask;
287 }
288 
289 /**
290  * ksz_set_global_dscp_entry - Sets the global DSCP-to-priority mapping entry
291  * @dev: Pointer to the KSZ switch device structure
292  * @dscp: DSCP value for which to set the priority
293  * @ipm: Priority value to set
294  *
295  * This function sets the global DSCP-to-priority mapping entry for the
296  * specified DSCP value.
297  *
298  * Return: 0 on success, or a negative error code on failure.
299  */
300 static int ksz_set_global_dscp_entry(struct ksz_device *dev, u8 dscp, u8 ipm)
301 {
302 	int reg, shift;
303 	u8 mask;
304 
305 	ksz_get_dscp_prio_reg(dev, dscp, &reg, &mask, &shift);
306 
307 	return ksz_rmw8(dev, reg, mask << shift, ipm << shift);
308 }
309 
310 /**
311  * ksz_init_global_dscp_map - Initializes the global DSCP-to-priority mapping
312  * @dev: Pointer to the KSZ switch device structure
313  *
314  * This function initializes the global DSCP-to-priority mapping table for the
315  * switch.
316  *
317  * Return: 0 on success, or a negative error code on failure
318  */
319 static int ksz_init_global_dscp_map(struct ksz_device *dev)
320 {
321 	int ret, dscp;
322 
323 	/* On KSZ9xxx variants, DSCP remapping is disabled by default.
324 	 * Enable to have, predictable and reproducible behavior across
325 	 * different devices.
326 	 */
327 	if (!is_ksz8(dev)) {
328 		ret = ksz_rmw8(dev, KSZ9477_REG_SW_MAC_TOS_CTRL,
329 			       KSZ9477_SW_TOS_DSCP_REMAP,
330 			       KSZ9477_SW_TOS_DSCP_REMAP);
331 		if (ret)
332 			return ret;
333 	}
334 
335 	for (dscp = 0; dscp < DSCP_MAX; dscp++) {
336 		int ipm, tt;
337 
338 		/* Map DSCP to Traffic Type, which is corresponding to the
339 		 * Internal Priority Map (IPM) in the switch.
340 		 */
341 		if (!is_ksz8(dev)) {
342 			ipm = ietf_dscp_to_ieee8021q_tt(dscp);
343 		} else {
344 			/* On KSZ8xxx variants we do not have IPM to queue
345 			 * remapping table. We need to convert DSCP to Traffic
346 			 * Type and then to queue.
347 			 */
348 			tt = ietf_dscp_to_ieee8021q_tt(dscp);
349 			if (tt < 0)
350 				return tt;
351 
352 			ipm = ieee8021q_tt_to_tc(tt, dev->info->num_tx_queues);
353 		}
354 
355 		if (ipm < 0)
356 			return ipm;
357 
358 		ret = ksz_set_global_dscp_entry(dev, dscp, ipm);
359 	}
360 
361 	return 0;
362 }
363 
364 /**
365  * ksz_port_add_dscp_prio - Adds a DSCP-to-priority mapping entry for a port on
366  *			    a KSZ switch.
367  * @ds: Pointer to the DSA switch structure
368  * @port: Port number for which to add the DSCP-to-priority mapping entry
369  * @dscp: DSCP value for which to add the priority
370  * @prio: Priority value to set
371  *
372  * Return: 0 on success, or a negative error code on failure
373  */
374 int ksz_port_add_dscp_prio(struct dsa_switch *ds, int port, u8 dscp, u8 prio)
375 {
376 	struct ksz_device *dev = ds->priv;
377 
378 	if (prio >= dev->info->num_ipms)
379 		return -ERANGE;
380 
381 	return ksz_set_global_dscp_entry(dev, dscp, prio);
382 }
383 
384 /**
385  * ksz_port_del_dscp_prio - Deletes a DSCP-to-priority mapping entry for a port
386  *			    on a KSZ switch.
387  * @ds: Pointer to the DSA switch structure
388  * @port: Port number for which to delete the DSCP-to-priority mapping entry
389  * @dscp: DSCP value for which to delete the priority
390  * @prio: Priority value to delete
391  *
392  * Return: 0 on success, or a negative error code on failure
393  */
394 int ksz_port_del_dscp_prio(struct dsa_switch *ds, int port, u8 dscp, u8 prio)
395 {
396 	struct ksz_device *dev = ds->priv;
397 	int ipm;
398 
399 	if (ksz_port_get_dscp_prio(ds, port, dscp) != prio)
400 		return 0;
401 
402 	if (is_ksz8(dev)) {
403 		ipm = ieee8021q_tt_to_tc(IEEE8021Q_TT_BE,
404 					 dev->info->num_tx_queues);
405 		if (ipm < 0)
406 			return ipm;
407 	} else {
408 		ipm = IEEE8021Q_TT_BE;
409 	}
410 
411 	return ksz_set_global_dscp_entry(dev, dscp, ipm);
412 }
413 
414 /**
415  * ksz_apptrust_error - Prints an error message for an invalid apptrust selector
416  * @dev: Pointer to the KSZ switch device structure
417  *
418  * This function prints an error message when an invalid apptrust selector is
419  * provided.
420  */
421 static void ksz_apptrust_error(struct ksz_device *dev)
422 {
423 	char supported_apptrust_variants[64];
424 	int i;
425 
426 	supported_apptrust_variants[0] = '\0';
427 	for (i = 0; i < ARRAY_SIZE(ksz_supported_apptrust_variants); i++) {
428 		if (i > 0)
429 			strlcat(supported_apptrust_variants, ", ",
430 				sizeof(supported_apptrust_variants));
431 		strlcat(supported_apptrust_variants,
432 			ksz_supported_apptrust_variants[i],
433 			sizeof(supported_apptrust_variants));
434 	}
435 
436 	dev_err(dev->dev, "Invalid apptrust selector or priority order. Supported: %s\n",
437 		supported_apptrust_variants);
438 }
439 
440 /**
441  * ksz_port_set_apptrust_validate - Validates the apptrust selectors
442  * @dev: Pointer to the KSZ switch device structure
443  * @port: Port number for which to set the apptrust selectors
444  * @sel: Array of apptrust selectors to validate
445  * @nsel: Number of apptrust selectors in the array
446  *
447  * This function validates the apptrust selectors provided and ensures that
448  * they are in the correct order.
449  *
450  * This family of switches supports two apptrust selectors: DCB_APP_SEL_PCP and
451  * IEEE_8021QAZ_APP_SEL_DSCP. The priority order of the selectors is fixed and
452  * cannot be changed. The order is as follows:
453  * 1. DCB_APP_SEL_PCP - Priority Code Point selector (highest priority)
454  * 2. IEEE_8021QAZ_APP_SEL_DSCP - Differentiated Services Code Point selector
455  *   (lowest priority)
456  *
457  * KSZ8995XA instead ORs the classification results, so it supports only
458  * one trusted selector at a time.
459  *
460  * Return: 0 on success, or a negative error code on failure
461  */
462 static int ksz_port_set_apptrust_validate(struct ksz_device *dev, int port,
463 					  const u8 *sel, int nsel)
464 {
465 	int i, j, found;
466 	int j_prev = 0;
467 
468 	if (ksz_is_ksz8995xa(dev) && nsel > 1) {
469 		dev_err(dev->dev,
470 			"KSZ8995XA supports only one apptrust selector at a time\n");
471 		return -EOPNOTSUPP;
472 	}
473 
474 	/* Iterate through the requested selectors */
475 	for (i = 0; i < nsel; i++) {
476 		found = 0;
477 
478 		/* Check if the current selector is supported by the hardware */
479 		for (j = 0; j < sizeof(ksz_supported_apptrust); j++) {
480 			if (sel[i] != ksz_supported_apptrust[j])
481 				continue;
482 
483 			found = 1;
484 
485 			/* Ensure that no higher priority selector (lower index)
486 			 * precedes a lower priority one
487 			 */
488 			if (i > 0 && j <= j_prev)
489 				goto err_sel_not_vaild;
490 
491 			j_prev = j;
492 			break;
493 		}
494 
495 		if (!found)
496 			goto err_sel_not_vaild;
497 	}
498 
499 	return 0;
500 
501 err_sel_not_vaild:
502 	ksz_apptrust_error(dev);
503 
504 	return -EINVAL;
505 }
506 
507 /**
508  * ksz_port_set_apptrust - Sets the apptrust selectors for a port on a KSZ
509  *			   switch
510  * @ds: Pointer to the DSA switch structure
511  * @port: Port number for which to set the apptrust selectors
512  * @sel: Array of apptrust selectors to set
513  * @nsel: Number of apptrust selectors in the array
514  *
515  * This function sets the apptrust selectors for the specified port on a KSZ
516  * switch.
517  *
518  * Return: 0 on success, or a negative error code on failure
519  */
520 int ksz_port_set_apptrust(struct dsa_switch *ds, int port,
521 			  const u8 *sel, int nsel)
522 {
523 	const struct ksz_apptrust_map *map;
524 	struct ksz_device *dev = ds->priv;
525 	int reg, i, ret;
526 	u8 data = 0;
527 	u8 mask;
528 
529 	ret = ksz_port_set_apptrust_validate(dev, port, sel, nsel);
530 	if (ret)
531 		return ret;
532 
533 	ksz_get_apptrust_map_and_reg(dev, &map, &reg, &mask);
534 
535 	for (i = 0; i < nsel; i++) {
536 		int j;
537 
538 		for (j = 0; j < ARRAY_SIZE(ksz_supported_apptrust); j++) {
539 			if (sel[i] != ksz_supported_apptrust[j])
540 				continue;
541 
542 			data |= map[j].bit;
543 			break;
544 		}
545 	}
546 
547 	return ksz_prmw8(dev, port, reg, mask, data);
548 }
549 
550 /**
551  * ksz_port_get_apptrust - Retrieves the apptrust selectors for a port on a KSZ
552  *			   switch
553  * @ds: Pointer to the DSA switch structure
554  * @port: Port number for which to get the apptrust selectors
555  * @sel: Array to store the apptrust selectors
556  * @nsel: Number of apptrust selectors in the array
557  *
558  * This function fetches the apptrust selectors for the specified port on a KSZ
559  * switch.
560  *
561  * Return: 0 on success, or a negative error code on failure
562  */
563 int ksz_port_get_apptrust(struct dsa_switch *ds, int port, u8 *sel, int *nsel)
564 {
565 	const struct ksz_apptrust_map *map;
566 	struct ksz_device *dev = ds->priv;
567 	int reg, i, ret;
568 	u8 data;
569 	u8 mask;
570 
571 	ksz_get_apptrust_map_and_reg(dev, &map, &reg, &mask);
572 
573 	ret = ksz_pread8(dev, port, reg, &data);
574 	if (ret)
575 		return ret;
576 
577 	/* XA's combined classification cannot be reported as a trust order. */
578 	if (ksz_is_ksz8995xa(dev) && (data & mask) == mask)
579 		return -EOPNOTSUPP;
580 
581 	*nsel = 0;
582 	for (i = 0; i < ARRAY_SIZE(ksz_supported_apptrust); i++) {
583 		if (data & map[i].bit)
584 			sel[(*nsel)++] = ksz_supported_apptrust[i];
585 	}
586 
587 	return 0;
588 }
589 
590 /**
591  * ksz_dcb_init_port - Initializes the DCB configuration for a port on a KSZ
592  * @dev: Pointer to the KSZ switch device structure
593  * @port: Port number for which to initialize the DCB configuration
594  *
595  * This function initializes the DCB configuration for the specified port on a
596  * KSZ switch. Particular DCB configuration is set for the port, including the
597  * default priority and apptrust selectors.
598  * The default priority is set to Best Effort, and the apptrust selectors are
599  * set to all supported selectors.
600  *
601  * Return: 0 on success, or a negative error code on failure
602  */
603 int ksz_dcb_init_port(struct ksz_device *dev, int port)
604 {
605 	const u8 ksz_default_apptrust[] = { DCB_APP_SEL_PCP };
606 	int ret, ipm;
607 
608 	if (is_ksz8(dev)) {
609 		ipm = ieee8021q_tt_to_tc(IEEE8021Q_TT_BE,
610 					 dev->info->num_tx_queues);
611 		if (ipm < 0)
612 			return ipm;
613 	} else {
614 		ipm = IEEE8021Q_TT_BE;
615 	}
616 
617 	/* Set the default priority for the port to Best Effort */
618 	ret = ksz_port_set_default_prio(dev->ds, port, ipm);
619 	if (ret)
620 		return ret;
621 
622 	return ksz_port_set_apptrust(dev->ds, port, ksz_default_apptrust,
623 				     ARRAY_SIZE(ksz_default_apptrust));
624 }
625 
626 /**
627  * ksz_dcb_init - Initializes the DCB configuration for a KSZ switch
628  * @dev: Pointer to the KSZ switch device structure
629  *
630  * This function initializes the DCB configuration for a KSZ switch. The global
631  * DSCP-to-priority mapping table is initialized.
632  *
633  * Return: 0 on success, or a negative error code on failure
634  */
635 int ksz_dcb_init(struct ksz_device *dev)
636 {
637 	return ksz_init_global_dscp_map(dev);
638 }
639