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