linux/drivers/net/dsa/microchip/ksz_dcb.c

// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2024 Pengutronix, Oleksij Rempel <[email protected]>

#include <linux/dsa/ksz_common.h>
#include <net/dsa.h>
#include <net/dscp.h>
#include <net/ieee8021q.h>

#include "ksz_common.h"
#include "ksz_dcb.h"
#include "ksz8.h"

#define KSZ8_REG_PORT_1_CTRL_0
#define KSZ8_PORT_DIFFSERV_ENABLE
#define KSZ8_PORT_802_1P_ENABLE
#define KSZ8_PORT_BASED_PRIO_M

#define KSZ88X3_REG_TOS_DSCP_CTRL
#define KSZ8765_REG_TOS_DSCP_CTRL

#define KSZ9477_REG_SW_MAC_TOS_CTRL
#define KSZ9477_SW_TOS_DSCP_REMAP
#define KSZ9477_SW_TOS_DSCP_DEFAULT_PRIO_M

#define KSZ9477_REG_DIFFSERV_PRIO_MAP

#define KSZ9477_REG_PORT_MRI_PRIO_CTRL
#define KSZ9477_PORT_HIGHEST_PRIO
#define KSZ9477_PORT_OR_PRIO
#define KSZ9477_PORT_MAC_PRIO_ENABLE
#define KSZ9477_PORT_VLAN_PRIO_ENABLE
#define KSZ9477_PORT_802_1P_PRIO_ENABLE
#define KSZ9477_PORT_DIFFSERV_PRIO_ENABLE
#define KSZ9477_PORT_ACL_PRIO_ENABLE

#define KSZ9477_REG_PORT_MRI_MAC_CTRL
#define KSZ9477_PORT_BASED_PRIO_M

struct ksz_apptrust_map {};

static const struct ksz_apptrust_map ksz8_apptrust_map_to_bit[] =;

static const struct ksz_apptrust_map ksz9477_apptrust_map_to_bit[] =;

/* ksz_supported_apptrust[] - Supported apptrust selectors and Priority Order
 *			      of Internal Priority Map (IPM) sources.
 *
 * This array defines the apptrust selectors supported by the hardware, where
 * the index within the array indicates the priority of the selector - lower
 * indices correspond to higher priority. This fixed priority scheme is due to
 * the hardware's design, which does not support configurable priority among
 * different priority sources.
 *
 * The priority sources, including Tail Tag, ACL, VLAN PCP and DSCP are ordered
 * by the hardware's fixed logic, as detailed below. The order reflects a
 * non-configurable precedence where certain types of priority information
 * override others:
 *
 * 1. Tail Tag - Highest priority, overrides ACL, VLAN PCP, and DSCP priorities.
 * 2. ACL - Overrides VLAN PCP and DSCP priorities.
 * 3. VLAN PCP - Overrides DSCP priority.
 * 4. DSCP - Lowest priority, does not override any other priority source.
 *
 * In this context, the array's lower index (higher priority) for
 * 'DCB_APP_SEL_PCP' suggests its relative priority over
 * 'IEEE_8021QAZ_APP_SEL_DSCP' within the system's fixed priority scheme.
 *
 * DCB_APP_SEL_PCP - Priority Code Point selector
 * IEEE_8021QAZ_APP_SEL_DSCP - Differentiated Services Code Point selector
 */
static const u8 ksz_supported_apptrust[] =;

static const char * const ksz_supported_apptrust_variants[] =;

static void ksz_get_default_port_prio_reg(struct ksz_device *dev, int *reg,
					  u8 *mask, int *shift)
{}

/**
 * ksz_get_dscp_prio_reg - Retrieves the DSCP-to-priority-mapping register
 * @dev: Pointer to the KSZ switch device structure
 * @reg: Pointer to the register address to be set
 * @per_reg: Pointer to the number of DSCP values per register
 * @mask: Pointer to the mask to be set
 *
 * This function retrieves the DSCP to priority mapping register, the number of
 * DSCP values per register, and the mask to be set.
 */
static void ksz_get_dscp_prio_reg(struct ksz_device *dev, int *reg,
				  int *per_reg, u8 *mask)
{}

/**
 * ksz_get_apptrust_map_and_reg - Retrieves the apptrust map and register
 * @dev: Pointer to the KSZ switch device structure
 * @map: Pointer to the apptrust map to be set
 * @reg: Pointer to the register address to be set
 * @mask: Pointer to the mask to be set
 *
 * This function retrieves the apptrust map and register address for the
 * apptrust configuration.
 */
static void ksz_get_apptrust_map_and_reg(struct ksz_device *dev,
					 const struct ksz_apptrust_map **map,
					 int *reg, u8 *mask)
{}

/**
 * ksz_port_get_default_prio - Retrieves the default priority for a port on a
 *			       KSZ switch
 * @ds: Pointer to the DSA switch structure
 * @port: Port number from which to get the default priority
 *
 * This function fetches the default priority for the specified port on a KSZ
 * switch.
 *
 * Return: The default priority of the port on success, or a negative error
 * code on failure.
 */
