On Tue, Jun 02, 2026 at 10:43:50AM +1000, Luke Howard wrote:
> +static int mv88e6xxx_setup_tc_mqprio(struct dsa_switch *ds, int port,
> +                                  struct tc_mqprio_qopt_offload *mqprio)
> +{
> +     struct netlink_ext_ack *extack = mqprio->extack;
> +     u8 ieee_pri_map[IEEE_8021Q_MAX_PRIORITIES];
> +     struct mv88e6xxx_chip *chip = ds->priv;
> +     struct mv88e6xxx_tc_policy *pol;
> +     enum mv88e6xxx_tc_mode tc_mode;
> +     struct net_device *user;
> +     bool can_update_pol;
> +     bool per_port_pol;
> +     int num_tc, err;
> +
> +     if (!dsa_is_user_port(ds, port))
> +             return -EINVAL;
> +
> +     num_tc = mv88e6xxx_validate_tc_mqprio(chip, mqprio, &tc_mode, 
> ieee_pri_map);
> +     if (num_tc < 0)
> +             return num_tc;
> +
> +     user = dsa_to_port(ds, port)->user;
> +
> +     per_port_pol = (tc_mode == MV88E6XXX_TC_MODE_QPRI &&
> +                     chip->info->ops->port_ieee_pri_map);
> +
> +     mv88e6xxx_reg_lock(chip);
> +
> +     pol = &chip->tc_policy;
> +
> +     if (num_tc && pol->tc_mode && pol->tc_mode != tc_mode) {
> +             NL_SET_ERR_MSG_MOD(extack, "all switch ports must use the same 
> MQPRIO mode");
> +             err = -EOPNOTSUPP;
> +             goto err_unlock;
> +     }
> +
> +     can_update_pol = per_port_pol ||
> +                      !pol->tc_port_mask || pol->tc_port_mask == BIT(port);
> +     if (!can_update_pol && num_tc &&
> +         !mv88e6xxx_tc_mode_map_equal(chip, tc_mode, ieee_pri_map)) {
> +             NL_SET_ERR_MSG_MOD(extack, "only a single priority mapping 
> supported per switch");
> +             err = -EOPNOTSUPP;
> +             goto err_unlock;
> +     }
> +
> +     err = mv88e6xxx_mqprio_netdev_set_tc(user, &mqprio->qopt, num_tc);
> +     if (err)
> +             goto err_reset_tc;
> +
> +     if (can_update_pol) {
> +             const u8 *map = num_tc ? ieee_pri_map : NULL;
> +
> +             if (per_port_pol)
> +                     err = mv88e6xxx_set_port_ieee_pri_map(chip, port, map);
> +             else
> +                     err = mv88e6xxx_set_ieee_pri_map(chip, map);

In case of per port priority mapping, i don't know if this is working as
expected, as the IEEE priority mapping is done at ingress.
Eg. i think if MQPRIO channel mode is used to configure a pcp to queue mapping
on port 1 and a different mapping on port 2. Traffic received on port 1 that
gets forwarded to port 2 and egresses port 2 will end up in the queue
configured by the mapping on port 1. As mqprio is an egress qdisc, i don't
think that's expected.

I have a patch that hasn't been submitted to the mailing list yet which
implements support for the dcb app pcp-prio command. This is also done by
configuring the IEEE priority mapping table.

Cedric


Reply via email to