162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+ 262306a36Sopenharmony_ci/* Microchip Sparx5 Switch driver 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Copyright (c) 2022 Microchip Technology Inc. and its subsidiaries. 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#include <net/dcbnl.h> 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include "sparx5_port.h" 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_cienum sparx5_dcb_apptrust_values { 1262306a36Sopenharmony_ci SPARX5_DCB_APPTRUST_EMPTY, 1362306a36Sopenharmony_ci SPARX5_DCB_APPTRUST_DSCP, 1462306a36Sopenharmony_ci SPARX5_DCB_APPTRUST_PCP, 1562306a36Sopenharmony_ci SPARX5_DCB_APPTRUST_DSCP_PCP, 1662306a36Sopenharmony_ci __SPARX5_DCB_APPTRUST_MAX 1762306a36Sopenharmony_ci}; 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_cistatic const struct sparx5_dcb_apptrust { 2062306a36Sopenharmony_ci u8 selectors[IEEE_8021QAZ_APP_SEL_MAX + 1]; 2162306a36Sopenharmony_ci int nselectors; 2262306a36Sopenharmony_ci} *sparx5_port_apptrust[SPX5_PORTS]; 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_cistatic const char *sparx5_dcb_apptrust_names[__SPARX5_DCB_APPTRUST_MAX] = { 2562306a36Sopenharmony_ci [SPARX5_DCB_APPTRUST_EMPTY] = "empty", 2662306a36Sopenharmony_ci [SPARX5_DCB_APPTRUST_DSCP] = "dscp", 2762306a36Sopenharmony_ci [SPARX5_DCB_APPTRUST_PCP] = "pcp", 2862306a36Sopenharmony_ci [SPARX5_DCB_APPTRUST_DSCP_PCP] = "dscp pcp" 2962306a36Sopenharmony_ci}; 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci/* Sparx5 supported apptrust policies */ 3262306a36Sopenharmony_cistatic const struct sparx5_dcb_apptrust 3362306a36Sopenharmony_ci sparx5_dcb_apptrust_policies[__SPARX5_DCB_APPTRUST_MAX] = { 3462306a36Sopenharmony_ci /* Empty *must* be first */ 3562306a36Sopenharmony_ci [SPARX5_DCB_APPTRUST_EMPTY] = { { 0 }, 0 }, 3662306a36Sopenharmony_ci [SPARX5_DCB_APPTRUST_DSCP] = { { IEEE_8021QAZ_APP_SEL_DSCP }, 1 }, 3762306a36Sopenharmony_ci [SPARX5_DCB_APPTRUST_PCP] = { { DCB_APP_SEL_PCP }, 1 }, 3862306a36Sopenharmony_ci [SPARX5_DCB_APPTRUST_DSCP_PCP] = { { IEEE_8021QAZ_APP_SEL_DSCP, 3962306a36Sopenharmony_ci DCB_APP_SEL_PCP }, 2 }, 4062306a36Sopenharmony_ci}; 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci/* Validate app entry. 4362306a36Sopenharmony_ci * 4462306a36Sopenharmony_ci * Check for valid selectors and valid protocol and priority ranges. 4562306a36Sopenharmony_ci */ 4662306a36Sopenharmony_cistatic int sparx5_dcb_app_validate(struct net_device *dev, 4762306a36Sopenharmony_ci const struct dcb_app *app) 4862306a36Sopenharmony_ci{ 4962306a36Sopenharmony_ci int err = 0; 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci switch (app->selector) { 5262306a36Sopenharmony_ci /* Default priority checks */ 5362306a36Sopenharmony_ci case IEEE_8021QAZ_APP_SEL_ETHERTYPE: 5462306a36Sopenharmony_ci if (app->protocol != 0) 5562306a36Sopenharmony_ci err = -EINVAL; 5662306a36Sopenharmony_ci else if (app->priority >= SPX5_PRIOS) 5762306a36Sopenharmony_ci err = -ERANGE; 5862306a36Sopenharmony_ci break; 5962306a36Sopenharmony_ci /* Dscp checks */ 6062306a36Sopenharmony_ci case IEEE_8021QAZ_APP_SEL_DSCP: 6162306a36Sopenharmony_ci if (app->protocol >= SPARX5_PORT_QOS_DSCP_COUNT) 6262306a36Sopenharmony_ci err = -EINVAL; 6362306a36Sopenharmony_ci else if (app->priority >= SPX5_PRIOS) 6462306a36Sopenharmony_ci err = -ERANGE; 6562306a36Sopenharmony_ci break; 6662306a36Sopenharmony_ci /* Pcp checks */ 6762306a36Sopenharmony_ci case DCB_APP_SEL_PCP: 6862306a36Sopenharmony_ci if (app->protocol >= SPARX5_PORT_QOS_PCP_DEI_COUNT) 6962306a36Sopenharmony_ci err = -EINVAL; 7062306a36Sopenharmony_ci else if (app->priority >= SPX5_PRIOS) 7162306a36Sopenharmony_ci err = -ERANGE; 7262306a36Sopenharmony_ci break; 7362306a36Sopenharmony_ci default: 7462306a36Sopenharmony_ci err = -EINVAL; 7562306a36Sopenharmony_ci break; 7662306a36Sopenharmony_ci } 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci if (err) 7962306a36Sopenharmony_ci netdev_err(dev, "Invalid entry: %d:%d\n", app->protocol, 8062306a36Sopenharmony_ci app->priority); 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci return err; 8362306a36Sopenharmony_ci} 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci/* Validate apptrust configuration. 8662306a36Sopenharmony_ci * 8762306a36Sopenharmony_ci * Return index of supported apptrust configuration if valid, otherwise return 8862306a36Sopenharmony_ci * error. 8962306a36Sopenharmony_ci */ 9062306a36Sopenharmony_cistatic int sparx5_dcb_apptrust_validate(struct net_device *dev, u8 *selectors, 9162306a36Sopenharmony_ci int nselectors, int *err) 9262306a36Sopenharmony_ci{ 9362306a36Sopenharmony_ci bool match = false; 9462306a36Sopenharmony_ci int i, ii; 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(sparx5_dcb_apptrust_policies); i++) { 9762306a36Sopenharmony_ci if (sparx5_dcb_apptrust_policies[i].nselectors != nselectors) 9862306a36Sopenharmony_ci continue; 9962306a36Sopenharmony_ci match = true; 10062306a36Sopenharmony_ci for (ii = 0; ii < nselectors; ii++) { 10162306a36Sopenharmony_ci if (sparx5_dcb_apptrust_policies[i].selectors[ii] != 10262306a36Sopenharmony_ci *(selectors + ii)) { 10362306a36Sopenharmony_ci match = false; 10462306a36Sopenharmony_ci break; 10562306a36Sopenharmony_ci } 10662306a36Sopenharmony_ci } 10762306a36Sopenharmony_ci if (match) 10862306a36Sopenharmony_ci break; 10962306a36Sopenharmony_ci } 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci /* Requested trust configuration is not supported */ 11262306a36Sopenharmony_ci if (!match) { 11362306a36Sopenharmony_ci netdev_err(dev, "Valid apptrust configurations are:\n"); 11462306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(sparx5_dcb_apptrust_names); i++) 11562306a36Sopenharmony_ci pr_info("order: %s\n", sparx5_dcb_apptrust_names[i]); 11662306a36Sopenharmony_ci *err = -EOPNOTSUPP; 11762306a36Sopenharmony_ci } 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci return i; 12062306a36Sopenharmony_ci} 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_cistatic bool sparx5_dcb_apptrust_contains(int portno, u8 selector) 12362306a36Sopenharmony_ci{ 12462306a36Sopenharmony_ci const struct sparx5_dcb_apptrust *conf = sparx5_port_apptrust[portno]; 12562306a36Sopenharmony_ci int i; 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci for (i = 0; i < conf->nselectors; i++) 12862306a36Sopenharmony_ci if (conf->selectors[i] == selector) 12962306a36Sopenharmony_ci return true; 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci return false; 13262306a36Sopenharmony_ci} 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_cistatic int sparx5_dcb_app_update(struct net_device *dev) 13562306a36Sopenharmony_ci{ 13662306a36Sopenharmony_ci struct dcb_ieee_app_prio_map dscp_rewr_map = {0}; 13762306a36Sopenharmony_ci struct dcb_rewr_prio_pcp_map pcp_rewr_map = {0}; 13862306a36Sopenharmony_ci struct sparx5_port *port = netdev_priv(dev); 13962306a36Sopenharmony_ci struct sparx5_port_qos_dscp_map *dscp_map; 14062306a36Sopenharmony_ci struct sparx5_port_qos_pcp_map *pcp_map; 14162306a36Sopenharmony_ci struct sparx5_port_qos qos = {0}; 14262306a36Sopenharmony_ci struct dcb_app app_itr = {0}; 14362306a36Sopenharmony_ci int portno = port->portno; 14462306a36Sopenharmony_ci bool dscp_rewr = false; 14562306a36Sopenharmony_ci bool pcp_rewr = false; 14662306a36Sopenharmony_ci u16 dscp; 14762306a36Sopenharmony_ci int i; 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci dscp_map = &qos.dscp.map; 15062306a36Sopenharmony_ci pcp_map = &qos.pcp.map; 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci /* Get default prio. */ 15362306a36Sopenharmony_ci qos.default_prio = dcb_ieee_getapp_default_prio_mask(dev); 15462306a36Sopenharmony_ci if (qos.default_prio) 15562306a36Sopenharmony_ci qos.default_prio = fls(qos.default_prio) - 1; 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci /* Get dscp ingress mapping */ 15862306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(dscp_map->map); i++) { 15962306a36Sopenharmony_ci app_itr.selector = IEEE_8021QAZ_APP_SEL_DSCP; 16062306a36Sopenharmony_ci app_itr.protocol = i; 16162306a36Sopenharmony_ci dscp_map->map[i] = dcb_getapp(dev, &app_itr); 16262306a36Sopenharmony_ci } 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci /* Get pcp ingress mapping */ 16562306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(pcp_map->map); i++) { 16662306a36Sopenharmony_ci app_itr.selector = DCB_APP_SEL_PCP; 16762306a36Sopenharmony_ci app_itr.protocol = i; 16862306a36Sopenharmony_ci pcp_map->map[i] = dcb_getapp(dev, &app_itr); 16962306a36Sopenharmony_ci } 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci /* Get pcp rewrite mapping */ 17262306a36Sopenharmony_ci dcb_getrewr_prio_pcp_mask_map(dev, &pcp_rewr_map); 17362306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(pcp_rewr_map.map); i++) { 17462306a36Sopenharmony_ci if (!pcp_rewr_map.map[i]) 17562306a36Sopenharmony_ci continue; 17662306a36Sopenharmony_ci pcp_rewr = true; 17762306a36Sopenharmony_ci qos.pcp_rewr.map.map[i] = fls(pcp_rewr_map.map[i]) - 1; 17862306a36Sopenharmony_ci } 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_ci /* Get dscp rewrite mapping */ 18162306a36Sopenharmony_ci dcb_getrewr_prio_dscp_mask_map(dev, &dscp_rewr_map); 18262306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(dscp_rewr_map.map); i++) { 18362306a36Sopenharmony_ci if (!dscp_rewr_map.map[i]) 18462306a36Sopenharmony_ci continue; 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci /* The rewrite table of the switch has 32 entries; one for each 18762306a36Sopenharmony_ci * priority for each DP level. Currently, the rewrite map does 18862306a36Sopenharmony_ci * not indicate DP level, so we map classified QoS class to 18962306a36Sopenharmony_ci * classified DSCP, for each classified DP level. Rewrite of 19062306a36Sopenharmony_ci * DSCP is only enabled, if we have active mappings. 19162306a36Sopenharmony_ci */ 19262306a36Sopenharmony_ci dscp_rewr = true; 19362306a36Sopenharmony_ci dscp = fls64(dscp_rewr_map.map[i]) - 1; 19462306a36Sopenharmony_ci qos.dscp_rewr.map.map[i] = dscp; /* DP 0 */ 19562306a36Sopenharmony_ci qos.dscp_rewr.map.map[i + 8] = dscp; /* DP 1 */ 19662306a36Sopenharmony_ci qos.dscp_rewr.map.map[i + 16] = dscp; /* DP 2 */ 19762306a36Sopenharmony_ci qos.dscp_rewr.map.map[i + 24] = dscp; /* DP 3 */ 19862306a36Sopenharmony_ci } 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci /* Enable use of pcp for queue classification ? */ 20162306a36Sopenharmony_ci if (sparx5_dcb_apptrust_contains(portno, DCB_APP_SEL_PCP)) { 20262306a36Sopenharmony_ci qos.pcp.qos_enable = true; 20362306a36Sopenharmony_ci qos.pcp.dp_enable = qos.pcp.qos_enable; 20462306a36Sopenharmony_ci /* Enable rewrite of PCP and DEI if PCP is trusted *and* rewrite 20562306a36Sopenharmony_ci * table is not empty. 20662306a36Sopenharmony_ci */ 20762306a36Sopenharmony_ci if (pcp_rewr) 20862306a36Sopenharmony_ci qos.pcp_rewr.enable = true; 20962306a36Sopenharmony_ci } 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ci /* Enable use of dscp for queue classification ? */ 21262306a36Sopenharmony_ci if (sparx5_dcb_apptrust_contains(portno, IEEE_8021QAZ_APP_SEL_DSCP)) { 21362306a36Sopenharmony_ci qos.dscp.qos_enable = true; 21462306a36Sopenharmony_ci qos.dscp.dp_enable = qos.dscp.qos_enable; 21562306a36Sopenharmony_ci if (dscp_rewr) 21662306a36Sopenharmony_ci /* Do not enable rewrite if no mappings are active, as 21762306a36Sopenharmony_ci * classified DSCP will then be zero for all classified 21862306a36Sopenharmony_ci * QoS class and DP combinations. 21962306a36Sopenharmony_ci */ 22062306a36Sopenharmony_ci qos.dscp_rewr.enable = true; 22162306a36Sopenharmony_ci } 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_ci return sparx5_port_qos_set(port, &qos); 22462306a36Sopenharmony_ci} 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ci/* Set or delete DSCP app entry. 22762306a36Sopenharmony_ci * 22862306a36Sopenharmony_ci * DSCP mapping is global for all ports, so set and delete app entries are 22962306a36Sopenharmony_ci * replicated for each port. 23062306a36Sopenharmony_ci */ 23162306a36Sopenharmony_cistatic int sparx5_dcb_ieee_dscp_setdel(struct net_device *dev, 23262306a36Sopenharmony_ci struct dcb_app *app, 23362306a36Sopenharmony_ci int (*setdel)(struct net_device *, 23462306a36Sopenharmony_ci struct dcb_app *)) 23562306a36Sopenharmony_ci{ 23662306a36Sopenharmony_ci struct sparx5_port *port = netdev_priv(dev); 23762306a36Sopenharmony_ci struct sparx5_port *port_itr; 23862306a36Sopenharmony_ci int err, i; 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci for (i = 0; i < SPX5_PORTS; i++) { 24162306a36Sopenharmony_ci port_itr = port->sparx5->ports[i]; 24262306a36Sopenharmony_ci if (!port_itr) 24362306a36Sopenharmony_ci continue; 24462306a36Sopenharmony_ci err = setdel(port_itr->ndev, app); 24562306a36Sopenharmony_ci if (err) 24662306a36Sopenharmony_ci return err; 24762306a36Sopenharmony_ci } 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_ci return 0; 25062306a36Sopenharmony_ci} 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_cistatic int sparx5_dcb_ieee_delapp(struct net_device *dev, struct dcb_app *app) 25362306a36Sopenharmony_ci{ 25462306a36Sopenharmony_ci int err; 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ci if (app->selector == IEEE_8021QAZ_APP_SEL_DSCP) 25762306a36Sopenharmony_ci err = sparx5_dcb_ieee_dscp_setdel(dev, app, dcb_ieee_delapp); 25862306a36Sopenharmony_ci else 25962306a36Sopenharmony_ci err = dcb_ieee_delapp(dev, app); 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ci if (err < 0) 26262306a36Sopenharmony_ci return err; 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_ci return sparx5_dcb_app_update(dev); 26562306a36Sopenharmony_ci} 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_cistatic int sparx5_dcb_ieee_setapp(struct net_device *dev, struct dcb_app *app) 26862306a36Sopenharmony_ci{ 26962306a36Sopenharmony_ci struct dcb_app app_itr; 27062306a36Sopenharmony_ci int err = 0; 27162306a36Sopenharmony_ci u8 prio; 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_ci err = sparx5_dcb_app_validate(dev, app); 27462306a36Sopenharmony_ci if (err) 27562306a36Sopenharmony_ci goto out; 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ci /* Delete current mapping, if it exists */ 27862306a36Sopenharmony_ci prio = dcb_getapp(dev, app); 27962306a36Sopenharmony_ci if (prio) { 28062306a36Sopenharmony_ci app_itr = *app; 28162306a36Sopenharmony_ci app_itr.priority = prio; 28262306a36Sopenharmony_ci sparx5_dcb_ieee_delapp(dev, &app_itr); 28362306a36Sopenharmony_ci } 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ci if (app->selector == IEEE_8021QAZ_APP_SEL_DSCP) 28662306a36Sopenharmony_ci err = sparx5_dcb_ieee_dscp_setdel(dev, app, dcb_ieee_setapp); 28762306a36Sopenharmony_ci else 28862306a36Sopenharmony_ci err = dcb_ieee_setapp(dev, app); 28962306a36Sopenharmony_ci 29062306a36Sopenharmony_ci if (err) 29162306a36Sopenharmony_ci goto out; 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ci sparx5_dcb_app_update(dev); 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_ciout: 29662306a36Sopenharmony_ci return err; 29762306a36Sopenharmony_ci} 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_cistatic int sparx5_dcb_setapptrust(struct net_device *dev, u8 *selectors, 30062306a36Sopenharmony_ci int nselectors) 30162306a36Sopenharmony_ci{ 30262306a36Sopenharmony_ci struct sparx5_port *port = netdev_priv(dev); 30362306a36Sopenharmony_ci int err = 0, idx; 30462306a36Sopenharmony_ci 30562306a36Sopenharmony_ci idx = sparx5_dcb_apptrust_validate(dev, selectors, nselectors, &err); 30662306a36Sopenharmony_ci if (err < 0) 30762306a36Sopenharmony_ci return err; 30862306a36Sopenharmony_ci 30962306a36Sopenharmony_ci sparx5_port_apptrust[port->portno] = &sparx5_dcb_apptrust_policies[idx]; 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci return sparx5_dcb_app_update(dev); 31262306a36Sopenharmony_ci} 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_cistatic int sparx5_dcb_getapptrust(struct net_device *dev, u8 *selectors, 31562306a36Sopenharmony_ci int *nselectors) 31662306a36Sopenharmony_ci{ 31762306a36Sopenharmony_ci struct sparx5_port *port = netdev_priv(dev); 31862306a36Sopenharmony_ci const struct sparx5_dcb_apptrust *trust; 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_ci trust = sparx5_port_apptrust[port->portno]; 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_ci memcpy(selectors, trust->selectors, trust->nselectors); 32362306a36Sopenharmony_ci *nselectors = trust->nselectors; 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_ci return 0; 32662306a36Sopenharmony_ci} 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_cistatic int sparx5_dcb_delrewr(struct net_device *dev, struct dcb_app *app) 32962306a36Sopenharmony_ci{ 33062306a36Sopenharmony_ci int err; 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_ci if (app->selector == IEEE_8021QAZ_APP_SEL_DSCP) 33362306a36Sopenharmony_ci err = sparx5_dcb_ieee_dscp_setdel(dev, app, dcb_delrewr); 33462306a36Sopenharmony_ci else 33562306a36Sopenharmony_ci err = dcb_delrewr(dev, app); 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_ci if (err < 0) 33862306a36Sopenharmony_ci return err; 33962306a36Sopenharmony_ci 34062306a36Sopenharmony_ci return sparx5_dcb_app_update(dev); 34162306a36Sopenharmony_ci} 34262306a36Sopenharmony_ci 34362306a36Sopenharmony_cistatic int sparx5_dcb_setrewr(struct net_device *dev, struct dcb_app *app) 34462306a36Sopenharmony_ci{ 34562306a36Sopenharmony_ci struct dcb_app app_itr; 34662306a36Sopenharmony_ci int err = 0; 34762306a36Sopenharmony_ci u16 proto; 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_ci err = sparx5_dcb_app_validate(dev, app); 35062306a36Sopenharmony_ci if (err) 35162306a36Sopenharmony_ci goto out; 35262306a36Sopenharmony_ci 35362306a36Sopenharmony_ci /* Delete current mapping, if it exists. */ 35462306a36Sopenharmony_ci proto = dcb_getrewr(dev, app); 35562306a36Sopenharmony_ci if (proto) { 35662306a36Sopenharmony_ci app_itr = *app; 35762306a36Sopenharmony_ci app_itr.protocol = proto; 35862306a36Sopenharmony_ci sparx5_dcb_delrewr(dev, &app_itr); 35962306a36Sopenharmony_ci } 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_ci if (app->selector == IEEE_8021QAZ_APP_SEL_DSCP) 36262306a36Sopenharmony_ci err = sparx5_dcb_ieee_dscp_setdel(dev, app, dcb_setrewr); 36362306a36Sopenharmony_ci else 36462306a36Sopenharmony_ci err = dcb_setrewr(dev, app); 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ci if (err) 36762306a36Sopenharmony_ci goto out; 36862306a36Sopenharmony_ci 36962306a36Sopenharmony_ci sparx5_dcb_app_update(dev); 37062306a36Sopenharmony_ci 37162306a36Sopenharmony_ciout: 37262306a36Sopenharmony_ci return err; 37362306a36Sopenharmony_ci} 37462306a36Sopenharmony_ci 37562306a36Sopenharmony_ciconst struct dcbnl_rtnl_ops sparx5_dcbnl_ops = { 37662306a36Sopenharmony_ci .ieee_setapp = sparx5_dcb_ieee_setapp, 37762306a36Sopenharmony_ci .ieee_delapp = sparx5_dcb_ieee_delapp, 37862306a36Sopenharmony_ci .dcbnl_setapptrust = sparx5_dcb_setapptrust, 37962306a36Sopenharmony_ci .dcbnl_getapptrust = sparx5_dcb_getapptrust, 38062306a36Sopenharmony_ci .dcbnl_setrewr = sparx5_dcb_setrewr, 38162306a36Sopenharmony_ci .dcbnl_delrewr = sparx5_dcb_delrewr, 38262306a36Sopenharmony_ci}; 38362306a36Sopenharmony_ci 38462306a36Sopenharmony_ciint sparx5_dcb_init(struct sparx5 *sparx5) 38562306a36Sopenharmony_ci{ 38662306a36Sopenharmony_ci struct sparx5_port *port; 38762306a36Sopenharmony_ci int i; 38862306a36Sopenharmony_ci 38962306a36Sopenharmony_ci for (i = 0; i < SPX5_PORTS; i++) { 39062306a36Sopenharmony_ci port = sparx5->ports[i]; 39162306a36Sopenharmony_ci if (!port) 39262306a36Sopenharmony_ci continue; 39362306a36Sopenharmony_ci port->ndev->dcbnl_ops = &sparx5_dcbnl_ops; 39462306a36Sopenharmony_ci /* Initialize [dscp, pcp] default trust */ 39562306a36Sopenharmony_ci sparx5_port_apptrust[port->portno] = 39662306a36Sopenharmony_ci &sparx5_dcb_apptrust_policies 39762306a36Sopenharmony_ci [SPARX5_DCB_APPTRUST_DSCP_PCP]; 39862306a36Sopenharmony_ci 39962306a36Sopenharmony_ci /* Enable DSCP classification based on classified QoS class and 40062306a36Sopenharmony_ci * DP, for all DSCP values, for all ports. 40162306a36Sopenharmony_ci */ 40262306a36Sopenharmony_ci sparx5_port_qos_dscp_rewr_mode_set(port, 40362306a36Sopenharmony_ci SPARX5_PORT_REW_DSCP_ALL); 40462306a36Sopenharmony_ci } 40562306a36Sopenharmony_ci 40662306a36Sopenharmony_ci return 0; 40762306a36Sopenharmony_ci} 408