int ksz_port_get_default_prio(struct dsa_switch *ds, int port)
{}

/**
 * ksz88x3_port_set_default_prio_quirks - Quirks for default priority
 * @dev: Pointer to the KSZ switch device structure
 * @port: Port number for which to set the default priority
 * @prio: Priority value to set
 *
 * This function implements quirks for setting the default priority on KSZ88x3
 * devices. On Port 2, no other priority providers are working
 * except of PCP. So, configuring default priority on Port 2 is not possible.
 * On Port 1, it is not possible to configure port priority if PCP
 * apptrust on Port 2 is disabled. Since we disable multiple queues on the
 * switch to disable PCP on Port 2, we need to ensure that the default priority
 * configuration on Port 1 is in agreement with the configuration on Port 2.
 *
 * Return: 0 on success, or a negative error code on failure
 */
static int ksz88x3_port_set_default_prio_quirks(struct ksz_device *dev, int port,
						u8 prio)
{}

/**
 * ksz_port_set_default_prio - Sets the default priority for a port on a KSZ
 *			       switch
 * @ds: Pointer to the DSA switch structure
 * @port: Port number for which to set the default priority
 * @prio: Priority value to set
 *
 * This function sets the default priority for the specified port on a KSZ
 * switch.
 *
 * Return: 0 on success, or a negative error code on failure.
 */
int ksz_port_set_default_prio(struct dsa_switch *ds, int port, u8 prio)
{}

/**
 * ksz_port_get_dscp_prio - Retrieves the priority for a DSCP value on a KSZ
 *			    switch
 * @ds: Pointer to the DSA switch structure
 * @port: Port number for which to get the priority
 * @dscp: DSCP value for which to get the priority
 *
 * This function fetches the priority value from switch global DSCP-to-priorty
 * mapping table for the specified DSCP value.
 *
 * Return: The priority value for the DSCP on success, or a negative error
 * code on failure.
 */
int ksz_port_get_dscp_prio(struct dsa_switch *ds, int port, u8 dscp)
{}

/**
 * ksz_set_global_dscp_entry - Sets the global DSCP-to-priority mapping entry
 * @dev: Pointer to the KSZ switch device structure
 * @dscp: DSCP value for which to set the priority
 * @ipm: Priority value to set
 *
 * This function sets the global DSCP-to-priority mapping entry for the
 * specified DSCP value.
 *
 * Return: 0 on success, or a negative error code on failure.
 */
static int ksz_set_global_dscp_entry(struct ksz_device *dev, u8 dscp, u8 ipm)
{}

/**
 * ksz_init_global_dscp_map - Initializes the global DSCP-to-priority mapping
 * @dev: Pointer to the KSZ switch device structure
 *
 * This function initializes the global DSCP-to-priority mapping table for the
 * switch.
 *
 * Return: 0 on success, or a negative error code on failure
 */
static int ksz_init_global_dscp_map(struct ksz_device *dev)
{}

/**
 * ksz_port_add_dscp_prio - Adds a DSCP-to-priority mapping entry for a port on
 *			    a KSZ switch.
 * @ds: Pointer to the DSA switch structure
 * @port: Port number for which to add the DSCP-to-priority mapping entry
 * @dscp: DSCP value for which to add the priority
 * @prio: Priority value to set
 *
 * Return: 0 on success, or a negative error code on failure
 */
int ksz_port_add_dscp_prio(struct dsa_switch *ds, int port, u8 dscp, u8 prio)
{}

/**
 * ksz_port_del_dscp_prio - Deletes a DSCP-to-priority mapping entry for a port
 *			    on a KSZ switch.
 * @ds: Pointer to the DSA switch structure
 * @port: Port number for which to delete the DSCP-to-priority mapping entry
 * @dscp: DSCP value for which to delete the priority
 * @prio: Priority value to delete
 *
 * Return: 0 on success, or a negative error code on failure
 */
int ksz_port_del_dscp_prio(struct dsa_switch *ds, int port, u8 dscp, u8 prio)
{}

/**
 * ksz_apptrust_error - Prints an error message for an invalid apptrust selector
 * @dev: Pointer to the KSZ switch device structure
 *
 * This function prints an error message when an invalid apptrust selector is
 * provided.
 */
static void ksz_apptrust_error(struct ksz_device *dev)
{}

/**
 * ksz_port_set_apptrust_validate - Validates the apptrust selectors
 * @dev: Pointer to the KSZ switch device structure
 * @port: Port number for which to set the apptrust selectors
 * @sel: Array of apptrust selectors to validate
 * @nsel: Number of apptrust selectors in the array
 *
 * This function validates the apptrust selectors provided and ensures that
 * they are in the correct order.
 *
 * This family of switches supports two apptrust selectors: DCB_APP_SEL_PCP and
 * IEEE_8021QAZ_APP_SEL_DSCP. The priority order of the selectors is fixed and
 * cannot be changed. The order is as follows:
 * 1. DCB_APP_SEL_PCP - Priority Code Point selector (highest priority)
 * 2. IEEE_8021QAZ_APP_SEL_DSCP - Differentiated Services Code Point selector
 *   (lowest priority)
 *
 * Return: 0 on success, or a negative error code on failure
 */
