enetc: Enable TC offloading with mqprio
Add support to configure multiple prioritized TX traffic classes with mqprio. Configure one BD ring per TC for the moment, one netdev queue per TC. Signed-off-by: Camelia Groza <camelia.groza@nxp.com> Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
7f3343234c
commit
cbe9e83594
@@ -1427,6 +1427,62 @@ int enetc_close(struct net_device *ndev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int enetc_setup_tc(struct net_device *ndev, enum tc_setup_type type,
|
||||
void *type_data)
|
||||
{
|
||||
struct enetc_ndev_priv *priv = netdev_priv(ndev);
|
||||
struct tc_mqprio_qopt *mqprio = type_data;
|
||||
struct enetc_bdr *tx_ring;
|
||||
u8 num_tc;
|
||||
int i;
|
||||
|
||||
if (type != TC_SETUP_QDISC_MQPRIO)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
|
||||
num_tc = mqprio->num_tc;
|
||||
|
||||
if (!num_tc) {
|
||||
netdev_reset_tc(ndev);
|
||||
netif_set_real_num_tx_queues(ndev, priv->num_tx_rings);
|
||||
|
||||
/* Reset all ring priorities to 0 */
|
||||
for (i = 0; i < priv->num_tx_rings; i++) {
|
||||
tx_ring = priv->tx_ring[i];
|
||||
enetc_set_bdr_prio(&priv->si->hw, tx_ring->index, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check if we have enough BD rings available to accommodate all TCs */
|
||||
if (num_tc > priv->num_tx_rings) {
|
||||
netdev_err(ndev, "Max %d traffic classes supported\n",
|
||||
priv->num_tx_rings);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* For the moment, we use only one BD ring per TC.
|
||||
*
|
||||
* Configure num_tc BD rings with increasing priorities.
|
||||
*/
|
||||
for (i = 0; i < num_tc; i++) {
|
||||
tx_ring = priv->tx_ring[i];
|
||||
enetc_set_bdr_prio(&priv->si->hw, tx_ring->index, i);
|
||||
}
|
||||
|
||||
/* Reset the number of netdev queues based on the TC count */
|
||||
netif_set_real_num_tx_queues(ndev, num_tc);
|
||||
|
||||
netdev_set_num_tc(ndev, num_tc);
|
||||
|
||||
/* Each TC is associated with one netdev queue */
|
||||
for (i = 0; i < num_tc; i++)
|
||||
netdev_set_tc_queue(ndev, i, 1, i);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct net_device_stats *enetc_get_stats(struct net_device *ndev)
|
||||
{
|
||||
struct enetc_ndev_priv *priv = netdev_priv(ndev);
|
||||
|
Reference in New Issue
Block a user