net: dsa: hellcreek: Offload per-tc max SDU from tc-taprio
Add support for configuring the max SDU per priority and per port. If not specified, keep the default. Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
248376b1b1
commit
a745c69783
|
@ -128,6 +128,16 @@ static void hellcreek_select_prio(struct hellcreek *hellcreek, int prio)
|
|||
hellcreek_write(hellcreek, val, HR_PSEL);
|
||||
}
|
||||
|
||||
static void hellcreek_select_port_prio(struct hellcreek *hellcreek, int port,
|
||||
int prio)
|
||||
{
|
||||
u16 val = port << HR_PSEL_PTWSEL_SHIFT;
|
||||
|
||||
val |= prio << HR_PSEL_PRTCWSEL_SHIFT;
|
||||
|
||||
hellcreek_write(hellcreek, val, HR_PSEL);
|
||||
}
|
||||
|
||||
static void hellcreek_select_counter(struct hellcreek *hellcreek, int counter)
|
||||
{
|
||||
u16 val = counter << HR_CSEL_SHIFT;
|
||||
|
@ -1537,6 +1547,45 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void hellcreek_setup_maxsdu(struct hellcreek *hellcreek, int port,
|
||||
const struct tc_taprio_qopt_offload *schedule)
|
||||
{
|
||||
int tc;
|
||||
|
||||
for (tc = 0; tc < 8; ++tc) {
|
||||
u32 max_sdu = schedule->max_sdu[tc] + VLAN_ETH_HLEN - ETH_FCS_LEN;
|
||||
u16 val;
|
||||
|
||||
if (!schedule->max_sdu[tc])
|
||||
continue;
|
||||
|
||||
dev_dbg(hellcreek->dev, "Configure max-sdu %u for tc %d on port %d\n",
|
||||
max_sdu, tc, port);
|
||||
|
||||
hellcreek_select_port_prio(hellcreek, port, tc);
|
||||
|
||||
val = (max_sdu & HR_PTPRTCCFG_MAXSDU_MASK) << HR_PTPRTCCFG_MAXSDU_SHIFT;
|
||||
|
||||
hellcreek_write(hellcreek, val, HR_PTPRTCCFG);
|
||||
}
|
||||
}
|
||||
|
||||
static void hellcreek_reset_maxsdu(struct hellcreek *hellcreek, int port)
|
||||
{
|
||||
int tc;
|
||||
|
||||
for (tc = 0; tc < 8; ++tc) {
|
||||
u16 val;
|
||||
|
||||
hellcreek_select_port_prio(hellcreek, port, tc);
|
||||
|
||||
val = (HELLCREEK_DEFAULT_MAX_SDU & HR_PTPRTCCFG_MAXSDU_MASK)
|
||||
<< HR_PTPRTCCFG_MAXSDU_SHIFT;
|
||||
|
||||
hellcreek_write(hellcreek, val, HR_PTPRTCCFG);
|
||||
}
|
||||
}
|
||||
|
||||
static void hellcreek_setup_gcl(struct hellcreek *hellcreek, int port,
|
||||
const struct tc_taprio_qopt_offload *schedule)
|
||||
{
|
||||
|
@ -1720,7 +1769,10 @@ static int hellcreek_port_set_schedule(struct dsa_switch *ds, int port,
|
|||
}
|
||||
hellcreek_port->current_schedule = taprio_offload_get(taprio);
|
||||
|
||||
/* Then select port */
|
||||
/* Configure max sdu */
|
||||
hellcreek_setup_maxsdu(hellcreek, port, hellcreek_port->current_schedule);
|
||||
|
||||
/* Select tdg */
|
||||
hellcreek_select_tgd(hellcreek, port);
|
||||
|
||||
/* Enable gating and keep defaults */
|
||||
|
@ -1772,7 +1824,10 @@ static int hellcreek_port_del_schedule(struct dsa_switch *ds, int port)
|
|||
hellcreek_port->current_schedule = NULL;
|
||||
}
|
||||
|
||||
/* Then select port */
|
||||
/* Reset max sdu */
|
||||
hellcreek_reset_maxsdu(hellcreek, port);
|
||||
|
||||
/* Select tgd */
|
||||
hellcreek_select_tgd(hellcreek, port);
|
||||
|
||||
/* Disable gating and return to regular switching flow */
|
||||
|
@ -1809,12 +1864,29 @@ static bool hellcreek_validate_schedule(struct hellcreek *hellcreek,
|
|||
return true;
|
||||
}
|
||||
|
||||
static int hellcreek_tc_query_caps(struct tc_query_caps_base *base)
|
||||
{
|
||||
switch (base->type) {
|
||||
case TC_SETUP_QDISC_TAPRIO: {
|
||||
struct tc_taprio_caps *caps = base->caps;
|
||||
|
||||
caps->supports_queue_max_sdu = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
}
|
||||
|
||||
static int hellcreek_port_setup_tc(struct dsa_switch *ds, int port,
|
||||
enum tc_setup_type type, void *type_data)
|
||||
{
|
||||
struct hellcreek *hellcreek = ds->priv;
|
||||
|
||||
switch (type) {
|
||||
case TC_QUERY_CAPS:
|
||||
return hellcreek_tc_query_caps(type_data);
|
||||
case TC_SETUP_QDISC_TAPRIO: {
|
||||
struct tc_taprio_qopt_offload *taprio = type_data;
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#define HELLCREEK_VLAN_UNTAGGED_MEMBER 0x1
|
||||
#define HELLCREEK_VLAN_TAGGED_MEMBER 0x3
|
||||
#define HELLCREEK_NUM_EGRESS_QUEUES 8
|
||||
#define HELLCREEK_DEFAULT_MAX_SDU 1536
|
||||
|
||||
/* Register definitions */
|
||||
#define HR_MODID_C (0 * 2)
|
||||
|
@ -72,6 +73,12 @@
|
|||
#define HR_PRTCCFG_PCP_TC_MAP_SHIFT 0
|
||||
#define HR_PRTCCFG_PCP_TC_MAP_MASK GENMASK(2, 0)
|
||||
|
||||
#define HR_PTPRTCCFG (0xa9 * 2)
|
||||
#define HR_PTPRTCCFG_SET_QTRACK BIT(15)
|
||||
#define HR_PTPRTCCFG_REJECT BIT(14)
|
||||
#define HR_PTPRTCCFG_MAXSDU_SHIFT 0
|
||||
#define HR_PTPRTCCFG_MAXSDU_MASK GENMASK(10, 0)
|
||||
|
||||
#define HR_CSEL (0x8d * 2)
|
||||
#define HR_CSEL_SHIFT 0
|
||||
#define HR_CSEL_MASK GENMASK(7, 0)
|
||||
|
|
Loading…
Reference in New Issue