static int ksz_port_set_apptrust_validate(struct ksz_device *dev, int port,
					  const u8 *sel, int nsel)
{}

/**
 * ksz88x3_port1_apptrust_quirk - Quirk for apptrust configuration on Port 1
 *				  of KSZ88x3 devices
 * @dev: Pointer to the KSZ switch device structure
 * @port: Port number for which to set the apptrust selectors
 * @reg: Register address for the apptrust configuration
 * @port1_data: Data to set for the apptrust configuration
 *
 * This function implements a quirk for apptrust configuration on Port 1 of
 * KSZ88x3 devices. It ensures that apptrust configuration on Port 1 is not
 * possible if PCP apptrust on Port 2 is disabled. This is because the Port 2
 * seems to be permanently hardwired to PCP classification, so we need to
 * do Port 1 configuration always in agreement with Port 2 configuration.
 *
 * Return: 0 on success, or a negative error code on failure
 */
static int ksz88x3_port1_apptrust_quirk(struct ksz_device *dev, int port,
					int reg, u8 port1_data)
{}

/**
 * ksz88x3_port2_apptrust_quirk - Quirk for apptrust configuration on Port 2
 *				  of KSZ88x3 devices
 * @dev: Pointer to the KSZ switch device structure
 * @port: Port number for which to set the apptrust selectors
 * @reg: Register address for the apptrust configuration
 * @port2_data: Data to set for the apptrust configuration
 *
 * This function implements a quirk for apptrust configuration on Port 2 of
 * KSZ88x3 devices. It ensures that DSCP apptrust is not working on Port 2 and
 * that it is not possible to disable PCP on Port 2. The only way to disable PCP
 * on Port 2 is to disable multiple queues on the switch.
 *
 * Return: 0 on success, or a negative error code on failure
 */
static int ksz88x3_port2_apptrust_quirk(struct ksz_device *dev, int port,
					int reg, u8 port2_data)
{}

/**
 * ksz88x3_port_apptrust_quirk - Quirk for apptrust configuration on KSZ88x3
 *			       devices
 * @dev: Pointer to the KSZ switch device structure
 * @port: Port number for which to set the apptrust selectors
 * @reg: Register address for the apptrust configuration
 * @data: Data to set for the apptrust configuration
 *
 * This function implements a quirk for apptrust configuration on KSZ88x3
 * devices. It ensures that apptrust configuration on Port 1 and
 * Port 2 is done in agreement with each other.
 *
 * Return: 0 on success, or a negative error code on failure
 */
static int ksz88x3_port_apptrust_quirk(struct ksz_device *dev, int port,
				       int reg, u8 data)
{}

/**
 * ksz_port_set_apptrust - Sets the apptrust selectors for a port on a KSZ
 *			   switch
 * @ds: Pointer to the DSA switch structure
 * @port: Port number for which to set the apptrust selectors
 * @sel: Array of apptrust selectors to set
 * @nsel: Number of apptrust selectors in the array
 *
 * This function sets the apptrust selectors for the specified port on a KSZ
 * switch.
 *
 * Return: 0 on success, or a negative error code on failure
 */
int ksz_port_set_apptrust(struct dsa_switch *ds, int port,
			  const u8 *sel, int nsel)
{}

/**
 * ksz_port_get_apptrust - Retrieves the apptrust selectors for a port on a KSZ
 *			   switch
 * @ds: Pointer to the DSA switch structure
 * @port: Port number for which to get the apptrust selectors
 * @sel: Array to store the apptrust selectors
 * @nsel: Number of apptrust selectors in the array
 *
 * This function fetches the apptrust selectors for the specified port on a KSZ
 * switch.
 *
 * Return: 0 on success, or a negative error code on failure
 */
int ksz_port_get_apptrust(struct dsa_switch *ds, int port, u8 *sel, int *nsel)
{}

/**
 * ksz_dcb_init_port - Initializes the DCB configuration for a port on a KSZ
 * @dev: Pointer to the KSZ switch device structure
 * @port: Port number for which to initialize the DCB configuration
 *
 * This function initializes the DCB configuration for the specified port on a
 * KSZ switch. Particular DCB configuration is set for the port, including the
 * default priority and apptrust selectors.
 * The default priority is set to Best Effort, and the apptrust selectors are
 * set to all supported selectors.
 *
 * Return: 0 on success, or a negative error code on failure
 */
int ksz_dcb_init_port(struct ksz_device *dev, int port)
{}

/**
 * ksz_dcb_init - Initializes the DCB configuration for a KSZ switch
 * @dev: Pointer to the KSZ switch device structure
 *
 * This function initializes the DCB configuration for a KSZ switch. The global
 * DSCP-to-priority mapping table is initialized.
 *
 * Return: 0 on success, or a negative error code on failure
 */
int ksz_dcb_init(struct ksz_device *dev)
{}