Skip to content

Commit cce2991

Browse files
committed
Merge branch 'net-stmmac-fpe-via-ethtool-tc'
Furong Xu says: ==================== net: stmmac: FPE via ethtool + tc Move the Frame Preemption(FPE) over to the new standard API which uses ethtool-mm/tc-mqprio/tc-taprio. ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 525034e + 22a805d commit cce2991

File tree

11 files changed

+497
-243
lines changed

11 files changed

+497
-243
lines changed

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,6 @@ static void dwmac4_core_init(struct mac_device_info *hw,
5858
if (hw->pcs)
5959
value |= GMAC_PCS_IRQ_DEFAULT;
6060

61-
/* Enable FPE interrupt */
62-
if ((GMAC_HW_FEAT_FPESEL & readl(ioaddr + GMAC_HW_FEATURE3)) >> 26)
63-
value |= GMAC_INT_FPE_EN;
64-
6561
writel(value, ioaddr + GMAC_INT_EN);
6662

6763
if (GMAC_INT_DEFAULT_ENABLE & GMAC_INT_TSIE)
@@ -1268,6 +1264,9 @@ const struct stmmac_ops dwmac410_ops = {
12681264
.fpe_configure = dwmac5_fpe_configure,
12691265
.fpe_send_mpacket = dwmac5_fpe_send_mpacket,
12701266
.fpe_irq_status = dwmac5_fpe_irq_status,
1267+
.fpe_get_add_frag_size = dwmac5_fpe_get_add_frag_size,
1268+
.fpe_set_add_frag_size = dwmac5_fpe_set_add_frag_size,
1269+
.fpe_map_preemption_class = dwmac5_fpe_map_preemption_class,
12711270
.add_hw_vlan_rx_fltr = dwmac4_add_hw_vlan_rx_fltr,
12721271
.del_hw_vlan_rx_fltr = dwmac4_del_hw_vlan_rx_fltr,
12731272
.restore_hw_vlan_rx_fltr = dwmac4_restore_hw_vlan_rx_fltr,
@@ -1320,6 +1319,9 @@ const struct stmmac_ops dwmac510_ops = {
13201319
.fpe_configure = dwmac5_fpe_configure,
13211320
.fpe_send_mpacket = dwmac5_fpe_send_mpacket,
13221321
.fpe_irq_status = dwmac5_fpe_irq_status,
1322+
.fpe_get_add_frag_size = dwmac5_fpe_get_add_frag_size,
1323+
.fpe_set_add_frag_size = dwmac5_fpe_set_add_frag_size,
1324+
.fpe_map_preemption_class = dwmac5_fpe_map_preemption_class,
13231325
.add_hw_vlan_rx_fltr = dwmac4_add_hw_vlan_rx_fltr,
13241326
.del_hw_vlan_rx_fltr = dwmac4_del_hw_vlan_rx_fltr,
13251327
.restore_hw_vlan_rx_fltr = dwmac4_restore_hw_vlan_rx_fltr,

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

Lines changed: 90 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -575,11 +575,11 @@ int dwmac5_flex_pps_config(void __iomem *ioaddr, int index,
575575

576576
void dwmac5_fpe_configure(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg,
577577
u32 num_txq, u32 num_rxq,
578-
bool enable)
578+
bool tx_enable, bool pmac_enable)
579579
{
580580
u32 value;
581581

582-
if (enable) {
582+
if (tx_enable) {
583583
cfg->fpe_csr = EFPE;
584584
value = readl(ioaddr + GMAC_RXQ_CTRL1);
585585
value &= ~GMAC_RXQCTRL_FPRQ;
@@ -589,6 +589,21 @@ void dwmac5_fpe_configure(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg,
589589
cfg->fpe_csr = 0;
590590
}
591591
writel(cfg->fpe_csr, ioaddr + MAC_FPE_CTRL_STS);
592+
593+
value = readl(ioaddr + GMAC_INT_EN);
594+
595+
if (pmac_enable) {
596+
if (!(value & GMAC_INT_FPE_EN)) {
597+
/* Dummy read to clear any pending masked interrupts */
598+
readl(ioaddr + MAC_FPE_CTRL_STS);
599+
600+
value |= GMAC_INT_FPE_EN;
601+
}
602+
} else {
603+
value &= ~GMAC_INT_FPE_EN;
604+
}
605+
606+
writel(value, ioaddr + GMAC_INT_EN);
592607
}
593608

594609
int dwmac5_fpe_irq_status(void __iomem *ioaddr, struct net_device *dev)
@@ -605,22 +620,22 @@ int dwmac5_fpe_irq_status(void __iomem *ioaddr, struct net_device *dev)
605620

606621
if (value & TRSP) {
607622
status |= FPE_EVENT_TRSP;
608-
netdev_info(dev, "FPE: Respond mPacket is transmitted\n");
623+
netdev_dbg(dev, "FPE: Respond mPacket is transmitted\n");
609624
}
610625

611626
if (value & TVER) {
612627
status |= FPE_EVENT_TVER;
613-
netdev_info(dev, "FPE: Verify mPacket is transmitted\n");
628+
netdev_dbg(dev, "FPE: Verify mPacket is transmitted\n");
614629
}
615630

616631
if (value & RRSP) {
617632
status |= FPE_EVENT_RRSP;
618-
netdev_info(dev, "FPE: Respond mPacket is received\n");
633+
netdev_dbg(dev, "FPE: Respond mPacket is received\n");
619634
}
620635

621636
if (value & RVER) {
622637
status |= FPE_EVENT_RVER;
623-
netdev_info(dev, "FPE: Verify mPacket is received\n");
638+
netdev_dbg(dev, "FPE: Verify mPacket is received\n");
624639
}
625640

626641
return status;
@@ -638,3 +653,72 @@ void dwmac5_fpe_send_mpacket(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg,
638653

639654
writel(value, ioaddr + MAC_FPE_CTRL_STS);
640655
}
656+
657+
int dwmac5_fpe_get_add_frag_size(const void __iomem *ioaddr)
658+
{
659+
return FIELD_GET(DWMAC5_ADD_FRAG_SZ, readl(ioaddr + MTL_FPE_CTRL_STS));
660+
}
661+
662+
void dwmac5_fpe_set_add_frag_size(void __iomem *ioaddr, u32 add_frag_size)
663+
{
664+
u32 value;
665+
666+
value = readl(ioaddr + MTL_FPE_CTRL_STS);
667+
writel(u32_replace_bits(value, add_frag_size, DWMAC5_ADD_FRAG_SZ),
668+
ioaddr + MTL_FPE_CTRL_STS);
669+
}
670+
671+
#define ALG_ERR_MSG "TX algorithm SP is not suitable for one-to-many mapping"
672+
#define WEIGHT_ERR_MSG "TXQ weight %u differs across other TXQs in TC: [%u]"
673+
674+
int dwmac5_fpe_map_preemption_class(struct net_device *ndev,
675+
struct netlink_ext_ack *extack, u32 pclass)
676+
{
677+
u32 val, offset, count, queue_weight, preemptible_txqs = 0;
678+
struct stmmac_priv *priv = netdev_priv(ndev);
679+
u32 num_tc = ndev->num_tc;
680+
681+
if (!pclass)
682+
goto update_mapping;
683+
684+
/* DWMAC CORE4+ can not program TC:TXQ mapping to hardware.
685+
*
686+
* Synopsys Databook:
687+
* "The number of Tx DMA channels is equal to the number of Tx queues,
688+
* and is direct one-to-one mapping."
689+
*/
690+
for (u32 tc = 0; tc < num_tc; tc++) {
691+
count = ndev->tc_to_txq[tc].count;
692+
offset = ndev->tc_to_txq[tc].offset;
693+
694+
if (pclass & BIT(tc))
695+
preemptible_txqs |= GENMASK(offset + count - 1, offset);
696+
697+
/* This is 1:1 mapping, go to next TC */
698+
if (count == 1)
699+
continue;
700+
701+
if (priv->plat->tx_sched_algorithm == MTL_TX_ALGORITHM_SP) {
702+
NL_SET_ERR_MSG_MOD(extack, ALG_ERR_MSG);
703+
return -EINVAL;
704+
}
705+
706+
queue_weight = priv->plat->tx_queues_cfg[offset].weight;
707+
708+
for (u32 i = 1; i < count; i++) {
709+
if (priv->plat->tx_queues_cfg[offset + i].weight !=
710+
queue_weight) {
711+
NL_SET_ERR_MSG_FMT_MOD(extack, WEIGHT_ERR_MSG,
712+
queue_weight, tc);
713+
return -EINVAL;
714+
}
715+
}
716+
}
717+
718+
update_mapping:
719+
val = readl(priv->ioaddr + MTL_FPE_CTRL_STS);
720+
writel(u32_replace_bits(val, preemptible_txqs, DWMAC5_PREEMPTION_CLASS),
721+
priv->ioaddr + MTL_FPE_CTRL_STS);
722+
723+
return 0;
724+
}

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@
3939
#define MAC_PPSx_INTERVAL(x) (0x00000b88 + ((x) * 0x10))
4040
#define MAC_PPSx_WIDTH(x) (0x00000b8c + ((x) * 0x10))
4141

42+
#define MTL_FPE_CTRL_STS 0x00000c90
43+
/* Preemption Classification */
44+
#define DWMAC5_PREEMPTION_CLASS GENMASK(15, 8)
45+
/* Additional Fragment Size of preempted frames */
46+
#define DWMAC5_ADD_FRAG_SZ GENMASK(1, 0)
47+
4248
#define MTL_RXP_CONTROL_STATUS 0x00000ca0
4349
#define RXPI BIT(31)
4450
#define NPE GENMASK(23, 16)
@@ -104,10 +110,14 @@ int dwmac5_flex_pps_config(void __iomem *ioaddr, int index,
104110
u32 sub_second_inc, u32 systime_flags);
105111
void dwmac5_fpe_configure(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg,
106112
u32 num_txq, u32 num_rxq,
107-
bool enable);
113+
bool tx_enable, bool pmac_enable);
108114
void dwmac5_fpe_send_mpacket(void __iomem *ioaddr,
109115
struct stmmac_fpe_cfg *cfg,
110116
enum stmmac_mpacket_type type);
111117
int dwmac5_fpe_irq_status(void __iomem *ioaddr, struct net_device *dev);
118+
int dwmac5_fpe_get_add_frag_size(const void __iomem *ioaddr);
119+
void dwmac5_fpe_set_add_frag_size(void __iomem *ioaddr, u32 add_frag_size);
120+
int dwmac5_fpe_map_preemption_class(struct net_device *ndev,
121+
struct netlink_ext_ack *extack, u32 pclass);
112122

113123
#endif /* __DWMAC5_H__ */

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1504,13 +1504,14 @@ static void dwxgmac2_set_arp_offload(struct mac_device_info *hw, bool en,
15041504
writel(value, ioaddr + XGMAC_RX_CONFIG);
15051505
}
15061506

1507-
static void dwxgmac3_fpe_configure(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg,
1508-
u32 num_txq,
1509-
u32 num_rxq, bool enable)
1507+
static void dwxgmac3_fpe_configure(void __iomem *ioaddr,
1508+
struct stmmac_fpe_cfg *cfg,
1509+
u32 num_txq, u32 num_rxq,
1510+
bool tx_enable, bool pmac_enable)
15101511
{
15111512
u32 value;
15121513

1513-
if (!enable) {
1514+
if (!tx_enable) {
15141515
value = readl(ioaddr + XGMAC_FPE_CTRL_STS);
15151516

15161517
value &= ~XGMAC_EFPE;

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ static const struct stmmac_hwif_entry {
171171
.mac = &dwmac4_ops,
172172
.hwtimestamp = &stmmac_ptp,
173173
.mode = NULL,
174-
.tc = &dwmac510_tc_ops,
174+
.tc = &dwmac4_tc_ops,
175175
.mmc = &dwmac_mmc_ops,
176176
.est = &dwmac510_est_ops,
177177
.setup = dwmac4_setup,
@@ -252,7 +252,7 @@ static const struct stmmac_hwif_entry {
252252
.mac = &dwxgmac210_ops,
253253
.hwtimestamp = &stmmac_ptp,
254254
.mode = NULL,
255-
.tc = &dwmac510_tc_ops,
255+
.tc = &dwxgmac_tc_ops,
256256
.mmc = &dwxgmac_mmc_ops,
257257
.est = &dwmac510_est_ops,
258258
.setup = dwxgmac2_setup,
@@ -273,7 +273,7 @@ static const struct stmmac_hwif_entry {
273273
.mac = &dwxlgmac2_ops,
274274
.hwtimestamp = &stmmac_ptp,
275275
.mode = NULL,
276-
.tc = &dwmac510_tc_ops,
276+
.tc = &dwxgmac_tc_ops,
277277
.mmc = &dwxgmac_mmc_ops,
278278
.est = &dwmac510_est_ops,
279279
.setup = dwxlgmac2_setup,

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

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include <linux/netdevice.h>
99
#include <linux/stmmac.h>
10+
#include <net/pkt_cls.h>
1011

1112
#define stmmac_do_void_callback(__priv, __module, __cname, __arg0, __args...) \
1213
({ \
@@ -28,6 +29,8 @@
2829
struct stmmac_extra_stats;
2930
struct stmmac_priv;
3031
struct stmmac_safety_stats;
32+
struct stmmac_fpe_cfg;
33+
enum stmmac_mpacket_type;
3134
struct dma_desc;
3235
struct dma_extended_desc;
3336
struct dma_edesc;
@@ -419,11 +422,16 @@ struct stmmac_ops {
419422
void (*set_arp_offload)(struct mac_device_info *hw, bool en, u32 addr);
420423
void (*fpe_configure)(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg,
421424
u32 num_txq, u32 num_rxq,
422-
bool enable);
425+
bool tx_enable, bool pmac_enable);
423426
void (*fpe_send_mpacket)(void __iomem *ioaddr,
424427
struct stmmac_fpe_cfg *cfg,
425428
enum stmmac_mpacket_type type);
426429
int (*fpe_irq_status)(void __iomem *ioaddr, struct net_device *dev);
430+
int (*fpe_get_add_frag_size)(const void __iomem *ioaddr);
431+
void (*fpe_set_add_frag_size)(void __iomem *ioaddr, u32 add_frag_size);
432+
int (*fpe_map_preemption_class)(struct net_device *ndev,
433+
struct netlink_ext_ack *extack,
434+
u32 pclass);
427435
};
428436

429437
#define stmmac_core_init(__priv, __args...) \
@@ -528,6 +536,12 @@ struct stmmac_ops {
528536
stmmac_do_void_callback(__priv, mac, fpe_send_mpacket, __args)
529537
#define stmmac_fpe_irq_status(__priv, __args...) \
530538
stmmac_do_callback(__priv, mac, fpe_irq_status, __args)
539+
#define stmmac_fpe_get_add_frag_size(__priv, __args...) \
540+
stmmac_do_callback(__priv, mac, fpe_get_add_frag_size, __args)
541+
#define stmmac_fpe_set_add_frag_size(__priv, __args...) \
542+
stmmac_do_void_callback(__priv, mac, fpe_set_add_frag_size, __args)
543+
#define stmmac_fpe_map_preemption_class(__priv, __args...) \
544+
stmmac_do_void_callback(__priv, mac, fpe_map_preemption_class, __args)
531545

532546
/* PTP and HW Timer helpers */
533547
struct stmmac_hwtimestamp {
@@ -615,6 +629,8 @@ struct stmmac_tc_ops {
615629
struct tc_etf_qopt_offload *qopt);
616630
int (*query_caps)(struct stmmac_priv *priv,
617631
struct tc_query_caps_base *base);
632+
int (*setup_mqprio)(struct stmmac_priv *priv,
633+
struct tc_mqprio_qopt_offload *qopt);
618634
};
619635

620636
#define stmmac_tc_init(__priv, __args...) \
@@ -631,6 +647,8 @@ struct stmmac_tc_ops {
631647
stmmac_do_callback(__priv, tc, setup_etf, __args)
632648
#define stmmac_tc_query_caps(__priv, __args...) \
633649
stmmac_do_callback(__priv, tc, query_caps, __args)
650+
#define stmmac_tc_setup_mqprio(__priv, __args...) \
651+
stmmac_do_callback(__priv, tc, setup_mqprio, __args)
634652

635653
struct stmmac_counters;
636654

@@ -674,7 +692,9 @@ extern const struct stmmac_dma_ops dwmac4_dma_ops;
674692
extern const struct stmmac_ops dwmac410_ops;
675693
extern const struct stmmac_dma_ops dwmac410_dma_ops;
676694
extern const struct stmmac_ops dwmac510_ops;
695+
extern const struct stmmac_tc_ops dwmac4_tc_ops;
677696
extern const struct stmmac_tc_ops dwmac510_tc_ops;
697+
extern const struct stmmac_tc_ops dwxgmac_tc_ops;
678698
extern const struct stmmac_ops dwxgmac210_ops;
679699
extern const struct stmmac_ops dwxlgmac2_ops;
680700
extern const struct stmmac_dma_ops dwxgmac210_dma_ops;

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

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,32 @@ struct stmmac_channel {
146146
u32 index;
147147
};
148148

149+
/* FPE link-partner hand-shaking mPacket type */
150+
enum stmmac_mpacket_type {
151+
MPACKET_VERIFY = 0,
152+
MPACKET_RESPONSE = 1,
153+
};
154+
155+
#define STMMAC_FPE_MM_MAX_VERIFY_RETRIES 3
156+
#define STMMAC_FPE_MM_MAX_VERIFY_TIME_MS 128
157+
158+
struct stmmac_fpe_cfg {
159+
/* Serialize access to MAC Merge state between ethtool requests
160+
* and link state updates.
161+
*/
162+
spinlock_t lock;
163+
164+
u32 fpe_csr; /* MAC_FPE_CTRL_STS reg cache */
165+
166+
enum ethtool_mm_verify_status status;
167+
struct timer_list verify_timer;
168+
bool verify_enabled;
169+
int verify_retries;
170+
bool pmac_enabled;
171+
u32 verify_time;
172+
bool tx_enabled;
173+
};
174+
149175
struct stmmac_tc_entry {
150176
bool in_use;
151177
bool in_hw;
@@ -339,11 +365,8 @@ struct stmmac_priv {
339365
struct workqueue_struct *wq;
340366
struct work_struct service_task;
341367

342-
/* Workqueue for handling FPE hand-shaking */
343-
unsigned long fpe_task_state;
344-
struct workqueue_struct *fpe_wq;
345-
struct work_struct fpe_task;
346-
char wq_name[IFNAMSIZ + 4];
368+
/* Frame Preemption feature (FPE) */
369+
struct stmmac_fpe_cfg fpe_cfg;
347370

348371
/* TC Handling */
349372
unsigned int tc_entries_max;
@@ -397,7 +420,7 @@ bool stmmac_eee_init(struct stmmac_priv *priv);
397420
int stmmac_reinit_queues(struct net_device *dev, u32 rx_cnt, u32 tx_cnt);
398421
int stmmac_reinit_ringparam(struct net_device *dev, u32 rx_size, u32 tx_size);
399422
int stmmac_bus_clks_config(struct stmmac_priv *priv, bool enabled);
400-
void stmmac_fpe_handshake(struct stmmac_priv *priv, bool enable);
423+
void stmmac_fpe_apply(struct stmmac_priv *priv);
401424

402425
static inline bool stmmac_xdp_is_enabled(struct stmmac_priv *priv)
403426
{

0 commit comments

Comments
 (0)