Skip to content

Commit 5f5109a

Browse files
oleremdavem330
authored andcommitted
net: dsa: add support switches global DSCP priority mapping
Some switches like Microchip KSZ variants do not support per port DSCP priority configuration. Instead there is a global DSCP mapping table. To handle it, we will accept set/del request to any of user ports to make global configuration and update dcb app entries for all other ports. Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent ea1078d commit 5f5109a

2 files changed

Lines changed: 84 additions & 0 deletions

File tree

include/net/dsa.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,11 @@ struct dsa_switch {
433433
*/
434434
u32 fdb_isolation:1;
435435

436+
/* Drivers that have global DSCP mapping settings must set this to
437+
* true to automatically apply the settings to all ports.
438+
*/
439+
u32 dscp_prio_mapping_is_global:1;
440+
436441
/* Listener for switch fabric events */
437442
struct notifier_block nb;
438443

@@ -586,6 +591,10 @@ static inline bool dsa_is_user_port(struct dsa_switch *ds, int p)
586591
dsa_switch_for_each_port((_dp), (_ds)) \
587592
if (dsa_port_is_user((_dp)))
588593

594+
#define dsa_switch_for_each_user_port_continue_reverse(_dp, _ds) \
595+
dsa_switch_for_each_port_continue_reverse((_dp), (_ds)) \
596+
if (dsa_port_is_user((_dp)))
597+
589598
#define dsa_switch_for_each_cpu_port(_dp, _ds) \
590599
dsa_switch_for_each_port((_dp), (_ds)) \
591600
if (dsa_port_is_cpu((_dp)))

net/dsa/user.c

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2189,6 +2189,58 @@ dsa_user_dcbnl_set_default_prio(struct net_device *dev, struct dcb_app *app)
21892189
return 0;
21902190
}
21912191

2192+
/* Update the DSCP prio entries on all user ports of the switch in case
2193+
* the switch supports global DSCP prio instead of per port DSCP prios.
2194+
*/
2195+
static int dsa_user_dcbnl_ieee_global_dscp_setdel(struct net_device *dev,
2196+
struct dcb_app *app, bool del)
2197+
{
2198+
int (*setdel)(struct net_device *dev, struct dcb_app *app);
2199+
struct dsa_port *dp = dsa_user_to_port(dev);
2200+
struct dsa_switch *ds = dp->ds;
2201+
struct dsa_port *other_dp;
2202+
int err, restore_err;
2203+
2204+
if (del)
2205+
setdel = dcb_ieee_delapp;
2206+
else
2207+
setdel = dcb_ieee_setapp;
2208+
2209+
dsa_switch_for_each_user_port(other_dp, ds) {
2210+
struct net_device *user = other_dp->user;
2211+
2212+
if (!user || user == dev)
2213+
continue;
2214+
2215+
err = setdel(user, app);
2216+
if (err)
2217+
goto err_try_to_restore;
2218+
}
2219+
2220+
return 0;
2221+
2222+
err_try_to_restore:
2223+
2224+
/* Revert logic to restore previous state of app entries */
2225+
if (!del)
2226+
setdel = dcb_ieee_delapp;
2227+
else
2228+
setdel = dcb_ieee_setapp;
2229+
2230+
dsa_switch_for_each_user_port_continue_reverse(other_dp, ds) {
2231+
struct net_device *user = other_dp->user;
2232+
2233+
if (!user || user == dev)
2234+
continue;
2235+
2236+
restore_err = setdel(user, app);
2237+
if (restore_err)
2238+
netdev_err(user, "Failed to restore DSCP prio entry configuration\n");
2239+
}
2240+
2241+
return err;
2242+
}
2243+
21922244
static int __maybe_unused
21932245
dsa_user_dcbnl_add_dscp_prio(struct net_device *dev, struct dcb_app *app)
21942246
{
@@ -2220,6 +2272,17 @@ dsa_user_dcbnl_add_dscp_prio(struct net_device *dev, struct dcb_app *app)
22202272
return err;
22212273
}
22222274

2275+
if (!ds->dscp_prio_mapping_is_global)
2276+
return 0;
2277+
2278+
err = dsa_user_dcbnl_ieee_global_dscp_setdel(dev, app, false);
2279+
if (err) {
2280+
if (ds->ops->port_del_dscp_prio)
2281+
ds->ops->port_del_dscp_prio(ds, port, dscp, new_prio);
2282+
dcb_ieee_delapp(dev, app);
2283+
return err;
2284+
}
2285+
22232286
return 0;
22242287
}
22252288

@@ -2290,6 +2353,18 @@ dsa_user_dcbnl_del_dscp_prio(struct net_device *dev, struct dcb_app *app)
22902353
return err;
22912354
}
22922355

2356+
if (!ds->dscp_prio_mapping_is_global)
2357+
return 0;
2358+
2359+
err = dsa_user_dcbnl_ieee_global_dscp_setdel(dev, app, true);
2360+
if (err) {
2361+
if (ds->ops->port_add_dscp_prio)
2362+
ds->ops->port_add_dscp_prio(ds, port, dscp,
2363+
app->priority);
2364+
dcb_ieee_setapp(dev, app);
2365+
return err;
2366+
}
2367+
22932368
return 0;
22942369
}
22952370

0 commit comments

Comments
 (0)