1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2024 Pengutronix, Oleksij Rempel <kernel@pengutronix.de>
4 #include <linux/dsa/ksz_common.h>
7 #include <net/ieee8021q.h>
9 #include "ksz_common.h"
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)
18 #define KSZ88X3_REG_TOS_DSCP_CTRL 0x60
19 #define KSZ8765_REG_TOS_DSCP_CTRL 0x90
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)
25 #define KSZ9477_REG_DIFFSERV_PRIO_MAP 0x0340
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)
36 #define KSZ9477_REG_PORT_MRI_MAC_CTRL 0x0802
37 #define KSZ9477_PORT_BASED_PRIO_M GENMASK(2, 0)
39 struct ksz_apptrust_map
{
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
},
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
},
54 /* ksz_supported_apptrust[] - Supported apptrust selectors and Priority Order
55 * of Internal Priority Map (IPM) sources.
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.
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
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.
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.
77 * DCB_APP_SEL_PCP - Priority Code Point selector
78 * IEEE_8021QAZ_APP_SEL_DSCP - Differentiated Services Code Point selector
80 static const u8 ksz_supported_apptrust
[] = {
82 IEEE_8021QAZ_APP_SEL_DSCP
,
85 static const char * const ksz_supported_apptrust_variants
[] = {
86 "empty", "dscp", "pcp", "dscp pcp"
89 static void ksz_get_default_port_prio_reg(struct ksz_device
*dev
, int *reg
,
93 *reg
= KSZ8_REG_PORT_1_CTRL_0
;
94 *mask
= KSZ8_PORT_BASED_PRIO_M
;
95 *shift
= __bf_shf(KSZ8_PORT_BASED_PRIO_M
);
97 *reg
= KSZ9477_REG_PORT_MRI_MAC_CTRL
;
98 *mask
= KSZ9477_PORT_BASED_PRIO_M
;
99 *shift
= __bf_shf(KSZ9477_PORT_BASED_PRIO_M
);
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
110 * This function retrieves the DSCP to priority mapping register, the number of
111 * DSCP values per register, and the mask to be set.
113 static void ksz_get_dscp_prio_reg(struct ksz_device
*dev
, int *reg
,
114 int *per_reg
, u8
*mask
)
116 if (ksz_is_ksz87xx(dev
) || ksz_is_8895_family(dev
)) {
117 *reg
= KSZ8765_REG_TOS_DSCP_CTRL
;
119 *mask
= GENMASK(1, 0);
120 } else if (ksz_is_ksz88x3(dev
)) {
121 *reg
= KSZ88X3_REG_TOS_DSCP_CTRL
;
123 *mask
= GENMASK(1, 0);
125 *reg
= KSZ9477_REG_DIFFSERV_PRIO_MAP
;
127 *mask
= GENMASK(2, 0);
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
138 * This function retrieves the apptrust map and register address for the
139 * apptrust configuration.
141 static void ksz_get_apptrust_map_and_reg(struct ksz_device
*dev
,
142 const struct ksz_apptrust_map
**map
,
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
;
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
;
158 * ksz_port_get_default_prio - Retrieves the default priority for a port on a
160 * @ds: Pointer to the DSA switch structure
161 * @port: Port number from which to get the default priority
163 * This function fetches the default priority for the specified port on a KSZ
166 * Return: The default priority of the port on success, or a negative error
169 int ksz_port_get_default_prio(struct dsa_switch
*ds
, int port
)
171 struct ksz_device
*dev
= ds
->priv
;
175 ksz_get_default_port_prio_reg(dev
, ®
, &mask
, &shift
);
177 ret
= ksz_pread8(dev
, port
, reg
, &data
);
181 return (data
& mask
) >> shift
;
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
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.
198 * Return: 0 on success, or a negative error code on failure
200 static int ksz88x3_port_set_default_prio_quirks(struct ksz_device
*dev
, int port
,
206 if (port
== KSZ_PORT_2
) {
207 dev_err(dev
->dev
, "Port priority configuration is not working on Port 2\n");
209 } else if (port
== KSZ_PORT_1
) {
213 ret
= ksz_pread8(dev
, KSZ_PORT_2
, KSZ8_REG_PORT_1_CTRL_0
,
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");
228 * ksz_port_set_default_prio - Sets the default priority for a port on a KSZ
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
234 * This function sets the default priority for the specified port on a KSZ
237 * Return: 0 on success, or a negative error code on failure.
239 int ksz_port_set_default_prio(struct dsa_switch
*ds
, int port
, u8 prio
)
241 struct ksz_device
*dev
= ds
->priv
;
245 if (prio
>= dev
->info
->num_ipms
)
248 if (ksz_is_ksz88x3(dev
)) {
249 ret
= ksz88x3_port_set_default_prio_quirks(dev
, port
, prio
);
254 ksz_get_default_port_prio_reg(dev
, ®
, &mask
, &shift
);
256 return ksz_prmw8(dev
, port
, reg
, mask
, (prio
<< shift
) & mask
);
260 * ksz_port_get_dscp_prio - Retrieves the priority for a DSCP value on a KSZ
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
266 * This function fetches the priority value from switch global DSCP-to-priorty
267 * mapping table for the specified DSCP value.
269 * Return: The priority value for the DSCP on success, or a negative error
272 int ksz_port_get_dscp_prio(struct dsa_switch
*ds
, int port
, u8 dscp
)
274 struct ksz_device
*dev
= ds
->priv
;
275 int reg
, per_reg
, ret
, shift
;
278 ksz_get_dscp_prio_reg(dev
, ®
, &per_reg
, &mask
);
280 /* If DSCP remapping is disabled, DSCP bits 3-5 are used as Internal
284 ret
= ksz_read8(dev
, KSZ9477_REG_SW_MAC_TOS_CTRL
, &data
);
288 /* If DSCP remapping is disabled, DSCP bits 3-5 are used as
289 * Internal Priority Map (IPM)
291 if (!(data
& KSZ9477_SW_TOS_DSCP_REMAP
))
292 return FIELD_GET(KSZ9477_SW_TOS_DSCP_DEFAULT_PRIO_M
,
296 /* In case DSCP remapping is enabled, we need to write the DSCP to
297 * priority mapping table.
299 reg
+= dscp
/ per_reg
;
300 ret
= ksz_read8(dev
, reg
, &data
);
304 shift
= (dscp
% per_reg
) * (8 / per_reg
);
306 return (data
>> shift
) & mask
;
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
315 * This function sets the global DSCP-to-priority mapping entry for the
316 * specified DSCP value.
318 * Return: 0 on success, or a negative error code on failure.
320 static int ksz_set_global_dscp_entry(struct ksz_device
*dev
, u8 dscp
, u8 ipm
)
322 int reg
, per_reg
, shift
;
325 ksz_get_dscp_prio_reg(dev
, ®
, &per_reg
, &mask
);
327 shift
= (dscp
% per_reg
) * (8 / per_reg
);
329 return ksz_rmw8(dev
, reg
+ (dscp
/ per_reg
), mask
<< shift
,
334 * ksz_init_global_dscp_map - Initializes the global DSCP-to-priority mapping
335 * @dev: Pointer to the KSZ switch device structure
337 * This function initializes the global DSCP-to-priority mapping table for the
340 * Return: 0 on success, or a negative error code on failure
342 static int ksz_init_global_dscp_map(struct ksz_device
*dev
)
346 /* On KSZ9xxx variants, DSCP remapping is disabled by default.
347 * Enable to have, predictable and reproducible behavior across
351 ret
= ksz_rmw8(dev
, KSZ9477_REG_SW_MAC_TOS_CTRL
,
352 KSZ9477_SW_TOS_DSCP_REMAP
,
353 KSZ9477_SW_TOS_DSCP_REMAP
);
358 for (dscp
= 0; dscp
< DSCP_MAX
; dscp
++) {
361 /* Map DSCP to Traffic Type, which is corresponding to the
362 * Internal Priority Map (IPM) in the switch.
365 ipm
= ietf_dscp_to_ieee8021q_tt(dscp
);
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.
371 tt
= ietf_dscp_to_ieee8021q_tt(dscp
);
375 ipm
= ieee8021q_tt_to_tc(tt
, dev
->info
->num_tx_queues
);
381 ret
= ksz_set_global_dscp_entry(dev
, dscp
, ipm
);
388 * ksz_port_add_dscp_prio - Adds a DSCP-to-priority mapping entry for a port on
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
395 * Return: 0 on success, or a negative error code on failure
397 int ksz_port_add_dscp_prio(struct dsa_switch
*ds
, int port
, u8 dscp
, u8 prio
)
399 struct ksz_device
*dev
= ds
->priv
;
401 if (prio
>= dev
->info
->num_ipms
)
404 return ksz_set_global_dscp_entry(dev
, dscp
, prio
);
408 * ksz_port_del_dscp_prio - Deletes a DSCP-to-priority mapping entry for a port
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
415 * Return: 0 on success, or a negative error code on failure
417 int ksz_port_del_dscp_prio(struct dsa_switch
*ds
, int port
, u8 dscp
, u8 prio
)
419 struct ksz_device
*dev
= ds
->priv
;
422 if (ksz_port_get_dscp_prio(ds
, port
, dscp
) != prio
)
426 ipm
= ieee8021q_tt_to_tc(IEEE8021Q_TT_BE
,
427 dev
->info
->num_tx_queues
);
431 ipm
= IEEE8021Q_TT_BE
;
434 return ksz_set_global_dscp_entry(dev
, dscp
, ipm
);
438 * ksz_apptrust_error - Prints an error message for an invalid apptrust selector
439 * @dev: Pointer to the KSZ switch device structure
441 * This function prints an error message when an invalid apptrust selector is
444 static void ksz_apptrust_error(struct ksz_device
*dev
)
446 char supported_apptrust_variants
[64];
449 supported_apptrust_variants
[0] = '\0';
450 for (i
= 0; i
< ARRAY_SIZE(ksz_supported_apptrust_variants
); i
++) {
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
));
459 dev_err(dev
->dev
, "Invalid apptrust selector or priority order. Supported: %s\n",
460 supported_apptrust_variants
);
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
470 * This function validates the apptrust selectors provided and ensures that
471 * they are in the correct order.
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
480 * Return: 0 on success, or a negative error code on failure
482 static int ksz_port_set_apptrust_validate(struct ksz_device
*dev
, int port
,
483 const u8
*sel
, int nsel
)
488 /* Iterate through the requested selectors */
489 for (i
= 0; i
< nsel
; i
++) {
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
])
499 /* Ensure that no higher priority selector (lower index)
500 * precedes a lower priority one
502 if (i
> 0 && j
<= j_prev
)
503 goto err_sel_not_vaild
;
510 goto err_sel_not_vaild
;
516 ksz_apptrust_error(dev
);
522 * ksz88x3_port1_apptrust_quirk - Quirk for apptrust configuration on Port 1
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
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.
535 * Return: 0 on success, or a negative error code on failure
537 static int ksz88x3_port1_apptrust_quirk(struct ksz_device
*dev
, int port
,
538 int reg
, u8 port1_data
)
543 /* If no apptrust is requested for Port 1, no need to care about Port 2
546 if (!(port1_data
& (KSZ8_PORT_802_1P_ENABLE
| KSZ8_PORT_DIFFSERV_ENABLE
)))
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.
554 ret
= ksz_pread8(dev
, KSZ_PORT_2
, reg
, &port2_data
);
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
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.
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");
576 * ksz88x3_port2_apptrust_quirk - Quirk for apptrust configuration on Port 2
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
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.
588 * Return: 0 on success, or a negative error code on failure
590 static int ksz88x3_port2_apptrust_quirk(struct ksz_device
*dev
, int port
,
591 int reg
, u8 port2_data
)
593 struct dsa_switch
*ds
= dev
->ds
;
597 /* First validate Port 2 configuration. DiffServ/DSCP is not working
600 if (port2_data
& KSZ8_PORT_DIFFSERV_ENABLE
) {
601 dev_err(dev
->dev
, "DSCP apptrust is not working on Port 2\n");
605 /* If PCP support is requested, we need to enable all queues on the
606 * switch to make PCP priority working on Port 2.
608 if (port2_data
& KSZ8_PORT_802_1P_ENABLE
)
609 return ksz8_all_queues_split(dev
, dev
->info
->num_tx_queues
);
611 /* We got request to disable PCP priority on Port 2.
612 * Now, we need to compare Port 2 configuration with Port 1
615 ret
= ksz_pread8(dev
, KSZ_PORT_1
, reg
, &port1_data
);
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.
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");
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.
630 ret
= ksz_port_get_default_prio(ds
, KSZ_PORT_1
);
634 dev_err(dev
->dev
, "Not possible to disable PCP on Port 2 if non zero default priority is set on Port 1\n");
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
642 return ksz8_all_queues_split(dev
, 1);
646 * ksz88x3_port_apptrust_quirk - Quirk for apptrust configuration on KSZ88x3
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
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.
657 * Return: 0 on success, or a negative error code on failure
659 static int ksz88x3_port_apptrust_quirk(struct ksz_device
*dev
, int port
,
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
);
671 * ksz_port_set_apptrust - Sets the apptrust selectors for a port on a KSZ
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
678 * This function sets the apptrust selectors for the specified port on a KSZ
681 * Return: 0 on success, or a negative error code on failure
683 int ksz_port_set_apptrust(struct dsa_switch
*ds
, int port
,
684 const u8
*sel
, int nsel
)
686 const struct ksz_apptrust_map
*map
;
687 struct ksz_device
*dev
= ds
->priv
;
692 ret
= ksz_port_set_apptrust_validate(dev
, port
, sel
, nsel
);
696 ksz_get_apptrust_map_and_reg(dev
, &map
, ®
, &mask
);
698 for (i
= 0; i
< nsel
; i
++) {
701 for (j
= 0; j
< ARRAY_SIZE(ksz_supported_apptrust
); j
++) {
702 if (sel
[i
] != ksz_supported_apptrust
[j
])
710 if (ksz_is_ksz88x3(dev
)) {
711 ret
= ksz88x3_port_apptrust_quirk(dev
, port
, reg
, data
);
716 return ksz_prmw8(dev
, port
, reg
, mask
, data
);
720 * ksz_port_get_apptrust - Retrieves the apptrust selectors for a port on a KSZ
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
727 * This function fetches the apptrust selectors for the specified port on a KSZ
730 * Return: 0 on success, or a negative error code on failure
732 int ksz_port_get_apptrust(struct dsa_switch
*ds
, int port
, u8
*sel
, int *nsel
)
734 const struct ksz_apptrust_map
*map
;
735 struct ksz_device
*dev
= ds
->priv
;
740 ksz_get_apptrust_map_and_reg(dev
, &map
, ®
, &mask
);
742 ret
= ksz_pread8(dev
, port
, reg
, &data
);
747 for (i
= 0; i
< ARRAY_SIZE(ksz_supported_apptrust
); i
++) {
748 if (data
& map
[i
].bit
)
749 sel
[(*nsel
)++] = ksz_supported_apptrust
[i
];
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
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.
766 * Return: 0 on success, or a negative error code on failure
768 int ksz_dcb_init_port(struct ksz_device
*dev
, int port
)
770 const u8 ksz_default_apptrust
[] = { DCB_APP_SEL_PCP
};
774 ipm
= ieee8021q_tt_to_tc(IEEE8021Q_TT_BE
,
775 dev
->info
->num_tx_queues
);
779 ipm
= IEEE8021Q_TT_BE
;
782 /* Set the default priority for the port to Best Effort */
783 ret
= ksz_port_set_default_prio(dev
->ds
, port
, ipm
);
787 return ksz_port_set_apptrust(dev
->ds
, port
, ksz_default_apptrust
,
788 ARRAY_SIZE(ksz_default_apptrust
));
792 * ksz_dcb_init - Initializes the DCB configuration for a KSZ switch
793 * @dev: Pointer to the KSZ switch device structure
795 * This function initializes the DCB configuration for a KSZ switch. The global
796 * DSCP-to-priority mapping table is initialized.
798 * Return: 0 on success, or a negative error code on failure
800 int ksz_dcb_init(struct ksz_device
*dev
)
804 ret
= ksz_init_global_dscp_map(dev
);
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.
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
);