net: enetc: offload per-tc max SDU from tc-taprio
The driver currently sets the PTCMSDUR register statically to the max MTU supported by the interface. Keep this logic if tc-taprio is absent or if the max_sdu for a traffic class is 0, and follow the requested max SDU size otherwise. Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
9a2ea26d97
commit
dfc7175de3
|
@ -453,7 +453,11 @@ static inline void enetc_cbd_free_data_mem(struct enetc_si *si, int size,
|
|||
data, *dma);
|
||||
}
|
||||
|
||||
void enetc_reset_ptcmsdur(struct enetc_hw *hw);
|
||||
void enetc_set_ptcmsdur(struct enetc_hw *hw, u32 *queue_max_sdu);
|
||||
|
||||
#ifdef CONFIG_FSL_ENETC_QOS
|
||||
int enetc_qos_query_caps(struct net_device *ndev, void *type_data);
|
||||
int enetc_setup_tc_taprio(struct net_device *ndev, void *type_data);
|
||||
void enetc_sched_speed_set(struct enetc_ndev_priv *priv, int speed);
|
||||
int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data);
|
||||
|
@ -521,6 +525,7 @@ static inline int enetc_psfp_disable(struct enetc_ndev_priv *priv)
|
|||
}
|
||||
|
||||
#else
|
||||
#define enetc_qos_query_caps(ndev, type_data) -EOPNOTSUPP
|
||||
#define enetc_setup_tc_taprio(ndev, type_data) -EOPNOTSUPP
|
||||
#define enetc_sched_speed_set(priv, speed) (void)0
|
||||
#define enetc_setup_tc_cbs(ndev, type_data) -EOPNOTSUPP
|
||||
|
|
|
@ -516,15 +516,34 @@ static void enetc_port_si_configure(struct enetc_si *si)
|
|||
enetc_port_wr(hw, ENETC_PSIVLANFMR, ENETC_PSIVLANFMR_VS);
|
||||
}
|
||||
|
||||
static void enetc_configure_port_mac(struct enetc_hw *hw)
|
||||
void enetc_set_ptcmsdur(struct enetc_hw *hw, u32 *max_sdu)
|
||||
{
|
||||
int tc;
|
||||
|
||||
enetc_port_wr(hw, ENETC_PM0_MAXFRM,
|
||||
ENETC_SET_MAXFRM(ENETC_RX_MAXFRM_SIZE));
|
||||
for (tc = 0; tc < 8; tc++) {
|
||||
u32 val = ENETC_MAC_MAXFRM_SIZE;
|
||||
|
||||
if (max_sdu[tc])
|
||||
val = max_sdu[tc] + VLAN_ETH_HLEN;
|
||||
|
||||
enetc_port_wr(hw, ENETC_PTCMSDUR(tc), val);
|
||||
}
|
||||
}
|
||||
|
||||
void enetc_reset_ptcmsdur(struct enetc_hw *hw)
|
||||
{
|
||||
int tc;
|
||||
|
||||
for (tc = 0; tc < 8; tc++)
|
||||
enetc_port_wr(hw, ENETC_PTCMSDUR(tc), ENETC_MAC_MAXFRM_SIZE);
|
||||
}
|
||||
|
||||
static void enetc_configure_port_mac(struct enetc_hw *hw)
|
||||
{
|
||||
enetc_port_wr(hw, ENETC_PM0_MAXFRM,
|
||||
ENETC_SET_MAXFRM(ENETC_RX_MAXFRM_SIZE));
|
||||
|
||||
enetc_reset_ptcmsdur(hw);
|
||||
|
||||
enetc_port_wr(hw, ENETC_PM0_CMD_CFG, ENETC_PM0_CMD_PHY_TX_EN |
|
||||
ENETC_PM0_CMD_TXP | ENETC_PM0_PROMISC);
|
||||
|
@ -738,6 +757,8 @@ static int enetc_pf_setup_tc(struct net_device *ndev, enum tc_setup_type type,
|
|||
void *type_data)
|
||||
{
|
||||
switch (type) {
|
||||
case TC_QUERY_CAPS:
|
||||
return enetc_qos_query_caps(ndev, type_data);
|
||||
case TC_SETUP_QDISC_MQPRIO:
|
||||
return enetc_setup_tc_mqprio(ndev, type_data);
|
||||
case TC_SETUP_QDISC_TAPRIO:
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <linux/math64.h>
|
||||
#include <linux/refcount.h>
|
||||
#include <net/pkt_cls.h>
|
||||
#include <net/pkt_sched.h>
|
||||
#include <net/tc_act/tc_gate.h>
|
||||
|
||||
static u16 enetc_get_max_gcl_len(struct enetc_hw *hw)
|
||||
|
@ -67,6 +68,7 @@ static int enetc_setup_taprio(struct net_device *ndev,
|
|||
tge = enetc_rd(hw, ENETC_PTGCR);
|
||||
if (!admin_conf->enable) {
|
||||
enetc_wr(hw, ENETC_PTGCR, tge & ~ENETC_PTGCR_TGE);
|
||||
enetc_reset_ptcmsdur(hw);
|
||||
|
||||
priv->active_offloads &= ~ENETC_F_QBV;
|
||||
|
||||
|
@ -122,10 +124,13 @@ static int enetc_setup_taprio(struct net_device *ndev,
|
|||
|
||||
enetc_cbd_free_data_mem(priv->si, data_size, tmp, &dma);
|
||||
|
||||
if (!err)
|
||||
priv->active_offloads |= ENETC_F_QBV;
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return err;
|
||||
enetc_set_ptcmsdur(hw, admin_conf->max_sdu);
|
||||
priv->active_offloads |= ENETC_F_QBV;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int enetc_setup_tc_taprio(struct net_device *ndev, void *type_data)
|
||||
|
@ -1594,3 +1599,23 @@ int enetc_setup_tc_psfp(struct net_device *ndev, void *type_data)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int enetc_qos_query_caps(struct net_device *ndev, void *type_data)
|
||||
{
|
||||
struct enetc_ndev_priv *priv = netdev_priv(ndev);
|
||||
struct tc_query_caps_base *base = type_data;
|
||||
struct enetc_si *si = priv->si;
|
||||
|
||||
switch (base->type) {
|
||||
case TC_SETUP_QDISC_TAPRIO: {
|
||||
struct tc_taprio_caps *caps = base->caps;
|
||||
|
||||
if (si->hw_features & ENETC_SI_F_QBV)
|
||||
caps->supports_queue_max_sdu = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue