Skip to content

Commit

Permalink
net: enetc: add support for preemptible traffic classes
Browse files Browse the repository at this point in the history
PFs which support the MAC Merge layer also have a set of 8 registers
called "Port traffic class N frame preemption register (PTC0FPR - PTC7FPR)".
Through these, a traffic class (group of TX rings of same dequeue
priority) can be mapped to the eMAC or to the pMAC.

There's nothing particularly spectacular here. We should probably only
commit the preemptible TCs to hardware once the MAC Merge layer became
active, but unlike Felix, we don't have an IRQ that notifies us of that.
We'd have to sleep for up to verifyTime (127 ms) to wait for a
resolution coming from the verification state machine; not only from the
ndo_setup_tc() code path, but also from enetc_mm_link_state_update().
Since it's relatively complicated and has a relatively small benefit,
I'm not doing it.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Ferenc Fejes <fejes@inf.elte.hu>
Reviewed-by: Simon Horman <simon.horman@corigine.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Vladimir Oltean authored and Jakub Kicinski committed Apr 14, 2023
1 parent 50764da commit 01e23b2
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 0 deletions.
22 changes: 22 additions & 0 deletions drivers/net/ethernet/freescale/enetc/enetc.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,24 @@ void enetc_port_mac_wr(struct enetc_si *si, u32 reg, u32 val)
}
EXPORT_SYMBOL_GPL(enetc_port_mac_wr);

void enetc_set_ptcfpr(struct enetc_hw *hw, unsigned long preemptible_tcs)
{
u32 val;
int tc;

for (tc = 0; tc < 8; tc++) {
val = enetc_port_rd(hw, ENETC_PTCFPR(tc));

if (preemptible_tcs & BIT(tc))
val |= ENETC_PTCFPR_FPE;
else
val &= ~ENETC_PTCFPR_FPE;

enetc_port_wr(hw, ENETC_PTCFPR(tc), val);
}
}
EXPORT_SYMBOL_GPL(enetc_set_ptcfpr);

static int enetc_num_stack_tx_queues(struct enetc_ndev_priv *priv)
{
int num_tx_rings = priv->num_tx_rings;
Expand Down Expand Up @@ -2640,6 +2658,8 @@ static void enetc_reset_tc_mqprio(struct net_device *ndev)
}

enetc_debug_tx_ring_prios(priv);

enetc_set_ptcfpr(hw, 0);
}

int enetc_setup_tc_mqprio(struct net_device *ndev, void *type_data)
Expand Down Expand Up @@ -2694,6 +2714,8 @@ int enetc_setup_tc_mqprio(struct net_device *ndev, void *type_data)

enetc_debug_tx_ring_prios(priv);

enetc_set_ptcfpr(hw, mqprio->preemptible_tcs);

return 0;

err_reset_tc:
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/freescale/enetc/enetc.h
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,7 @@ static inline void enetc_cbd_free_data_mem(struct enetc_si *si, int size,

void enetc_reset_ptcmsdur(struct enetc_hw *hw);
void enetc_set_ptcmsdur(struct enetc_hw *hw, u32 *queue_max_sdu);
void enetc_set_ptcfpr(struct enetc_hw *hw, unsigned long preemptible_tcs);

#ifdef CONFIG_FSL_ENETC_QOS
int enetc_qos_query_caps(struct net_device *ndev, void *type_data);
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/freescale/enetc/enetc_hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -965,6 +965,10 @@ static inline u32 enetc_usecs_to_cycles(u32 usecs)
return (u32)div_u64(usecs * ENETC_CLK, 1000000ULL);
}

/* Port traffic class frame preemption register */
#define ENETC_PTCFPR(n) (0x1910 + (n) * 4) /* n = [0 ..7] */
#define ENETC_PTCFPR_FPE BIT(31)

/* port time gating control register */
#define ENETC_PTGCR 0x11a00
#define ENETC_PTGCR_TGE BIT(31)
Expand Down

0 comments on commit 01e23b2

Please sign in to comment.