Skip to content

Commit 1f705bc

Browse files
joabreudavem330
authored andcommitted
net: stmmac: Add support for CBS QDISC
This adds support for CBS reconfiguration using the TC application. A new callback was added to TC ops struct and another one to DMA ops to reconfigure the channel mode. Tested in GMAC5.10. Signed-off-by: Jose Abreu <[email protected]> Cc: David S. Miller <[email protected]> Cc: Joao Pinto <[email protected]> Cc: Vitor Soares <[email protected]> Cc: Giuseppe Cavallaro <[email protected]> Cc: Alexandre Torgue <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 30408a4 commit 1f705bc

File tree

4 files changed

+87
-0
lines changed

4 files changed

+87
-0
lines changed

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,19 @@ static void dwmac4_enable_tso(void __iomem *ioaddr, bool en, u32 chan)
407407
}
408408
}
409409

410+
static void dwmac4_qmode(void __iomem *ioaddr, u32 channel, u8 qmode)
411+
{
412+
u32 mtl_tx_op = readl(ioaddr + MTL_CHAN_TX_OP_MODE(channel));
413+
414+
mtl_tx_op &= ~MTL_OP_MODE_TXQEN_MASK;
415+
if (qmode != MTL_QUEUE_AVB)
416+
mtl_tx_op |= MTL_OP_MODE_TXQEN;
417+
else
418+
mtl_tx_op |= MTL_OP_MODE_TXQEN_AV;
419+
420+
writel(mtl_tx_op, ioaddr + MTL_CHAN_TX_OP_MODE(channel));
421+
}
422+
410423
const struct stmmac_dma_ops dwmac4_dma_ops = {
411424
.reset = dwmac4_dma_reset,
412425
.init = dwmac4_dma_init,
@@ -431,6 +444,7 @@ const struct stmmac_dma_ops dwmac4_dma_ops = {
431444
.set_rx_tail_ptr = dwmac4_set_rx_tail_ptr,
432445
.set_tx_tail_ptr = dwmac4_set_tx_tail_ptr,
433446
.enable_tso = dwmac4_enable_tso,
447+
.qmode = dwmac4_qmode,
434448
};
435449

436450
const struct stmmac_dma_ops dwmac410_dma_ops = {
@@ -457,4 +471,5 @@ const struct stmmac_dma_ops dwmac410_dma_ops = {
457471
.set_rx_tail_ptr = dwmac4_set_rx_tail_ptr,
458472
.set_tx_tail_ptr = dwmac4_set_tx_tail_ptr,
459473
.enable_tso = dwmac4_enable_tso,
474+
.qmode = dwmac4_qmode,
460475
};

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ struct stmmac_dma_ops {
183183
void (*set_rx_tail_ptr)(void __iomem *ioaddr, u32 tail_ptr, u32 chan);
184184
void (*set_tx_tail_ptr)(void __iomem *ioaddr, u32 tail_ptr, u32 chan);
185185
void (*enable_tso)(void __iomem *ioaddr, bool en, u32 chan);
186+
void (*qmode)(void __iomem *ioaddr, u32 channel, u8 qmode);
186187
};
187188

188189
#define stmmac_reset(__priv, __args...) \
@@ -235,6 +236,8 @@ struct stmmac_dma_ops {
235236
stmmac_do_void_callback(__priv, dma, set_tx_tail_ptr, __args)
236237
#define stmmac_enable_tso(__priv, __args...) \
237238
stmmac_do_void_callback(__priv, dma, enable_tso, __args)
239+
#define stmmac_dma_qmode(__priv, __args...) \
240+
stmmac_do_void_callback(__priv, dma, qmode, __args)
238241

239242
struct mac_device_info;
240243
struct net_device;
@@ -441,17 +444,22 @@ struct stmmac_mode_ops {
441444

442445
struct stmmac_priv;
443446
struct tc_cls_u32_offload;
447+
struct tc_cbs_qopt_offload;
444448

445449
struct stmmac_tc_ops {
446450
int (*init)(struct stmmac_priv *priv);
447451
int (*setup_cls_u32)(struct stmmac_priv *priv,
448452
struct tc_cls_u32_offload *cls);
453+
int (*setup_cbs)(struct stmmac_priv *priv,
454+
struct tc_cbs_qopt_offload *qopt);
449455
};
450456

451457
#define stmmac_tc_init(__priv, __args...) \
452458
stmmac_do_callback(__priv, tc, init, __args)
453459
#define stmmac_tc_setup_cls_u32(__priv, __args...) \
454460
stmmac_do_callback(__priv, tc, setup_cls_u32, __args)
461+
#define stmmac_tc_setup_cbs(__priv, __args...) \
462+
stmmac_do_callback(__priv, tc, setup_cbs, __args)
455463

456464
struct stmmac_regs_off {
457465
u32 ptp_off;

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3793,6 +3793,8 @@ static int stmmac_setup_tc(struct net_device *ndev, enum tc_setup_type type,
37933793
switch (type) {
37943794
case TC_SETUP_BLOCK:
37953795
return stmmac_setup_tc_block(priv, type_data);
3796+
case TC_SETUP_QDISC_CBS:
3797+
return stmmac_tc_setup_cbs(priv, priv, type_data);
37963798
default:
37973799
return -EOPNOTSUPP;
37983800
}

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

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,69 @@ static int tc_init(struct stmmac_priv *priv)
289289
return 0;
290290
}
291291

292+
static int tc_setup_cbs(struct stmmac_priv *priv,
293+
struct tc_cbs_qopt_offload *qopt)
294+
{
295+
u32 tx_queues_count = priv->plat->tx_queues_to_use;
296+
u32 queue = qopt->queue;
297+
u32 ptr, speed_div;
298+
u32 mode_to_use;
299+
u64 value;
300+
int ret;
301+
302+
/* Queue 0 is not AVB capable */
303+
if (queue <= 0 || queue >= tx_queues_count)
304+
return -EINVAL;
305+
if (priv->speed != SPEED_100 && priv->speed != SPEED_1000)
306+
return -EOPNOTSUPP;
307+
308+
mode_to_use = priv->plat->tx_queues_cfg[queue].mode_to_use;
309+
if (mode_to_use == MTL_QUEUE_DCB && qopt->enable) {
310+
ret = stmmac_dma_qmode(priv, priv->ioaddr, queue, MTL_QUEUE_AVB);
311+
if (ret)
312+
return ret;
313+
314+
priv->plat->tx_queues_cfg[queue].mode_to_use = MTL_QUEUE_AVB;
315+
} else if (!qopt->enable) {
316+
return stmmac_dma_qmode(priv, priv->ioaddr, queue, MTL_QUEUE_DCB);
317+
}
318+
319+
/* Port Transmit Rate and Speed Divider */
320+
ptr = (priv->speed == SPEED_100) ? 4 : 8;
321+
speed_div = (priv->speed == SPEED_100) ? 100000 : 1000000;
322+
323+
/* Final adjustments for HW */
324+
value = qopt->idleslope * 1024 * ptr;
325+
do_div(value, speed_div);
326+
priv->plat->tx_queues_cfg[queue].idle_slope = value & GENMASK(31, 0);
327+
328+
value = -qopt->sendslope * 1024UL * ptr;
329+
do_div(value, speed_div);
330+
priv->plat->tx_queues_cfg[queue].send_slope = value & GENMASK(31, 0);
331+
332+
value = qopt->hicredit * 1024 * 8;
333+
priv->plat->tx_queues_cfg[queue].high_credit = value & GENMASK(31, 0);
334+
335+
value = qopt->locredit * 1024 * 8;
336+
priv->plat->tx_queues_cfg[queue].low_credit = value & GENMASK(31, 0);
337+
338+
ret = stmmac_config_cbs(priv, priv->hw,
339+
priv->plat->tx_queues_cfg[queue].send_slope,
340+
priv->plat->tx_queues_cfg[queue].idle_slope,
341+
priv->plat->tx_queues_cfg[queue].high_credit,
342+
priv->plat->tx_queues_cfg[queue].low_credit,
343+
queue);
344+
if (ret)
345+
return ret;
346+
347+
dev_info(priv->device, "CBS queue %d: send %d, idle %d, hi %d, lo %d\n",
348+
queue, qopt->sendslope, qopt->idleslope,
349+
qopt->hicredit, qopt->locredit);
350+
return 0;
351+
}
352+
292353
const struct stmmac_tc_ops dwmac510_tc_ops = {
293354
.init = tc_init,
294355
.setup_cls_u32 = tc_setup_cls_u32,
356+
.setup_cbs = tc_setup_cbs,
295357
};

0 commit comments

Comments
 (0)