2022-09-29 18:52:54

by Daniel Machon

[permalink] [raw]
Subject: [PATCH net-next v2 5/6] net: microchip: sparx5: add support for offloading dscp table

Add support for offloading dscp app entries. Dscp values are global for
all ports on the sparx5 switch. Therefore, we replicate each dscp app
entry per-port.

Signed-off-by: Daniel Machon <[email protected]>
---
.../ethernet/microchip/sparx5/sparx5_dcb.c | 62 ++++++++++++++++++-
.../ethernet/microchip/sparx5/sparx5_port.c | 39 ++++++++++++
.../ethernet/microchip/sparx5/sparx5_port.h | 9 +++
3 files changed, 108 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c b/drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c
index 10aeb422b1ae..0cc46672b59c 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_dcb.c
@@ -34,6 +34,13 @@ static int sparx5_dcb_app_validate(struct net_device *dev,
int err = 0;

switch (app->selector) {
+ /* Dscp checks */
+ case IEEE_8021QAZ_APP_SEL_DSCP:
+ if (app->protocol > 63)
+ err = -EINVAL;
+ else if (app->priority >= SPX5_PRIOS)
+ err = -ERANGE;
+ break;
/* Pcp checks */
case DCB_APP_SEL_PCP:
if (app->protocol > 15)
@@ -104,12 +111,20 @@ static int sparx5_dcb_app_update(struct net_device *dev)
struct dcb_app app_itr = { .selector = DCB_APP_SEL_PCP };
struct sparx5_port *port = netdev_priv(dev);
struct sparx5_port_qos_pcp_map *pcp_map;
+ struct dcb_ieee_app_dscp_map *dscp_map;
struct sparx5_port_qos qos = {0};
int portno = port->portno;
int i;

+ dscp_map = &qos.dscp.map;
pcp_map = &qos.pcp.map;

+ /* Get dscp ingress mapping */
+ dcb_ieee_getapp_dscp_prio_mask_map(dev, dscp_map);
+ for (i = 0; i < ARRAY_SIZE(dscp_map->map); i++)
+ if (dscp_map->map[i])
+ dscp_map->map[i] = fls(dscp_map->map[i]) - 1;
+
/* Get pcp ingress mapping */
for (i = 0; i < ARRAY_SIZE(pcp_map->map); i++) {
app_itr.protocol = i;
@@ -122,9 +137,44 @@ static int sparx5_dcb_app_update(struct net_device *dev)
qos.pcp.dp_enable = qos.pcp.qos_enable;
}

+ /* Enable use of dscp for queue classification ? */
+ if (sparx5_dcb_apptrust_contains(portno, IEEE_8021QAZ_APP_SEL_DSCP)) {
+ qos.dscp.qos_enable = true;
+ qos.dscp.dp_enable = qos.dscp.qos_enable;
+ }
+
return sparx5_port_qos_set(port, &qos);
}

+/* Set or delete dscp app entry.
+ *
+ * Dscp mapping is global for all ports, so set and delete app entries are
+ * replicated for each port.
+ */
+static int sparx5_dcb_ieee_dscp_setdel_app(struct net_device *dev,
+ struct dcb_app *app, bool del)
+{
+ struct sparx5_port *port = netdev_priv(dev);
+ struct dcb_app apps[SPX5_PORTS];
+ struct sparx5_port *port_itr;
+ int err, i;
+
+ for (i = 0; i < SPX5_PORTS; i++) {
+ port_itr = port->sparx5->ports[i];
+ if (!port_itr)
+ continue;
+ memcpy(&apps[i], app, sizeof(struct dcb_app));
+ if (del)
+ err = dcb_ieee_delapp(port_itr->ndev, &apps[i]);
+ else
+ err = dcb_ieee_setapp(port_itr->ndev, &apps[i]);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
static int sparx5_dcb_ieee_setapp(struct net_device *dev, struct dcb_app *app)
{
struct dcb_app app_itr;
@@ -143,7 +193,11 @@ static int sparx5_dcb_ieee_setapp(struct net_device *dev, struct dcb_app *app)
dcb_ieee_delapp(dev, &app_itr);
}

- err = dcb_ieee_setapp(dev, app);
+ if (app->selector == IEEE_8021QAZ_APP_SEL_DSCP)
+ err = sparx5_dcb_ieee_dscp_setdel_app(dev, app, false);
+ else
+ err = dcb_ieee_setapp(dev, app);
+
if (err)
goto out;

@@ -157,7 +211,11 @@ static int sparx5_dcb_ieee_delapp(struct net_device *dev, struct dcb_app *app)
{
int err;

- err = dcb_ieee_delapp(dev, app);
+ if (app->selector == IEEE_8021QAZ_APP_SEL_DSCP)
+ err = sparx5_dcb_ieee_dscp_setdel_app(dev, app, true);
+ else
+ err = dcb_ieee_delapp(dev, app);
+
if (err < 0)
return err;

diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
index 99e86e87aa16..fb5e321c4896 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
@@ -1149,6 +1149,7 @@ void sparx5_port_enable(struct sparx5_port *port, bool enable)
int sparx5_port_qos_set(struct sparx5_port *port,
struct sparx5_port_qos *qos)
{
+ sparx5_port_qos_dscp_set(port, &qos->dscp);
sparx5_port_qos_pcp_set(port, &qos->pcp);

return 0;
@@ -1181,3 +1182,41 @@ int sparx5_port_qos_pcp_set(const struct sparx5_port *port,

return 0;
}
+
+int sparx5_port_qos_dscp_set(const struct sparx5_port *port,
+ struct sparx5_port_qos_dscp *qos)
+{
+ struct sparx5 *sparx5 = port->sparx5;
+ u8 *dscp = qos->map.map;
+ int i;
+
+ /* Enable/disable dscp and dp for qos classification.
+ * Disable rewrite of dscp values for now.
+ */
+ spx5_rmw(ANA_CL_QOS_CFG_DSCP_QOS_ENA_SET(qos->qos_enable) |
+ ANA_CL_QOS_CFG_DSCP_DP_ENA_SET(qos->dp_enable) |
+ ANA_CL_QOS_CFG_DSCP_KEEP_ENA_SET(1),
+ ANA_CL_QOS_CFG_DSCP_QOS_ENA | ANA_CL_QOS_CFG_DSCP_DP_ENA |
+ ANA_CL_QOS_CFG_DSCP_KEEP_ENA, sparx5,
+ ANA_CL_QOS_CFG(port->portno));
+
+ /* Map each dscp value to priority and dp */
+ for (i = 0; i < ARRAY_SIZE(qos->map.map); i++) {
+ spx5_rmw(ANA_CL_DSCP_CFG_DSCP_QOS_VAL_SET(*(dscp + i)) |
+ ANA_CL_DSCP_CFG_DSCP_DP_VAL_SET(0),
+ ANA_CL_DSCP_CFG_DSCP_QOS_VAL |
+ ANA_CL_DSCP_CFG_DSCP_DP_VAL, sparx5,
+ ANA_CL_DSCP_CFG(i));
+ }
+
+ /* Set per-dscp trust */
+ for (i = 0; i < ARRAY_SIZE(qos->map.map); i++) {
+ if (qos->qos_enable) {
+ spx5_rmw(ANA_CL_DSCP_CFG_DSCP_TRUST_ENA_SET(1),
+ ANA_CL_DSCP_CFG_DSCP_TRUST_ENA, sparx5,
+ ANA_CL_DSCP_CFG(i));
+ }
+ }
+
+ return 0;
+}
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.h b/drivers/net/ethernet/microchip/sparx5/sparx5_port.h
index fae9f5464548..00def02455a7 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.h
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.h
@@ -101,8 +101,15 @@ struct sparx5_port_qos_pcp {
bool dp_enable;
};

+struct sparx5_port_qos_dscp {
+ struct dcb_ieee_app_dscp_map map;
+ bool qos_enable;
+ bool dp_enable;
+};
+
struct sparx5_port_qos {
struct sparx5_port_qos_pcp pcp;
+ struct sparx5_port_qos_dscp dscp;
};

int sparx5_port_qos_set(struct sparx5_port *port, struct sparx5_port_qos *qos);
@@ -110,4 +117,6 @@ int sparx5_port_qos_set(struct sparx5_port *port, struct sparx5_port_qos *qos);
int sparx5_port_qos_pcp_set(const struct sparx5_port *port,
struct sparx5_port_qos_pcp *qos);

+int sparx5_port_qos_dscp_set(const struct sparx5_port *port,
+ struct sparx5_port_qos_dscp *qos);
#endif /* __SPARX5_PORT_H__ */
--
2.34.1


2022-09-30 23:30:33

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH net-next v2 5/6] net: microchip: sparx5: add support for offloading dscp table

Hi Daniel,

I love your patch! Yet something to improve:

[auto build test ERROR on net-next/master]

url: https://github.com/intel-lab-lkp/linux/commits/Daniel-Machon/Add-new-PCP-and-APPTRUST-attributes-to-dcbnl/20220930-024511
base: https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 510bbf82f8dc36804114873d30ed1d0c8533af81
config: sh-randconfig-r024-20220926
compiler: sh4-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/443c23e1ddfd38eba2240f4de118876c58f2439e
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Daniel-Machon/Add-new-PCP-and-APPTRUST-attributes-to-dcbnl/20220930-024511
git checkout 443c23e1ddfd38eba2240f4de118876c58f2439e
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=sh SHELL=/bin/bash drivers/net/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <[email protected]>

All errors (new ones prefixed by >>):

cc1: warning: arch/sh/include/mach-rsk: No such file or directory [-Wmissing-include-dirs]
cc1: warning: arch/sh/include/mach-rsk: No such file or directory [-Wmissing-include-dirs]
In file included from drivers/net/ethernet/microchip/sparx5/sparx5_main.c:29:
>> drivers/net/ethernet/microchip/sparx5/sparx5_port.h:105:38: error: field 'map' has incomplete type
105 | struct dcb_ieee_app_dscp_map map;
| ^~~
--
cc1: warning: arch/sh/include/mach-rsk: No such file or directory [-Wmissing-include-dirs]
cc1: warning: arch/sh/include/mach-rsk: No such file or directory [-Wmissing-include-dirs]
In file included from drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c:9:
>> drivers/net/ethernet/microchip/sparx5/sparx5_port.h:105:38: error: field 'map' has incomplete type
105 | struct dcb_ieee_app_dscp_map map;
| ^~~
drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c: In function 'sparx5_create_netdev':
drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c:261:13: error: 'struct net_device' has no member named 'dcbnl_ops'
261 | ndev->dcbnl_ops = &sparx5_dcbnl_ops;
| ^~


vim +/map +105 drivers/net/ethernet/microchip/sparx5/sparx5_port.h

103
104 struct sparx5_port_qos_dscp {
> 105 struct dcb_ieee_app_dscp_map map;
106 bool qos_enable;
107 bool dp_enable;
108 };
109

--
0-DAY CI Kernel Test Service
https://01.org/lkp


Attachments:
(No filename) (2.83 kB)
config (149.15 kB)
Download all attachments