Skip to content

Commit c5c3e1b

Browse files
rohangt07davem330
authored andcommitted
net: stmmac: Offload queueMaxSDU from tc-taprio
Add support for configuring queueMaxSDU. As DWMAC IPs doesn't support queueMaxSDU table handle this in the SW. The maximum 802.3 frame size that is allowed to be transmitted by any queue is queueMaxSDU + 16 bytes (i.e. 6 bytes SA + 6 bytes DA + 4 bytes FCS). Inspired from intel i225 driver. Signed-off-by: Rohan G Thomas <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 57bf3dd commit c5c3e1b

File tree

4 files changed

+49
-0
lines changed

4 files changed

+49
-0
lines changed

drivers/net/ethernet/stmicro/stmmac/common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ struct stmmac_extra_stats {
202202
unsigned long mtl_est_hlbf;
203203
unsigned long mtl_est_btre;
204204
unsigned long mtl_est_btrlm;
205+
unsigned long max_sdu_txq_drop[MTL_MAX_TX_QUEUES];
205206
/* per queue statistics */
206207
struct stmmac_txq_stats txq_stats[MTL_MAX_TX_QUEUES];
207208
struct stmmac_rxq_stats rxq_stats[MTL_MAX_RX_QUEUES];

drivers/net/ethernet/stmicro/stmmac/stmmac_main.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2507,6 +2507,13 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
25072507
if (!xsk_tx_peek_desc(pool, &xdp_desc))
25082508
break;
25092509

2510+
if (priv->plat->est && priv->plat->est->enable &&
2511+
priv->plat->est->max_sdu[queue] &&
2512+
xdp_desc.len > priv->plat->est->max_sdu[queue]) {
2513+
priv->xstats.max_sdu_txq_drop[queue]++;
2514+
continue;
2515+
}
2516+
25102517
if (likely(priv->extend_desc))
25112518
tx_desc = (struct dma_desc *)(tx_q->dma_etx + entry);
25122519
else if (tx_q->tbs & STMMAC_TBS_AVAIL)
@@ -4498,6 +4505,13 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
44984505
return stmmac_tso_xmit(skb, dev);
44994506
}
45004507

4508+
if (priv->plat->est && priv->plat->est->enable &&
4509+
priv->plat->est->max_sdu[queue] &&
4510+
skb->len > priv->plat->est->max_sdu[queue]){
4511+
priv->xstats.max_sdu_txq_drop[queue]++;
4512+
goto max_sdu_err;
4513+
}
4514+
45014515
if (unlikely(stmmac_tx_avail(priv, queue) < nfrags + 1)) {
45024516
if (!netif_tx_queue_stopped(netdev_get_tx_queue(dev, queue))) {
45034517
netif_tx_stop_queue(netdev_get_tx_queue(priv->dev,
@@ -4715,6 +4729,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
47154729

47164730
dma_map_err:
47174731
netdev_err(priv->dev, "Tx DMA map failed\n");
4732+
max_sdu_err:
47184733
dev_kfree_skb(skb);
47194734
priv->xstats.tx_dropped++;
47204735
return NETDEV_TX_OK;
@@ -4871,6 +4886,13 @@ static int stmmac_xdp_xmit_xdpf(struct stmmac_priv *priv, int queue,
48714886
if (stmmac_tx_avail(priv, queue) < STMMAC_TX_THRESH(priv))
48724887
return STMMAC_XDP_CONSUMED;
48734888

4889+
if (priv->plat->est && priv->plat->est->enable &&
4890+
priv->plat->est->max_sdu[queue] &&
4891+
xdpf->len > priv->plat->est->max_sdu[queue]) {
4892+
priv->xstats.max_sdu_txq_drop[queue]++;
4893+
return STMMAC_XDP_CONSUMED;
4894+
}
4895+
48744896
if (likely(priv->extend_desc))
48754897
tx_desc = (struct dma_desc *)(tx_q->dma_etx + entry);
48764898
else if (tx_q->tbs & STMMAC_TBS_AVAIL)

drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -915,6 +915,28 @@ struct timespec64 stmmac_calc_tas_basetime(ktime_t old_base_time,
915915
return time;
916916
}
917917

918+
static void tc_taprio_map_maxsdu_txq(struct stmmac_priv *priv,
919+
struct tc_taprio_qopt_offload *qopt)
920+
{
921+
struct plat_stmmacenet_data *plat = priv->plat;
922+
u32 num_tc = qopt->mqprio.qopt.num_tc;
923+
u32 offset, count, i, j;
924+
925+
/* QueueMaxSDU received from the driver corresponds to the Linux traffic
926+
* class. Map queueMaxSDU per Linux traffic class to DWMAC Tx queues.
927+
*/
928+
for (i = 0; i < num_tc; i++) {
929+
if (!qopt->max_sdu[i])
930+
continue;
931+
932+
offset = qopt->mqprio.qopt.offset[i];
933+
count = qopt->mqprio.qopt.count[i];
934+
935+
for (j = offset; j < offset + count; j++)
936+
plat->est->max_sdu[j] = qopt->max_sdu[i] + ETH_HLEN - ETH_TLEN;
937+
}
938+
}
939+
918940
static int tc_setup_taprio(struct stmmac_priv *priv,
919941
struct tc_taprio_qopt_offload *qopt)
920942
{
@@ -1045,6 +1067,8 @@ static int tc_setup_taprio(struct stmmac_priv *priv,
10451067

10461068
priv->plat->est->ter = qopt->cycle_time_extension;
10471069

1070+
tc_taprio_map_maxsdu_txq(priv, qopt);
1071+
10481072
if (fpe && !priv->dma_cap.fpesel) {
10491073
mutex_unlock(&priv->plat->est->lock);
10501074
return -EOPNOTSUPP;
@@ -1126,6 +1150,7 @@ static int tc_query_caps(struct stmmac_priv *priv,
11261150
return -EOPNOTSUPP;
11271151

11281152
caps->gate_mask_per_txq = true;
1153+
caps->supports_queue_max_sdu = true;
11291154

11301155
return 0;
11311156
}

include/linux/stmmac.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ struct stmmac_est {
127127
u32 gcl_unaligned[EST_GCL];
128128
u32 gcl[EST_GCL];
129129
u32 gcl_size;
130+
u32 max_sdu[MTL_MAX_TX_QUEUES];
130131
};
131132

132133
struct stmmac_rxq_cfg {

0 commit comments

Comments
 (0)