Skip to content

Commit c2e7226

Browse files
oleremdavem330
authored andcommitted
net: dsa: microchip: add support DSCP priority mapping
Microchip KSZ and LAN variants do not have per port DSCP priority configuration. Instead there is a global DSCP mapping table. This patch provides write access to this global DSCP map. In case entry is "deleted", we map corresponding DSCP entry to a best effort prio, which is expected to be the default priority for all untagged traffic. Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 5f5109a commit c2e7226

3 files changed

Lines changed: 50 additions & 15 deletions

File tree

drivers/net/dsa/microchip/ksz_common.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2360,6 +2360,7 @@ static int ksz_setup(struct dsa_switch *ds)
23602360
ksz_init_mib_timer(dev);
23612361

23622362
ds->configure_vlan_while_not_filtering = false;
2363+
ds->dscp_prio_mapping_is_global = true;
23632364

23642365
if (dev->dev_ops->setup) {
23652366
ret = dev->dev_ops->setup(ds);
@@ -3989,6 +3990,8 @@ static const struct dsa_switch_ops ksz_switch_ops = {
39893990
.port_get_default_prio = ksz_port_get_default_prio,
39903991
.port_set_default_prio = ksz_port_set_default_prio,
39913992
.port_get_dscp_prio = ksz_port_get_dscp_prio,
3993+
.port_add_dscp_prio = ksz_port_add_dscp_prio,
3994+
.port_del_dscp_prio = ksz_port_del_dscp_prio,
39923995
.port_get_apptrust = ksz_port_get_apptrust,
39933996
.port_set_apptrust = ksz_port_set_apptrust,
39943997
};

drivers/net/dsa/microchip/ksz_dcb.c

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,19 @@ int ksz_port_get_dscp_prio(struct dsa_switch *ds, int port, u8 dscp)
310310
return (data >> shift) & mask;
311311
}
312312

313+
static int ksz_set_global_dscp_entry(struct ksz_device *dev, u8 dscp, u8 ipv)
314+
{
315+
int reg, per_reg, shift;
316+
u8 mask;
317+
318+
ksz_get_dscp_prio_reg(dev, &reg, &per_reg, &mask);
319+
320+
shift = (dscp % per_reg) * (8 / per_reg);
321+
322+
return ksz_rmw8(dev, reg + (dscp / per_reg), mask << shift,
323+
ipv << shift);
324+
}
325+
313326
/**
314327
* ksz_init_global_dscp_map - Initializes the global DSCP-to-priority mapping
315328
* @dev: Pointer to the KSZ switch device structure
@@ -321,9 +334,7 @@ int ksz_port_get_dscp_prio(struct dsa_switch *ds, int port, u8 dscp)
321334
*/
322335
static int ksz_init_global_dscp_map(struct ksz_device *dev)
323336
{
324-
int reg, per_reg, ret, dscp;
325-
u8 data = 0;
326-
u8 mask;
337+
int ret, dscp;
327338

328339
/* On KSZ9xxx variants, DSCP remapping is disabled by default.
329340
* Enable to have, predictable and reproducible behavior across
@@ -337,10 +348,8 @@ static int ksz_init_global_dscp_map(struct ksz_device *dev)
337348
return ret;
338349
}
339350

340-
ksz_get_dscp_prio_reg(dev, &reg, &per_reg, &mask);
341-
342351
for (dscp = 0; dscp < DSCP_MAX; dscp++) {
343-
int ipv, shift, tt;
352+
int ipv, tt;
344353

345354
/* Map DSCP to Traffic Type, which is corresponding to the
346355
* Internal Priority Value (IPV) in the switch.
@@ -362,19 +371,40 @@ static int ksz_init_global_dscp_map(struct ksz_device *dev)
362371
if (ipv < 0)
363372
return ipv;
364373

365-
shift = (dscp % per_reg) * (8 / per_reg);
366-
data |= (ipv & mask) << shift;
374+
ret = ksz_set_global_dscp_entry(dev, dscp, ipv);
375+
}
367376

368-
if (dscp % per_reg == per_reg - 1) {
369-
ret = ksz_write8(dev, reg + (dscp / per_reg), data);
370-
if (ret)
371-
return ret;
377+
return 0;
378+
}
372379

373-
data = 0;
374-
}
380+
int ksz_port_add_dscp_prio(struct dsa_switch *ds, int port, u8 dscp, u8 prio)
381+
{
382+
struct ksz_device *dev = ds->priv;
383+
384+
if (prio >= dev->info->num_ipvs)
385+
return -ERANGE;
386+
387+
return ksz_set_global_dscp_entry(dev, dscp, prio);
388+
}
389+
390+
int ksz_port_del_dscp_prio(struct dsa_switch *ds, int port, u8 dscp, u8 prio)
391+
{
392+
struct ksz_device *dev = ds->priv;
393+
int ipv;
394+
395+
if (ksz_port_get_dscp_prio(ds, port, dscp) != prio)
396+
return 0;
397+
398+
if (is_ksz8(dev)) {
399+
ipv = ieee8021q_tt_to_tc(IEEE8021Q_TT_BE,
400+
dev->info->num_tx_queues);
401+
if (ipv < 0)
402+
return ipv;
403+
} else {
404+
ipv = IEEE8021Q_TT_BE;
375405
}
376406

377-
return 0;
407+
return ksz_set_global_dscp_entry(dev, dscp, ipv);
378408
}
379409

380410
/**

drivers/net/dsa/microchip/ksz_dcb.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
int ksz_port_get_default_prio(struct dsa_switch *ds, int port);
1212
int ksz_port_set_default_prio(struct dsa_switch *ds, int port, u8 prio);
1313
int ksz_port_get_dscp_prio(struct dsa_switch *ds, int port, u8 dscp);
14+
int ksz_port_add_dscp_prio(struct dsa_switch *ds, int port, u8 dscp, u8 prio);
15+
int ksz_port_del_dscp_prio(struct dsa_switch *ds, int port, u8 dscp, u8 prio);
1416
int ksz_port_set_apptrust(struct dsa_switch *ds, int port,
1517
const unsigned char *sel,
1618
int nsel);

0 commit comments

Comments
 (0)