net: ethernet: am65-cpsw: cleanup TAPRIO handling

Handle offloading commands using switch-case in
am65_cpsw_setup_taprio().

Move checks to am65_cpsw_taprio_replace().

Use NL_SET_ERR_MSG_MOD for error messages.
Change error message from "Failed to set cycle time extension"
to "cycle time extension not supported"

Signed-off-by: Roger Quadros <rogerq@kernel.org>
Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Roger Quadros 2023-12-19 12:58:00 +02:00 committed by David S. Miller
parent d0f9535b31
commit 5db81bdc48
1 changed files with 71 additions and 80 deletions

View File

@ -428,7 +428,7 @@ static void am65_cpsw_stop_est(struct net_device *ndev)
am65_cpsw_timer_stop(ndev); am65_cpsw_timer_stop(ndev);
} }
static void am65_cpsw_purge_est(struct net_device *ndev) static void am65_cpsw_taprio_destroy(struct net_device *ndev)
{ {
struct am65_cpsw_port *port = am65_ndev_to_port(ndev); struct am65_cpsw_port *port = am65_ndev_to_port(ndev);
@ -441,29 +441,66 @@ static void am65_cpsw_purge_est(struct net_device *ndev)
port->qos.est_admin = NULL; port->qos.est_admin = NULL;
} }
static int am65_cpsw_configure_taprio(struct net_device *ndev, static void am65_cpsw_cp_taprio(struct tc_taprio_qopt_offload *from,
struct am65_cpsw_est *est_new) struct tc_taprio_qopt_offload *to)
{
int i;
*to = *from;
for (i = 0; i < from->num_entries; i++)
to->entries[i] = from->entries[i];
}
static int am65_cpsw_taprio_replace(struct net_device *ndev,
struct tc_taprio_qopt_offload *taprio)
{ {
struct am65_cpsw_common *common = am65_ndev_to_common(ndev); struct am65_cpsw_common *common = am65_ndev_to_common(ndev);
struct netlink_ext_ack *extack = taprio->mqprio.extack;
struct am65_cpsw_port *port = am65_ndev_to_port(ndev);
struct am65_cpts *cpts = common->cpts; struct am65_cpts *cpts = common->cpts;
int ret = 0, tact = TACT_PROG; struct am65_cpsw_est *est_new;
int ret, tact;
if (!netif_running(ndev)) {
NL_SET_ERR_MSG_MOD(extack, "interface is down, link speed unknown");
return -ENETDOWN;
}
if (common->pf_p0_rx_ptype_rrobin) {
NL_SET_ERR_MSG_MOD(extack,
"p0-rx-ptype-rrobin flag conflicts with taprio qdisc");
return -EINVAL;
}
if (port->qos.link_speed == SPEED_UNKNOWN)
return -ENOLINK;
if (taprio->cycle_time_extension) {
NL_SET_ERR_MSG_MOD(extack,
"cycle time extension not supported");
return -EOPNOTSUPP;
}
est_new = devm_kzalloc(&ndev->dev,
struct_size(est_new, taprio.entries, taprio->num_entries),
GFP_KERNEL);
if (!est_new)
return -ENOMEM;
am65_cpsw_cp_taprio(taprio, &est_new->taprio);
am65_cpsw_est_update_state(ndev); am65_cpsw_est_update_state(ndev);
if (est_new->taprio.cmd == TAPRIO_CMD_DESTROY) {
am65_cpsw_stop_est(ndev);
return ret;
}
ret = am65_cpsw_est_check_scheds(ndev, est_new); ret = am65_cpsw_est_check_scheds(ndev, est_new);
if (ret < 0) if (ret < 0)
return ret; goto fail;
tact = am65_cpsw_timer_act(ndev, est_new); tact = am65_cpsw_timer_act(ndev, est_new);
if (tact == TACT_NEED_STOP) { if (tact == TACT_NEED_STOP) {
dev_err(&ndev->dev, NL_SET_ERR_MSG_MOD(extack,
"Can't toggle estf timer, stop taprio first"); "Can't toggle estf timer, stop taprio first");
return -EINVAL; ret = -EINVAL;
goto fail;
} }
if (tact == TACT_PROG) if (tact == TACT_PROG)
@ -476,62 +513,24 @@ static int am65_cpsw_configure_taprio(struct net_device *ndev,
am65_cpsw_est_set_sched_list(ndev, est_new); am65_cpsw_est_set_sched_list(ndev, est_new);
am65_cpsw_port_est_assign_buf_num(ndev, est_new->buf); am65_cpsw_port_est_assign_buf_num(ndev, est_new->buf);
am65_cpsw_est_set(ndev, est_new->taprio.cmd == TAPRIO_CMD_REPLACE); am65_cpsw_est_set(ndev, 1);
if (tact == TACT_PROG) { if (tact == TACT_PROG) {
ret = am65_cpsw_timer_set(ndev, est_new); ret = am65_cpsw_timer_set(ndev, est_new);
if (ret) { if (ret) {
dev_err(&ndev->dev, "Failed to set cycle time"); NL_SET_ERR_MSG_MOD(extack,
return ret; "Failed to set cycle time");
goto fail;
} }
} }
return ret; devm_kfree(&ndev->dev, port->qos.est_admin);
} port->qos.est_admin = est_new;
static void am65_cpsw_cp_taprio(struct tc_taprio_qopt_offload *from, return 0;
struct tc_taprio_qopt_offload *to)
{
int i;
*to = *from;
for (i = 0; i < from->num_entries; i++)
to->entries[i] = from->entries[i];
}
static int am65_cpsw_set_taprio(struct net_device *ndev, void *type_data)
{
struct am65_cpsw_port *port = am65_ndev_to_port(ndev);
struct tc_taprio_qopt_offload *taprio = type_data;
struct am65_cpsw_est *est_new;
int ret = 0;
if (taprio->cycle_time_extension) {
dev_err(&ndev->dev, "Failed to set cycle time extension");
return -EOPNOTSUPP;
}
est_new = devm_kzalloc(&ndev->dev,
struct_size(est_new, taprio.entries, taprio->num_entries),
GFP_KERNEL);
if (!est_new)
return -ENOMEM;
am65_cpsw_cp_taprio(taprio, &est_new->taprio);
ret = am65_cpsw_configure_taprio(ndev, est_new);
if (!ret) {
if (taprio->cmd == TAPRIO_CMD_REPLACE) {
devm_kfree(&ndev->dev, port->qos.est_admin);
port->qos.est_admin = est_new;
} else {
devm_kfree(&ndev->dev, est_new);
am65_cpsw_purge_est(ndev);
}
} else {
devm_kfree(&ndev->dev, est_new);
}
fail:
devm_kfree(&ndev->dev, est_new);
return ret; return ret;
} }
@ -558,34 +557,26 @@ static void am65_cpsw_est_link_up(struct net_device *ndev, int link_speed)
return; return;
purge_est: purge_est:
am65_cpsw_purge_est(ndev); am65_cpsw_taprio_destroy(ndev);
} }
static int am65_cpsw_setup_taprio(struct net_device *ndev, void *type_data) static int am65_cpsw_setup_taprio(struct net_device *ndev, void *type_data)
{ {
struct am65_cpsw_port *port = am65_ndev_to_port(ndev);
struct tc_taprio_qopt_offload *taprio = type_data; struct tc_taprio_qopt_offload *taprio = type_data;
struct am65_cpsw_common *common = port->common; int err = 0;
if (taprio->cmd != TAPRIO_CMD_REPLACE && switch (taprio->cmd) {
taprio->cmd != TAPRIO_CMD_DESTROY) case TAPRIO_CMD_REPLACE:
return -EOPNOTSUPP; err = am65_cpsw_taprio_replace(ndev, taprio);
break;
if (!netif_running(ndev)) { case TAPRIO_CMD_DESTROY:
dev_err(&ndev->dev, "interface is down, link speed unknown\n"); am65_cpsw_taprio_destroy(ndev);
return -ENETDOWN; break;
default:
err = -EOPNOTSUPP;
} }
if (common->pf_p0_rx_ptype_rrobin) { return err;
dev_err(&ndev->dev,
"p0-rx-ptype-rrobin flag conflicts with taprio qdisc\n");
return -EINVAL;
}
if (port->qos.link_speed == SPEED_UNKNOWN)
return -ENOLINK;
return am65_cpsw_set_taprio(ndev, type_data);
} }
static int am65_cpsw_tc_query_caps(struct net_device *ndev, void *type_data) static int am65_cpsw_tc_query_caps(struct net_device *ndev, void *type_data)