net: stmmac: FPE via ethtool + tc
Subsystems (4)
v4 cover 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.
Changes in v4:
1. reorder FPE-related declarations and definitions into clean groups
2. move mm_lock to stmmac_fpe_cfg.lock
3. protect user configurations across NIC up/down
4. block stmmac_set_mm() when fpe_task is in progress to finish
5. convert to ethtool_dev_mm_supported() to check FPE capability in tc-mqprio/tc-taprio
6. silence FPE workqueue start/stop logs
Changes in v3:
1. avoid races among ISR, workqueue, link update and register configuration.
2. update FPE verification retry logic, so it retries and fails as expected.
Changes in v2:
1. refactor FPE verification processe
2. suspend/resume and kselftest-ethtool_mm, all test cases passed
3. handle TC:TXQ remapping for DWMAC CORE4+
Furong Xu (7):
net: stmmac: move stmmac_fpe_cfg to stmmac_priv data
net: stmmac: drop stmmac_fpe_handshake
net: stmmac: refactor FPE verification process
net: stmmac: configure FPE via ethtool-mm
net: stmmac: support fp parameter of tc-mqprio
net: stmmac: support fp parameter of tc-taprio
net: stmmac: silence FPE kernel logs
.../net/ethernet/stmicro/stmmac/dwmac4_core.c | 10 +- drivers/net/ethernet/stmicro/stmmac/dwmac5.c | 96 +++++++- drivers/net/ethernet/stmicro/stmmac/dwmac5.h | 11 +- .../ethernet/stmicro/stmmac/dwxgmac2_core.c | 4 +- drivers/net/ethernet/stmicro/stmmac/hwif.h | 20 +- drivers/net/ethernet/stmicro/stmmac/stmmac.h | 27 ++- .../ethernet/stmicro/stmmac/stmmac_ethtool.c | 110 +++++++++ .../net/ethernet/stmicro/stmmac/stmmac_main.c | 214 +++++++++--------- .../net/ethernet/stmicro/stmmac/stmmac_tc.c | 124 +++++++--- include/linux/stmmac.h | 28 --- 10 files changed, 463 insertions(+), 181 deletions(-)
Signature · 1 line
2.34.1
PATCH v4 1/7 net: stmmac: move stmmac_fpe_cfg to stmmac_priv data
By moving the fpe_cfg field to the stmmac_priv data, stmmac_fpe_cfg becomes platform-data eventually, instead of a run-time config.
--- drivers/net/ethernet/stmicro/stmmac/hwif.h | 2 ++ drivers/net/ethernet/stmicro/stmmac/stmmac.h | 30 ++++++++++++++++++- .../net/ethernet/stmicro/stmmac/stmmac_main.c | 20 ++++++------- .../net/ethernet/stmicro/stmmac/stmmac_tc.c | 16 ++-------- include/linux/stmmac.h | 28 ----------------- 5 files changed, 44 insertions(+), 52 deletions(-)
drivers/net/ethernet/stmicro/stmmac/hwif.h +2 -0
@@ -26,6 +26,8 @@ })struct stmmac_extra_stats ; +struct stmmac_fpe_cfg ; +enum stmmac_mpacket_type ;struct stmmac_priv ;struct stmmac_safety_stats ;struct dma_desc ;
drivers/net/ethernet/stmicro/stmmac/stmmac.h +29 -1
@@ -146,6 +146,33 @@ struct stmmac_channel {u32 index; }; +/* FPE link state */ +enum stmmac_fpe_state { +FPE_STATE_OFF =0 , +FPE_STATE_CAPABLE =1 , +FPE_STATE_ENTERING_ON =2 , +FPE_STATE_ON =3 , +}; + +/* FPE link-partner hand-shaking mPacket type */ +enum stmmac_mpacket_type { +MPACKET_VERIFY =0 , +MPACKET_RESPONSE =1 , +}; + +enum stmmac_fpe_task_state_t { + __FPE_REMOVING, + __FPE_TASK_SCHED, +}; + +struct stmmac_fpe_cfg { +bool enable;/* FPE enable */ +bool hs_enable;/* FPE handshake enable */ +enum stmmac_fpe_state lp_fpe_state;/* Link Partner FPE state */ +enum stmmac_fpe_state lo_fpe_state;/* Local station FPE state */ +u32 fpe_csr;/* MAC_FPE_CTRL_STS reg cache */ +}; +struct stmmac_tc_entry {bool in_use;bool in_hw;
@@ -339,11 +366,12 @@ struct stmmac_priv {struct workqueue_struct *wq;struct work_struct service_task; -/* Workqueue for handling FPE hand-shaking */ +/* Frame Preemption feature (FPE) */ unsigned long fpe_task_state;struct workqueue_struct *fpe_wq;struct work_struct fpe_task;char wq_name[IFNAMSIZ +4 ]; +struct stmmac_fpe_cfg fpe_cfg;/* TC Handling */ unsigned int tc_entries_max;
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +10 -10
@@ -968,7 +968,7 @@ static void stmmac_mac_config(struct phylink_config *config, unsigned int mode,static void stmmac_fpe_link_state_handle (struct stmmac_priv *priv,bool is_up) { -struct stmmac_fpe_cfg *fpe_cfg = priv->plat->fpe_cfg; +struct stmmac_fpe_cfg *fpe_cfg = &priv->fpe_cfg;enum stmmac_fpe_state *lo_state = &fpe_cfg->lo_fpe_state;enum stmmac_fpe_state *lp_state = &fpe_cfg->lp_fpe_state;bool *hs_enable = &fpe_cfg->hs_enable;
@@ -3536,7 +3536,7 @@ static int stmmac_hw_setup(struct net_device *dev, bool ptp_register)if (priv->dma_cap.fpesel) {stmmac_fpe_start_wq (priv); -if (priv->plat->fpe_cfg->enable) +if (priv->fpe_cfg.enable)stmmac_fpe_handshake (priv, true); }
@@ -5982,7 +5982,7 @@ static int stmmac_set_features(struct net_device *netdev,static void stmmac_fpe_event_status (struct stmmac_priv *priv,int status) { -struct stmmac_fpe_cfg *fpe_cfg = priv->plat->fpe_cfg; +struct stmmac_fpe_cfg *fpe_cfg = &priv->fpe_cfg;enum stmmac_fpe_state *lo_state = &fpe_cfg->lo_fpe_state;enum stmmac_fpe_state *lp_state = &fpe_cfg->lp_fpe_state;bool *hs_enable = &fpe_cfg->hs_enable;
@@ -7381,7 +7381,7 @@ static void stmmac_fpe_lp_task(struct work_struct *work) { struct stmmac_priv *priv = container_of(work, struct stmmac_priv, fpe_task); -struct stmmac_fpe_cfg *fpe_cfg = priv->plat->fpe_cfg; +struct stmmac_fpe_cfg *fpe_cfg = &priv->fpe_cfg;enum stmmac_fpe_state *lo_state = &fpe_cfg->lo_fpe_state;enum stmmac_fpe_state *lp_state = &fpe_cfg->lp_fpe_state;bool *hs_enable = &fpe_cfg->hs_enable;
@@ -7427,17 +7427,17 @@ static void stmmac_fpe_lp_task(struct work_struct *work)void stmmac_fpe_handshake (struct stmmac_priv *priv,bool enable) { -if (priv->plat->fpe_cfg->hs_enable != enable) { +if (priv->fpe_cfg.hs_enable != enable) {if (enable) {stmmac_fpe_send_mpacket (priv, priv->ioaddr, - priv->plat->fpe_cfg, + &priv->fpe_cfg,MPACKET_VERIFY ); }else { - priv->plat->fpe_cfg->lo_fpe_state =FPE_STATE_OFF ; - priv->plat->fpe_cfg->lp_fpe_state =FPE_STATE_OFF ; + priv->fpe_cfg.lo_fpe_state =FPE_STATE_OFF ; + priv->fpe_cfg.lp_fpe_state =FPE_STATE_OFF ; } - priv->plat->fpe_cfg->hs_enable = enable; + priv->fpe_cfg.hs_enable = enable; } }
@@ -7898,7 +7898,7 @@ int stmmac_suspend(struct device *dev)if (priv->dma_cap.fpesel) {/* Disable FPE */ stmmac_fpe_configure (priv, priv->ioaddr, - priv->plat->fpe_cfg, + &priv->fpe_cfg, priv->plat->tx_queues_to_use, priv->plat->rx_queues_to_use, false);
drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c +3 -13
@@ -282,16 +282,6 @@ static int tc_init(struct stmmac_priv *priv)if (ret)return -ENOMEM ; -if (!priv->plat->fpe_cfg) { - priv->plat->fpe_cfg =devm_kzalloc (priv->device, -sizeof (*priv->plat->fpe_cfg), -GFP_KERNEL ); -if (!priv->plat->fpe_cfg) -return -ENOMEM ; - }else { -memset (priv->plat->fpe_cfg,0 ,sizeof (*priv->plat->fpe_cfg)); - } -/* Fail silently as we can still use remaining features, e.g. CBS */ if (!dma_cap->frpsel)return 0 ;
@@ -1076,7 +1066,7 @@ static int tc_taprio_configure(struct stmmac_priv *priv,/* Actual FPE register configuration will be done after FPE handshake * is success. */ - priv->plat->fpe_cfg->enable = fpe; + priv->fpe_cfg.enable = fpe; ret =stmmac_est_configure (priv, priv, priv->est, priv->plat->clk_ptp_rate);
@@ -1109,9 +1099,9 @@ static int tc_taprio_configure(struct stmmac_priv *priv,mutex_unlock (&priv->est_lock); } - priv->plat->fpe_cfg->enable = false; + priv->fpe_cfg.enable = false;stmmac_fpe_configure (priv, priv->ioaddr, - priv->plat->fpe_cfg, + &priv->fpe_cfg, priv->plat->tx_queues_to_use, priv->plat->rx_queues_to_use, false);
include/linux/stmmac.h +0 -28
@@ -138,33 +138,6 @@ struct stmmac_txq_cfg {int tbs_en; }; -/* FPE link state */ -enum stmmac_fpe_state { -FPE_STATE_OFF =0 , -FPE_STATE_CAPABLE =1 , -FPE_STATE_ENTERING_ON =2 , -FPE_STATE_ON =3 , -}; - -/* FPE link-partner hand-shaking mPacket type */ -enum stmmac_mpacket_type { -MPACKET_VERIFY =0 , -MPACKET_RESPONSE =1 , -}; - -enum stmmac_fpe_task_state_t { - __FPE_REMOVING, - __FPE_TASK_SCHED, -}; - -struct stmmac_fpe_cfg { -bool enable;/* FPE enable */ -bool hs_enable;/* FPE handshake enable */ -enum stmmac_fpe_state lp_fpe_state;/* Link Partner FPE state */ -enum stmmac_fpe_state lo_fpe_state;/* Local station FPE state */ -u32 fpe_csr;/* MAC_FPE_CTRL_STS reg cache */ -}; -struct stmmac_safety_feature_cfg {u32 tsoee;u32 mrxpee;
@@ -232,7 +205,6 @@ struct plat_stmmacenet_data {struct fwnode_handle *port_node;struct device_node *mdio_node;struct stmmac_dma_cfg *dma_cfg; -struct stmmac_fpe_cfg *fpe_cfg;struct stmmac_safety_feature_cfg *safety_feat_cfg;int clk_csr;int has_gmac;
Signature · 1 line
2.34.1
Re: [PATCH net-next v4 1/7] net: stmmac: move stmmac_fpe_cfg to stmmac_priv data
Quoted 6 lines · Furong Xu
By moving the
fpe_cfgfield to thestmmac_privdata,stmmac_fpe_cfgbecomes platform-data eventually, instead of a run-time config.Suggested-by Serge Semin <[email protected]>Signed-off-by Furong Xu <[email protected]>---
PATCH v4 2/7 net: stmmac: drop stmmac_fpe_handshake
In reply to Furong Xuethtool --set-mm can trigger FPE verification processe by calling stmmac_fpe_send_mpacket, stmmac_fpe_handshake should be gone.
--- .../net/ethernet/stmicro/stmmac/stmmac_main.c | 23 +------------------ .../net/ethernet/stmicro/stmmac/stmmac_tc.c | 8 ------- 2 files changed, 1 insertion(+), 30 deletions(-)
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +1 -22
@@ -3533,13 +3533,9 @@ static int stmmac_hw_setup(struct net_device *dev, bool ptp_register)stmmac_set_hw_vlan_mode (priv, priv->hw); -if (priv->dma_cap.fpesel) { +if (priv->dma_cap.fpesel)stmmac_fpe_start_wq (priv); -if (priv->fpe_cfg.enable) -stmmac_fpe_handshake (priv, true); - } -return 0 ; }
@@ -7425,22 +7421,6 @@ static void stmmac_fpe_lp_task(struct work_struct *work)clear_bit (__FPE_TASK_SCHED, &priv->fpe_task_state); } -void stmmac_fpe_handshake (struct stmmac_priv *priv,bool enable) -{ -if (priv->fpe_cfg.hs_enable != enable) { -if (enable) { -stmmac_fpe_send_mpacket (priv, priv->ioaddr, - &priv->fpe_cfg, -MPACKET_VERIFY ); - }else { - priv->fpe_cfg.lo_fpe_state =FPE_STATE_OFF ; - priv->fpe_cfg.lp_fpe_state =FPE_STATE_OFF ; - } - - priv->fpe_cfg.hs_enable = enable; - } -} -static int stmmac_xdp_rx_timestamp (const struct xdp_md *_ctx,u64 *timestamp) {const struct stmmac_xdp_buff *ctx = (void *)_ctx;
@@ -7902,7 +7882,6 @@ int stmmac_suspend(struct device *dev) priv->plat->tx_queues_to_use, priv->plat->rx_queues_to_use, false); -stmmac_fpe_handshake (priv, false);stmmac_fpe_stop_wq (priv); }
drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c +0 -8
@@ -1078,11 +1078,6 @@ static int tc_taprio_configure(struct stmmac_priv *priv,netdev_info (priv->dev,"configured EST\n" ); -if (fpe) { -stmmac_fpe_handshake (priv, true); -netdev_info (priv->dev,"start FPE handshake\n" ); - } -return 0 ; disable:
@@ -1107,9 +1102,6 @@ static int tc_taprio_configure(struct stmmac_priv *priv, false);netdev_info (priv->dev,"disabled FPE\n" ); -stmmac_fpe_handshake (priv, false); -netdev_info (priv->dev,"stop FPE handshake\n" ); -return ret; }
Signature · 1 line
2.34.1
Re: [PATCH net-next v4 2/7] net: stmmac: drop stmmac_fpe_handshake
Quoted 1 line · Furong Xu
ethtool --set-mm can trigger FPE verification processe by calling
nitpick: process
Quoted 4 lines
stmmac_fpe_send_mpacket,stmmac_fpe_handshakeshould be gone.Signed-off-by Furong Xu <[email protected]>---
PATCH v4 3/7 net: stmmac: refactor FPE verification process
In reply to Furong XuDrop driver defined stmmac_fpe_state, and switch to common ethtool_mm_verify_status for local TX verification status.
Local side and remote side verification processes are completely independent. There is no reason at all to keep a local state and a remote state.
Add a spinlock to avoid races among ISR, workqueue, link update and register configuration.
--- drivers/net/ethernet/stmicro/stmmac/stmmac.h | 21 +-- .../net/ethernet/stmicro/stmmac/stmmac_main.c | 172 ++++++++++-------- .../net/ethernet/stmicro/stmmac/stmmac_tc.c | 6 - 3 files changed, 102 insertions(+), 97 deletions(-)
drivers/net/ethernet/stmicro/stmmac/stmmac.h +9 -12
@@ -146,14 +146,6 @@ struct stmmac_channel {u32 index; }; -/* FPE link state */ -enum stmmac_fpe_state { -FPE_STATE_OFF =0 , -FPE_STATE_CAPABLE =1 , -FPE_STATE_ENTERING_ON =2 , -FPE_STATE_ON =3 , -}; -/* FPE link-partner hand-shaking mPacket type */ enum stmmac_mpacket_type {MPACKET_VERIFY =0 ,
@@ -166,11 +158,16 @@ enum stmmac_fpe_task_state_t { };struct stmmac_fpe_cfg { -bool enable;/* FPE enable */ -bool hs_enable;/* FPE handshake enable */ -enum stmmac_fpe_state lp_fpe_state;/* Link Partner FPE state */ -enum stmmac_fpe_state lo_fpe_state;/* Local station FPE state */ +/* Serialize access to MAC Merge state between ethtool requests +* and link state updates. +*/ +spinlock_t lock; +u32 fpe_csr;/* MAC_FPE_CTRL_STS reg cache */ +u32 verify_time;/* see ethtool_mm_state */ +bool pmac_enabled;/* see ethtool_mm_state */ +bool verify_enabled;/* see ethtool_mm_state */ +enum ethtool_mm_verify_status status; };struct stmmac_tc_entry {
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +93 -79
244 lines not on this page · raw message
drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c +0 -6
@@ -1063,11 +1063,6 @@ static int tc_taprio_configure(struct stmmac_priv *priv,return -EOPNOTSUPP ; } -/* Actual FPE register configuration will be done after FPE handshake -* is success. -*/ - priv->fpe_cfg.enable = fpe; - ret =stmmac_est_configure (priv, priv, priv->est, priv->plat->clk_ptp_rate);mutex_unlock (&priv->est_lock);
@@ -1094,7 +1089,6 @@ static int tc_taprio_configure(struct stmmac_priv *priv,mutex_unlock (&priv->est_lock); } - priv->fpe_cfg.enable = false; stmmac_fpe_configure(priv, priv->ioaddr, &priv->fpe_cfg, priv->plat->tx_queues_to_use,
Signature · 1 line
2.34.1
Re: [PATCH net-next v4 3/7] net: stmmac: refactor FPE verification process
Quoted 75 lines · Furong Xu
Drop driver defined
stmmac_fpe_state, and switch to commonethtool_mm_verify_statusfor local TX verification status.Local side and remote side verification processes are completely independent. There is no reason at all to keep a local state and a remote state.
Add a spinlock to avoid races among ISR, workqueue, link update and register configuration.
Signed-off-by Furong Xu <[email protected]>--- drivers/net/ethernet/stmicro/stmmac/stmmac.h | 21 +-- .../net/ethernet/stmicro/stmmac/stmmac_main.c | 172 ++++++++++-------- .../net/ethernet/stmicro/stmmac/stmmac_tc.c | 6 - 3 files changed, 102 insertions(+), 97 deletions(-)drivers/net/ethernet/stmicro/stmmac/stmmac.h +9
-12@@ -146,14 +146,6 @@ struct stmmac_channel {u32 index; }; -/* FPE link state */ -enum stmmac_fpe_state { -FPE_STATE_OFF =0 , -FPE_STATE_CAPABLE =1 , -FPE_STATE_ENTERING_ON =2 , -FPE_STATE_ON =3 , -}; -/* FPE link-partner hand-shaking mPacket type */ enum stmmac_mpacket_type {MPACKET_VERIFY =0 ,@@ -166,11 +158,16 @@ enum stmmac_fpe_task_state_t { };struct stmmac_fpe_cfg { -bool enable;/* FPE enable */ -bool hs_enable;/* FPE handshake enable */ -enum stmmac_fpe_state lp_fpe_state;/* Link Partner FPE state */ -enum stmmac_fpe_state lo_fpe_state;/* Local station FPE state */ +/* Serialize access to MAC Merge state between ethtool requests +* and link state updates. +*/ +spinlock_t lock; +u32 fpe_csr;/* MAC_FPE_CTRL_STS reg cache */ +u32 verify_time;/* see ethtool_mm_state */ +bool pmac_enabled;/* see ethtool_mm_state */ +bool verify_enabled;/* see ethtool_mm_state */ +enum ethtool_mm_verify_status status; };struct stmmac_tc_entry {drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +6
-3@@ -969,17 +969,21 @@ static void stmmac_mac_config(struct phylink_config *config, unsigned int mode,static void stmmac_fpe_link_state_handle (struct stmmac_priv *priv,bool is_up) {struct stmmac_fpe_cfg *fpe_cfg = &priv->fpe_cfg; -enum stmmac_fpe_state *lo_state = &fpe_cfg->lo_fpe_state; -enum stmmac_fpe_state *lp_state = &fpe_cfg->lp_fpe_state; -bool *hs_enable = &fpe_cfg->hs_enable; +unsigned long flags; + +spin_lock_irqsave (&priv->fpe_cfg.lock, flags); + +if (!fpe_cfg->pmac_enabled) + goto __unlock_out;
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c static void stmmac_mac_config(struct phylink_config *config, unsigned int mode, · line 983
Quoted 10 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +3
-5-if (is_up && *hs_enable) { +if (is_up && fpe_cfg->verify_enabled)stmmac_fpe_send_mpacket (priv, priv->ioaddr, fpe_cfg,MPACKET_VERIFY ); - }else { - *lo_state =FPE_STATE_OFF ; - *lp_state =FPE_STATE_OFF ; - } +else + fpe_cfg->status =ETHTOOL_MM_VERIFY_STATUS_DISABLED ;
The fpe_task may be scheduled here. When you unlock, it may run and overwrite the fpe_cfg->status you've just set.
Although I don't actually recommend setting ETHTOOL_MM_VERIFY_STATUS_DISABLED unless cfg->verify_enabled=false.
Quoted 19 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +7
-3+ +__unlock_out: +spin_unlock_irqrestore (&priv->fpe_cfg.lock, flags); } static void stmmac_mac_link_down(struct phylink_config *config,@@ -4091,11 +4095,25 @@ static int stmmac_release(struct net_device *dev)stmmac_release_ptp (priv); -pm_runtime_put (priv->device); - -if (priv->dma_cap.fpesel) +if (priv->dma_cap.fpesel) {stmmac_fpe_stop_wq (priv); +/* stmmac_ethtool_ops.begin() guarantees that all ethtool +* requests to fail with EBUSY when !netif_running() +*
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c static int stmmac_release(struct net_device *dev) · line 4113
Quoted 10 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +10
-0+* Prepare some params here, then fpe_cfg can keep consistent +* with the register states after a SW reset by __stmmac_open(). +*/ + priv->fpe_cfg.pmac_enabled = false; + priv->fpe_cfg.verify_enabled = false; + priv->fpe_cfg.status =ETHTOOL_MM_VERIFY_STATUS_DISABLED ; + +/* Reset MAC_FPE_CTRL_STS reg cache */ + priv->fpe_cfg.fpe_csr =0 ; + }
With this block of code, you're saying that you're deliberately okay for the ethtool-mm state to be lost after a stmmac_release() call. Mind you, some of the call sites of this are:
- stmmac_change_mtu()
- stmmac_reinit_queues()
- stmmac_reinit_ringparam()
I disagree that it's okay to lose the state configured by user space. Instead, you should reprogram the saved state once lost.
Note that because stmmac_release() calls phylink_stop(), I think that restoring the state in stmmac_fpe_link_state_handle() is enough. Because there will always be a link drop.
Quoted 90 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +23
-37+ +pm_runtime_put (priv->device); +return 0 ; }@@ -5979,44 +5997,34 @@ static int stmmac_set_features(struct net_device *netdev,static void stmmac_fpe_event_status (struct stmmac_priv *priv,int status) {struct stmmac_fpe_cfg *fpe_cfg = &priv->fpe_cfg; -enum stmmac_fpe_state *lo_state = &fpe_cfg->lo_fpe_state; -enum stmmac_fpe_state *lp_state = &fpe_cfg->lp_fpe_state; -bool *hs_enable = &fpe_cfg->hs_enable; -if (status ==FPE_EVENT_UNKNOWN || !*hs_enable) -return ; +spin_lock (&priv->fpe_cfg.lock); -/* If LP has sent verify mPacket, LP is FPE capable */ -if ((status &FPE_EVENT_RVER ) ==FPE_EVENT_RVER ) { -if (*lp_state <FPE_STATE_CAPABLE ) - *lp_state =FPE_STATE_CAPABLE ; +if (!fpe_cfg->pmac_enabled || status ==FPE_EVENT_UNKNOWN ) + goto __unlock_out; -/* If user has requested FPE enable, quickly response */ -if (*hs_enable) -stmmac_fpe_send_mpacket (priv, priv->ioaddr, - fpe_cfg, -MPACKET_RESPONSE ); - } +/* LP has sent verify mPacket */ +if ((status &FPE_EVENT_RVER ) ==FPE_EVENT_RVER ) +stmmac_fpe_send_mpacket (priv, priv->ioaddr, fpe_cfg, +MPACKET_RESPONSE ); -/* If Local has sent verify mPacket, Local is FPE capable */ -if ((status &FPE_EVENT_TVER ) ==FPE_EVENT_TVER ) { -if (*lo_state <FPE_STATE_CAPABLE ) - *lo_state =FPE_STATE_CAPABLE ; - } +/* Local has sent verify mPacket */ +if ((status &FPE_EVENT_TVER ) ==FPE_EVENT_TVER && + fpe_cfg->status !=ETHTOOL_MM_VERIFY_STATUS_SUCCEEDED ) + fpe_cfg->status =ETHTOOL_MM_VERIFY_STATUS_VERIFYING ; -/* If LP has sent response mPacket, LP is entering FPE ON */ +/* LP has sent response mPacket */ if ((status &FPE_EVENT_RRSP ) ==FPE_EVENT_RRSP ) - *lp_state =FPE_STATE_ENTERING_ON ; - -/* If Local has sent response mPacket, Local is entering FPE ON */ -if ((status &FPE_EVENT_TRSP ) ==FPE_EVENT_TRSP ) - *lo_state =FPE_STATE_ENTERING_ON ; + fpe_cfg->status =ETHTOOL_MM_VERIFY_STATUS_SUCCEEDED ;if (!test_bit (__FPE_REMOVING, &priv->fpe_task_state) && !test_and_set_bit (__FPE_TASK_SCHED, &priv->fpe_task_state) && priv->fpe_wq) {queue_work (priv->fpe_wq, &priv->fpe_task); } + +__unlock_out: +spin_unlock (&priv->fpe_cfg.lock); }static void stmmac_common_interrupt (struct stmmac_priv *priv)@@ -7372,50 +7380,57 @@ int stmmac_reinit_ringparam(struct net_device *dev, u32 rx_size, u32 tx_size)return ret; } -#define SEND_VERIFY_MPAKCET_FMT "Send Verify mPacket lo_state=%d lp_state=%d\n" -static void stmmac_fpe_lp_task (struct work_struct *work) +static void stmmac_fpe_verify_task (struct work_struct *work) { struct stmmac_priv *priv = container_of(work, struct stmmac_priv, fpe_task);struct stmmac_fpe_cfg *fpe_cfg = &priv->fpe_cfg; -enum stmmac_fpe_state *lo_state = &fpe_cfg->lo_fpe_state; -enum stmmac_fpe_state *lp_state = &fpe_cfg->lp_fpe_state; -bool *hs_enable = &fpe_cfg->hs_enable; -bool *enable = &fpe_cfg->enable; -int retries =20 ; - -while (retries-- >0 ) { -/* Bail out immediately if FPE handshake is OFF */ -if (*lo_state ==FPE_STATE_OFF || !*hs_enable) +int verify_limit =3 ;/* defined by 802.3 */ +unsigned long flags; +u32 sleep_ms;
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c int stmmac_reinit_ringparam(struct net_device *dev, u32 rx_size, u32 tx_size) · line 7400
Quoted 10 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +10
-0+ +spin_lock (&priv->fpe_cfg.lock); + sleep_ms = fpe_cfg->verify_time; +spin_unlock (&priv->fpe_cfg.lock); + +while (1 ) { +/* The initial VERIFY was triggered by linkup event or +* stmmac_set_mm(), sleep then check MM_VERIFY_STATUS. +*/ +msleep (sleep_ms);
Thanks for the added comment. But why don't you just use queue_delayed_work() instead of queue_work() and sleeping at the very beginning?
With this, you really don't need to drop the lock and read fpe_cfg->verify_time twice.
But I think what is needed here is better suited for a timer, especially because of the required coordination with the IRQ. See the end and the attachment for more details.
Quoted 16 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +5
-8+ +if (!netif_running (priv->dev))break ; -if (*lo_state ==FPE_STATE_ENTERING_ON && - *lp_state ==FPE_STATE_ENTERING_ON ) { -stmmac_fpe_configure (priv, priv->ioaddr, - fpe_cfg, - priv->plat->tx_queues_to_use, - priv->plat->rx_queues_to_use, - *enable); +spin_lock_irqsave (&priv->fpe_cfg.lock, flags); -netdev_info (priv->dev,"configured FPE\n" ); + if (fpe_cfg->status == ETHTOOL_MM_VERIFY_STATUS_DISABLED || + fpe_cfg->status == ETHTOOL_MM_VERIFY_STATUS_SUCCEEDED ||
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c int stmmac_reinit_ringparam(struct net_device *dev, u32 rx_size, u32 tx_size) · line 7415
Quoted 10 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +6
-3+ !fpe_cfg->pmac_enabled || !fpe_cfg->verify_enabled) { +spin_unlock_irqrestore (&priv->fpe_cfg.lock, flags); +break ; + } - *lo_state =FPE_STATE_ON ; - *lp_state =FPE_STATE_ON ; -netdev_info (priv->dev,"!!! BOTH FPE stations ON\n" ); +if (verify_limit ==0 ) { + fpe_cfg->verify_enabled = false;
I don't understand why turn off verify_enabled after failure? Only the user should be able to modify this.
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c int stmmac_reinit_ringparam(struct net_device *dev, u32 rx_size, u32 tx_size) · line 7420
Quoted 5 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +5
-0+ fpe_cfg->status =ETHTOOL_MM_VERIFY_STATUS_FAILED ; +stmmac_fpe_configure (priv, priv->ioaddr, fpe_cfg, + priv->plat->tx_queues_to_use, + priv->plat->rx_queues_to_use, + false);
I don't understand why turn off tx_enabled after failure, rather than not turning it on at all until success?
This really has me thinking. This hardware does not have the explicit notion of the verification state - it is purely a driver construct. So I wonder if the EFPE bit in MAC_FPE_CTRL_STS isn't actually what corresponds to "tx_active" rather than "tx_enabled"? (definitions at https://docs.kernel.org/networking/ethtool-netlink.html)
And "tx_enabled" would just correspond to a state variable in the driver, which does nothing until verification is actually complete.
There is a test in manual_failed_verification() which checks the correctness of the tx_enabled/tx_active behavior. If tx_enabled=true but verification fails (and also _up until_ that point), the MM layer is supposed to send packets through the eMAC (because tx_active=false). But for your driver, that test is inconclusive, because you don't report ethtool stats broken down by eMAC/pMAC, just aggregate. So we don't know unless we take a closer look manually at the driver in that state.
Quoted 14 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +3
-7+spin_unlock_irqrestore (&priv->fpe_cfg.lock, flags);break ; } -if ((*lo_state ==FPE_STATE_CAPABLE || - *lo_state ==FPE_STATE_ENTERING_ON ) && - *lp_state !=FPE_STATE_ON ) { -netdev_info (priv->dev,SEND_VERIFY_MPAKCET_FMT , - *lo_state, *lp_state); -stmmac_fpe_send_mpacket (priv, priv->ioaddr, - fpe_cfg, +if (fpe_cfg->status ==ETHTOOL_MM_VERIFY_STATUS_VERIFYING ) +stmmac_fpe_send_mpacket (priv, priv->ioaddr, fpe_cfg,MPACKET_VERIFY );
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c int stmmac_reinit_ringparam(struct net_device *dev, u32 rx_size, u32 tx_size) · line 7434
Quoted 10 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +6
-3- } -/* Sleep then retry */ -msleep (500 ); + + sleep_ms = fpe_cfg->verify_time; + +spin_unlock_irqrestore (&priv->fpe_cfg.lock, flags); + + verify_limit--; }
I took the liberty of rewriting the fpe_task to a timer, and delete the workqueue. Here is a completely untested patch, which at least is less complex, has less code and is easier to understand. What do you think?
From 6ce277245128638160385d948583a3e6d2561a94 Mon Sep 17 00:00:00 2001
From: Vladimir Oltean <[email protected]>
Date: Tue, 20 Aug 2024 14:50:32 +0300
Subject: [PATCH] net: stmmac: replace FPE workqueue with timer
What remains in the fpe_task after decoupling RX from TX appears overengineered to use a workqueue. A timer which retransmits Verify mPackets until the verify_limit expires, or enables transmission on success, seems enough.
In the INITIAL state, the timer sends MPACKET_VERIFY. Eventually the stmmac_fpe_event_status() IRQ fires and advances the state to VERIFYING, then rearms the timer after verify_time ms. If a subsequent IRQ comes in and modifies the state to SUCCEEDED after getting MPACKET_RESPONSE, the timer sees this. It must enable the EFPE bit now. Otherwise, it decrements the verify_limit counter and tries again. Eventually it moves the status to FAILED, from which the IRQ cannot move it anywhere else, except for another stmmac_fpe_apply() call.
--- drivers/net/ethernet/stmicro/stmmac/stmmac.h | 16 +- .../ethernet/stmicro/stmmac/stmmac_ethtool.c | 35 +-- .../net/ethernet/stmicro/stmmac/stmmac_main.c | 212 +++++++----------- 3 files changed, 100 insertions(+), 163 deletions(-)
drivers/net/ethernet/stmicro/stmmac/stmmac.h +5 -11
@@ -152,21 +152,18 @@ enum stmmac_mpacket_type { MPACKET_RESPONSE = 1, }; -enum stmmac_fpe_task_state_t { - __FPE_REMOVING, - __FPE_TASK_SCHED, -}; -struct stmmac_fpe_cfg {/* Serialize access to MAC Merge state between ethtool requests * and link state updates. */ spinlock_t lock; - +struct timer_list verify_timer;u32 fpe_csr;/* MAC_FPE_CTRL_STS reg cache */ u32 verify_time;/* see ethtool_mm_state */ bool pmac_enabled;/* see ethtool_mm_state */ bool verify_enabled;/* see ethtool_mm_state */ +bool tx_enabled; +int verify_limit;enum ethtool_mm_verify_status status; };
@@ -364,10 +361,6 @@ struct stmmac_priv {struct work_struct service_task;/* Frame Preemption feature (FPE) */ -unsigned long fpe_task_state; -struct workqueue_struct *fpe_wq; -struct work_struct fpe_task; -char wq_name[IFNAMSIZ +4 ];struct stmmac_fpe_cfg fpe_cfg;/* TC Handling */
@@ -422,7 +415,8 @@ bool stmmac_eee_init(struct stmmac_priv *priv);int stmmac_reinit_queues (struct net_device *dev,u32 rx_cnt,u32 tx_cnt);int stmmac_reinit_ringparam (struct net_device *dev,u32 rx_size,u32 tx_size);int stmmac_bus_clks_config (struct stmmac_priv *priv,bool enabled); -void stmmac_fpe_handshake (struct stmmac_priv *priv,bool enable); +void stmmac_fpe_apply (struct stmmac_priv *priv); +void stmmac_fpe_verify_timer_arm (struct stmmac_fpe_cfg *fpe_cfg);static inline bool stmmac_xdp_is_enabled (struct stmmac_priv *priv) {
drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +11 -24
@@ -1293,14 +1293,7 @@ static int stmmac_get_mm(struct net_device *ndev,* variable has a range between 1 and 128 ms inclusive. Limit to that. */ state->max_verify_time =128 ; - -/* Cannot read MAC_FPE_CTRL_STS register here, or FPE interrupt events -* can be lost. -* -* See commit 37e4b8df27bc ("net: stmmac: fix FPE events losing") -*/ - state->tx_enabled = !!(priv->fpe_cfg.fpe_csr ==EFPE ); - + state->tx_enabled = priv->fpe_cfg.tx_enabled;/* FPE active if common tx_enabled and verification success or disabled (forced) */ state->tx_active = state->tx_enabled && (state->verify_status == ETHTOOL_MM_VERIFY_STATUS_SUCCEEDED ||
@@ -1326,34 +1319,28 @@ static int stmmac_set_mm(struct net_device *ndev, struct ethtool_mm_cfg *cfg,if (!priv->dma_cap.fpesel)return -EOPNOTSUPP ; -/* Wait for the fpe_task that's currently in progress to finish */ -flush_workqueue (priv->fpe_wq); - err =ethtool_mm_frag_size_min_to_add (cfg->tx_min_frag_size, &add_frag_size, extack);if (err)return err; -spin_lock_irqsave (&priv->fpe_cfg.lock, flags); +/* Wait for the verification that's currently in progress to finish */ +del_timer_sync (&fpe_cfg->verify_timer); + +spin_lock_irqsave (&fpe_cfg->lock, flags); fpe_cfg->pmac_enabled = cfg->pmac_enabled; + fpe_cfg->tx_enabled = cfg->tx_enabled; fpe_cfg->verify_time = cfg->verify_time; fpe_cfg->verify_enabled = cfg->verify_enabled; - -stmmac_fpe_configure (priv, priv->ioaddr, fpe_cfg, - priv->plat->tx_queues_to_use, - priv->plat->rx_queues_to_use, - cfg->tx_enabled, cfg->pmac_enabled); + fpe_cfg->verify_limit =3 ;/* IEEE 802.3 constant */ +if (!cfg->verify_enabled) + fpe_cfg->status =ETHTOOL_MM_VERIFY_STATUS_DISABLED ;stmmac_fpe_set_add_frag_size (priv, priv->ioaddr, add_frag_size); +stmmac_fpe_apply (priv); -if (cfg->verify_enabled) -stmmac_fpe_send_mpacket (priv, priv->ioaddr, fpe_cfg, -MPACKET_VERIFY ); -else - fpe_cfg->status =ETHTOOL_MM_VERIFY_STATUS_DISABLED ; - -spin_unlock_irqrestore (&priv->fpe_cfg.lock, flags); +spin_unlock_irqrestore (&fpe_cfg->lock, flags);return 0 ; }
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +84 -128
285 lines not on this page · raw message
Signature · 1 line
2.34.1
Re: [PATCH net-next v4 3/7] net: stmmac: refactor FPE verification process
Quoted 3 lines · Vladimir Oltean
I took the liberty of rewriting the
fpe_taskto a timer, and delete the workqueue. Here is a completely untested patch, which at least is less complex, has less code and is easier to understand. What do you think?
I already found a bug in the code I sent, sorry. verify_limit needs to be reset each time status is reset to ETHTOOL_MM_VERIFY_STATUS_INITIAL, to allow for 3 retries on each clean-state verification process.
drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +0 -1
@@ -1333,7 +1333,6 @@ static int stmmac_set_mm(struct net_device *ndev, struct ethtool_mm_cfg *cfg, fpe_cfg->tx_enabled = cfg->tx_enabled; fpe_cfg->verify_time = cfg->verify_time; fpe_cfg->verify_enabled = cfg->verify_enabled; - fpe_cfg->verify_limit =3 ;/* IEEE 802.3 constant */ if (!cfg->verify_enabled) fpe_cfg->status =ETHTOOL_MM_VERIFY_STATUS_DISABLED ;
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +1 -0
@@ -7405,6 +7405,7 @@ void stmmac_fpe_apply(struct stmmac_priv *priv) fpe_cfg->pmac_enabled); }else { fpe_cfg->status =ETHTOOL_MM_VERIFY_STATUS_INITIAL ; + fpe_cfg->verify_limit =3 ;/* IEEE 802.3 constant */ stmmac_fpe_verify_timer_arm (fpe_cfg); } }
Re: [PATCH net-next v4 3/7] net: stmmac: refactor FPE verification process
In reply to Vladimir OlteanHi Vladimir
Quoted 4 lines · Vladimir Oltean
I took the liberty of rewriting the
fpe_taskto a timer, and delete the workqueue. Here is a completely untested patch, which at least is less complex, has less code and is easier to understand. What do you think?
Your patch is much better than my ugly implementation ;)
Some small fixes are required to make kselftest-ethtool_mm pass.
Would you mind if I rebase you patch, fix some small issues, make sure all test cases pass, split it into two patches and include them in my patchset, then send to review as a Co-developer and a tester?
Thanks.
Re: [PATCH net-next v4 3/7] net: stmmac: refactor FPE verification process
Quoted 10 lines · Furong Xu
Hi Vladimir
Quoted 4 lines · Vladimir Oltean
I took the liberty of rewriting the
fpe_taskto a timer, and delete the workqueue. Here is a completely untested patch, which at least is less complex, has less code and is easier to understand. What do you think?Your patch is much better than my ugly implementation ;)
Well, to be fair, it took us a number of iterations to properly see how much it could be simplified.
Quoted 5 lines
Some small fixes are required to make kselftest-ethtool_mm pass.
Would you mind if I rebase you patch, fix some small issues, make sure all test cases pass, split it into two patches and include them in my patchset, then send to review as a Co-developer and a tester?
Please feel free to split up that patch and squash it into your patches, keeping your Author: field and just a Co-developed-by: + Signed-off-by:
for me, where parts of that patch helped you.
Re: [PATCH net-next v4 3/7] net: stmmac: refactor FPE verification process
In reply to Furong XuFrom: Furong Xu <[email protected]>
Date: Tue, 20 Aug 2024 17:38:31 +0800
Quoted 44 lines
Drop driver defined
stmmac_fpe_state, and switch to commonethtool_mm_verify_statusfor local TX verification status.Local side and remote side verification processes are completely independent. There is no reason at all to keep a local state and a remote state.
Add a spinlock to avoid races among ISR, workqueue, link update and register configuration.
Signed-off-by Furong Xu <[email protected]>--- drivers/net/ethernet/stmicro/stmmac/stmmac.h | 21 +-- .../net/ethernet/stmicro/stmmac/stmmac_main.c | 172 ++++++++++-------- .../net/ethernet/stmicro/stmmac/stmmac_tc.c | 6 - 3 files changed, 102 insertions(+), 97 deletions(-)drivers/net/ethernet/stmicro/stmmac/stmmac.h +0
-12@@ -146,14 +146,6 @@ struct stmmac_channel {u32 index; }; -/* FPE link state */ -enum stmmac_fpe_state { -FPE_STATE_OFF =0 , -FPE_STATE_CAPABLE =1 , -FPE_STATE_ENTERING_ON =2 , -FPE_STATE_ON =3 , -}; -/* FPE link-partner hand-shaking mPacket type */ enum stmmac_mpacket_type {MPACKET_VERIFY =0 ,@@ -166,11 +158,16 @@ enum stmmac_fpe_task_state_t { };struct stmmac_fpe_cfg { -bool enable;/* FPE enable */ -bool hs_enable;/* FPE handshake enable */ -enum stmmac_fpe_state lp_fpe_state;/* Link Partner FPE state */ -enum stmmac_fpe_state lo_fpe_state;/* Local station FPE state */
drivers/net/ethernet/stmicro/stmmac/stmmac.h enum stmmac_fpe_task_state_t { · line 170
Quoted 10 lines
drivers/net/ethernet/stmicro/stmmac/stmmac.h +9
-0+/* Serialize access to MAC Merge state between ethtool requests +* and link state updates. +*/ +spinlock_t lock; +u32 fpe_csr;/* MAC_FPE_CTRL_STS reg cache */ +u32 verify_time;/* see ethtool_mm_state */ +bool pmac_enabled;/* see ethtool_mm_state */ +bool verify_enabled;/* see ethtool_mm_state */ +enum ethtool_mm_verify_status status;
Why not embed ðtool_mm_state here then?
Quoted 23 lines
drivers/net/ethernet/stmicro/stmmac/stmmac.h +0
-0};struct stmmac_tc_entry {drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +7
-4@@ -969,17 +969,21 @@ static void stmmac_mac_config(struct phylink_config *config, unsigned int mode,static void stmmac_fpe_link_state_handle (struct stmmac_priv *priv,bool is_up) {struct stmmac_fpe_cfg *fpe_cfg = &priv->fpe_cfg; -enum stmmac_fpe_state *lo_state = &fpe_cfg->lo_fpe_state; -enum stmmac_fpe_state *lp_state = &fpe_cfg->lp_fpe_state; -bool *hs_enable = &fpe_cfg->hs_enable; +unsigned long flags; + +spin_lock_irqsave (&priv->fpe_cfg.lock, flags); + +if (!fpe_cfg->pmac_enabled) + goto __unlock_out; -if (is_up && *hs_enable) { +if (is_up && fpe_cfg->verify_enabled)
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c static void stmmac_mac_config(struct phylink_config *config, unsigned int mode, · line 985
Quoted 10 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +4
-4stmmac_fpe_send_mpacket (priv, priv->ioaddr, fpe_cfg,MPACKET_VERIFY ); - }else { - *lo_state =FPE_STATE_OFF ; - *lp_state =FPE_STATE_OFF ; - } + else + fpe_cfg->status = ETHTOOL_MM_VERIFY_STATUS_DISABLED; + +__unlock_out:
Why underscores?
Quoted 34 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +18
-3+spin_unlock_irqrestore (&priv->fpe_cfg.lock, flags); } static void stmmac_mac_link_down(struct phylink_config *config,@@ -4091,11 +4095,25 @@ static int stmmac_release(struct net_device *dev)stmmac_release_ptp (priv); -pm_runtime_put (priv->device); - -if (priv->dma_cap.fpesel) +if (priv->dma_cap.fpesel) {stmmac_fpe_stop_wq (priv); +/* stmmac_ethtool_ops.begin() guarantees that all ethtool +* requests to fail with EBUSY when !netif_running() +* +* Prepare some params here, then fpe_cfg can keep consistent +* with the register states after a SW reset by __stmmac_open(). +*/ + priv->fpe_cfg.pmac_enabled = false; + priv->fpe_cfg.verify_enabled = false; + priv->fpe_cfg.status =ETHTOOL_MM_VERIFY_STATUS_DISABLED ; + +/* Reset MAC_FPE_CTRL_STS reg cache */ + priv->fpe_cfg.fpe_csr =0 ; + } + +pm_runtime_put (priv->device); +return 0 ; }
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c static int stmmac_set_features(struct net_device *netdev, · line 6001
Quoted 10 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +1
-5@@ -5979,44 +5997,34 @@ static int stmmac_set_features(struct net_device *netdev,static void stmmac_fpe_event_status (struct stmmac_priv *priv,int status) {struct stmmac_fpe_cfg *fpe_cfg = &priv->fpe_cfg; -enum stmmac_fpe_state *lo_state = &fpe_cfg->lo_fpe_state; -enum stmmac_fpe_state *lp_state = &fpe_cfg->lp_fpe_state; -bool *hs_enable = &fpe_cfg->hs_enable; -if (status ==FPE_EVENT_UNKNOWN || !*hs_enable) -return ; +spin_lock (&priv->fpe_cfg.lock);
Is this ISR, so that you used the non-IRQ-safe variant?
Quoted 7 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +2
-4-/* If LP has sent verify mPacket, LP is FPE capable */ -if ((status &FPE_EVENT_RVER ) ==FPE_EVENT_RVER ) { -if (*lp_state <FPE_STATE_CAPABLE ) - *lp_state =FPE_STATE_CAPABLE ; +if (!fpe_cfg->pmac_enabled || status ==FPE_EVENT_UNKNOWN ) + goto __unlock_out;
[...]
Quoted 7 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +1
-2-#define SEND_VERIFY_MPAKCET_FMT "Send Verify mPacket lo_state=%d lp_state=%d\n" -static void stmmac_fpe_lp_task (struct work_struct *work) +static void stmmac_fpe_verify_task (struct work_struct *work) { struct stmmac_priv *priv = container_of(work, struct stmmac_priv, fpe_task);struct stmmac_fpe_cfg *fpe_cfg = &priv->fpe_cfg;
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c int stmmac_reinit_ringparam(struct net_device *dev, u32 rx_size, u32 tx_size) · line 7388
Quoted 10 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +1
-9-enum stmmac_fpe_state *lo_state = &fpe_cfg->lo_fpe_state; -enum stmmac_fpe_state *lp_state = &fpe_cfg->lp_fpe_state; -bool *hs_enable = &fpe_cfg->hs_enable; -bool *enable = &fpe_cfg->enable; -int retries =20 ; - -while (retries-- >0 ) { -/* Bail out immediately if FPE handshake is OFF */ -if (*lo_state ==FPE_STATE_OFF || !*hs_enable) +int verify_limit =3 ;/* defined by 802.3 */
If it's a generic/IEEE definition, then either put it somewhere in the generic headers or at least make a definition from it, doesn't open-code directly.
Quoted 56 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +31
-18+unsigned long flags; +u32 sleep_ms; + +spin_lock (&priv->fpe_cfg.lock); + sleep_ms = fpe_cfg->verify_time; +spin_unlock (&priv->fpe_cfg.lock); + +while (1 ) { +/* The initial VERIFY was triggered by linkup event or +* stmmac_set_mm(), sleep then check MM_VERIFY_STATUS. +*/ +msleep (sleep_ms); + +if (!netif_running (priv->dev))break ; -if (*lo_state ==FPE_STATE_ENTERING_ON && - *lp_state ==FPE_STATE_ENTERING_ON ) { -stmmac_fpe_configure (priv, priv->ioaddr, - fpe_cfg, - priv->plat->tx_queues_to_use, - priv->plat->rx_queues_to_use, - *enable); +spin_lock_irqsave (&priv->fpe_cfg.lock, flags); -netdev_info (priv->dev,"configured FPE\n" ); +if (fpe_cfg->status ==ETHTOOL_MM_VERIFY_STATUS_DISABLED || + fpe_cfg->status ==ETHTOOL_MM_VERIFY_STATUS_SUCCEEDED || + !fpe_cfg->pmac_enabled || !fpe_cfg->verify_enabled) { +spin_unlock_irqrestore (&priv->fpe_cfg.lock, flags); +break ; + } - *lo_state =FPE_STATE_ON ; - *lp_state =FPE_STATE_ON ; -netdev_info (priv->dev,"!!! BOTH FPE stations ON\n" ); +if (verify_limit ==0 ) { + fpe_cfg->verify_enabled = false; + fpe_cfg->status =ETHTOOL_MM_VERIFY_STATUS_FAILED ; +stmmac_fpe_configure (priv, priv->ioaddr, fpe_cfg, + priv->plat->tx_queues_to_use, + priv->plat->rx_queues_to_use, + false); +spin_unlock_irqrestore (&priv->fpe_cfg.lock, flags);break ; } -if ((*lo_state ==FPE_STATE_CAPABLE || - *lo_state ==FPE_STATE_ENTERING_ON ) && - *lp_state !=FPE_STATE_ON ) { -netdev_info (priv->dev,SEND_VERIFY_MPAKCET_FMT , - *lo_state, *lp_state); - stmmac_fpe_send_mpacket(priv, priv->ioaddr, - fpe_cfg, +if (fpe_cfg->status ==ETHTOOL_MM_VERIFY_STATUS_VERIFYING ) + stmmac_fpe_send_mpacket(priv, priv->ioaddr, fpe_cfg,
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c int stmmac_reinit_ringparam(struct net_device *dev, u32 rx_size, u32 tx_size) · line 7433
Quoted 10 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +6
-3MPACKET_VERIFY); - } -/* Sleep then retry */ -msleep (500 ); + + sleep_ms = fpe_cfg->verify_time; + +spin_unlock_irqrestore (&priv->fpe_cfg.lock, flags); + + verify_limit--;
Are these 3 empty newlines needed? I'd remove at least some of them.
Quoted 15 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +2
-2}clear_bit (__FPE_TASK_SCHED, &priv->fpe_task_state);@@ -7535,8 +7550,8 @@ int stmmac_dvr_probe(struct device *device,INIT_WORK (&priv->service_task, stmmac_service_task); -/* Initialize Link Partner FPE workqueue */ -INIT_WORK (&priv->fpe_task, stmmac_fpe_lp_task); +/* Initialize FPE verify workqueue */ +INIT_WORK (&priv->fpe_task, stmmac_fpe_verify_task);/* Override with kernel parameters if supplied XXX CRS XXX * this needs to have multiple instances
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c int stmmac_dvr_probe(struct device *device, · line 7721
Quoted 5 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +2
-0@@ -7702,6 +7717,12 @@ int stmmac_dvr_probe(struct device *device,mutex_init (&priv->lock); +spin_lock_init (&priv->fpe_cfg.lock); + priv->fpe_cfg.pmac_enabled = false;
I think it's kzalloc()'d? If so, why initialize booleans to false?
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c int stmmac_dvr_probe(struct device *device, · line 7722
Quoted 1 line
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +1
-0+ priv->fpe_cfg.verify_time =128 ;/* ethtool_mm_state.max_verify_time */
Same as verify_limit above, make it a definition, don't open-code.
Quoted 40 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +4
-8+ priv->fpe_cfg.verify_enabled = false; + priv->fpe_cfg.status =ETHTOOL_MM_VERIFY_STATUS_DISABLED ; +/* If a specific clk_csr value is passed from the platform * this means that the CSR Clock Range selection cannot be * changed at run-time and it is fixed. Viceversa the driver'll try to @@ -7875,15 +7896,8 @@ int stmmac_suspend(struct device *dev) }rtnl_unlock (); -if (priv->dma_cap.fpesel) { -/* Disable FPE */ -stmmac_fpe_configure (priv, priv->ioaddr, - &priv->fpe_cfg, - priv->plat->tx_queues_to_use, - priv->plat->rx_queues_to_use, false); - +if (priv->dma_cap.fpesel)stmmac_fpe_stop_wq (priv); - } priv->speed =SPEED_UNKNOWN ;return 0 ;drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c +0
-5@@ -1063,11 +1063,6 @@ static int tc_taprio_configure(struct stmmac_priv *priv,return -EOPNOTSUPP ; } -/* Actual FPE register configuration will be done after FPE handshake -* is success. -*/ - priv->fpe_cfg.enable = fpe; - ret =stmmac_est_configure (priv, priv, priv->est, priv->plat->clk_ptp_rate);mutex_unlock (&priv->est_lock);
drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c static int tc_taprio_configure(struct stmmac_priv *priv, · line 1094
Quoted 7 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c +0
-1@@ -1094,7 +1089,6 @@ static int tc_taprio_configure(struct stmmac_priv *priv,mutex_unlock (&priv->est_lock); } - priv->fpe_cfg.enable = false; stmmac_fpe_configure(priv, priv->ioaddr, &priv->fpe_cfg, priv->plat->tx_queues_to_use,
Thanks,
Olek
PATCH v4 4/7 net: stmmac: configure FPE via ethtool-mm
In reply to Furong XuImplement ethtool --show-mm and --set-mm callbacks.
NIC up/down, link up/down, suspend/resume, kselftest-ethtool_mm, all tested okay.
--- .../net/ethernet/stmicro/stmmac/dwmac4_core.c | 8 +- drivers/net/ethernet/stmicro/stmmac/dwmac5.c | 36 +++++- drivers/net/ethernet/stmicro/stmmac/dwmac5.h | 7 +- .../ethernet/stmicro/stmmac/dwxgmac2_core.c | 4 +- drivers/net/ethernet/stmicro/stmmac/hwif.h | 8 +- .../ethernet/stmicro/stmmac/stmmac_ethtool.c | 110 ++++++++++++++++++ .../net/ethernet/stmicro/stmmac/stmmac_main.c | 17 ++- .../net/ethernet/stmicro/stmmac/stmmac_tc.c | 2 +- 8 files changed, 179 insertions(+), 13 deletions(-)
drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +4 -4
@@ -58,10 +58,6 @@ static void dwmac4_core_init(struct mac_device_info *hw,if (hw->pcs) value |=GMAC_PCS_IRQ_DEFAULT ; -/* Enable FPE interrupt */ -if ((GMAC_HW_FEAT_FPESEL &readl (ioaddr +GMAC_HW_FEATURE3 )) >>26 ) - value |=GMAC_INT_FPE_EN ; -writel (value, ioaddr +GMAC_INT_EN );if (GMAC_INT_DEFAULT_ENABLE &GMAC_INT_TSIE )
@@ -1268,6 +1264,8 @@ const struct stmmac_ops dwmac410_ops = { .fpe_configure = dwmac5_fpe_configure, .fpe_send_mpacket = dwmac5_fpe_send_mpacket, .fpe_irq_status = dwmac5_fpe_irq_status, + .fpe_get_add_frag_size = dwmac5_fpe_get_add_frag_size, + .fpe_set_add_frag_size = dwmac5_fpe_set_add_frag_size, .add_hw_vlan_rx_fltr = dwmac4_add_hw_vlan_rx_fltr, .del_hw_vlan_rx_fltr = dwmac4_del_hw_vlan_rx_fltr, .restore_hw_vlan_rx_fltr = dwmac4_restore_hw_vlan_rx_fltr,
@@ -1320,6 +1318,8 @@ const struct stmmac_ops dwmac510_ops = { .fpe_configure = dwmac5_fpe_configure, .fpe_send_mpacket = dwmac5_fpe_send_mpacket, .fpe_irq_status = dwmac5_fpe_irq_status, + .fpe_get_add_frag_size = dwmac5_fpe_get_add_frag_size, + .fpe_set_add_frag_size = dwmac5_fpe_set_add_frag_size, .add_hw_vlan_rx_fltr = dwmac4_add_hw_vlan_rx_fltr, .del_hw_vlan_rx_fltr = dwmac4_del_hw_vlan_rx_fltr, .restore_hw_vlan_rx_fltr = dwmac4_restore_hw_vlan_rx_fltr,
drivers/net/ethernet/stmicro/stmmac/dwmac5.c +34 -2
@@ -575,11 +575,11 @@ int dwmac5_flex_pps_config(void __iomem *ioaddr, int index,void dwmac5_fpe_configure (void __iomem *ioaddr,struct stmmac_fpe_cfg *cfg,u32 num_txq,u32 num_rxq, -bool enable) +bool tx_enable,bool pmac_enable) {u32 value; -if (enable) { +if (tx_enable) { cfg->fpe_csr =EFPE ; value =readl (ioaddr +GMAC_RXQ_CTRL1 ); value &= ~GMAC_RXQCTRL_FPRQ ;
@@ -589,6 +589,21 @@ void dwmac5_fpe_configure(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg, cfg->fpe_csr =0 ; }writel (cfg->fpe_csr, ioaddr +MAC_FPE_CTRL_STS ); + + value =readl (ioaddr +GMAC_INT_EN ); + +if (pmac_enable) { +if (!(value &GMAC_INT_FPE_EN )) { +/* Dummy read to clear any pending masked interrupts */ + (void )readl (ioaddr +MAC_FPE_CTRL_STS ); + + value |=GMAC_INT_FPE_EN ; + } + }else { + value &= ~GMAC_INT_FPE_EN ; + } + +writel (value, ioaddr +GMAC_INT_EN ); }int dwmac5_fpe_irq_status (void __iomem *ioaddr,struct net_device *dev)
@@ -638,3 +653,20 @@ void dwmac5_fpe_send_mpacket(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg,writel (value, ioaddr +MAC_FPE_CTRL_STS ); } + +int dwmac5_fpe_get_add_frag_size (void __iomem *ioaddr) +{ +return FIELD_GET (AFSZ ,readl (ioaddr +MTL_FPE_CTRL_STS )); +} + +void dwmac5_fpe_set_add_frag_size (void __iomem *ioaddr,u32 add_frag_size) +{ +u32 value; + + value =readl (ioaddr +MTL_FPE_CTRL_STS ); + + value &= ~AFSZ ; + value |=FIELD_PREP (AFSZ , add_frag_size); + +writel (value, ioaddr +MTL_FPE_CTRL_STS ); +}
drivers/net/ethernet/stmicro/stmmac/dwmac5.h +6 -1
@@ -39,6 +39,9 @@#define MAC_PPSx_INTERVAL (x) (0x00000b88 + ((x) * 0x10))#define MAC_PPSx_WIDTH (x) (0x00000b8c + ((x) * 0x10)) +#define MTL_FPE_CTRL_STS 0x00000c90 +#define AFSZ GENMASK(1, 0) +#define MTL_RXP_CONTROL_STATUS 0x00000ca0#define RXPI BIT(31)#define NPE GENMASK(23, 16)
@@ -104,10 +107,12 @@ int dwmac5_flex_pps_config(void __iomem *ioaddr, int index, u32 sub_second_inc, u32 systime_flags);void dwmac5_fpe_configure (void __iomem *ioaddr,struct stmmac_fpe_cfg *cfg,u32 num_txq,u32 num_rxq, -bool enable); +bool tx_enable,bool pmac_enable);void dwmac5_fpe_send_mpacket (void __iomem *ioaddr,struct stmmac_fpe_cfg *cfg,enum stmmac_mpacket_type type);int dwmac5_fpe_irq_status (void __iomem *ioaddr,struct net_device *dev); +int dwmac5_fpe_get_add_frag_size (void __iomem *ioaddr); +void dwmac5_fpe_set_add_frag_size (void __iomem *ioaddr,u32 add_frag_size);#endif /* __DWMAC5_H__ */
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c +2 -2
@@ -1506,11 +1506,11 @@ static void dwxgmac2_set_arp_offload(struct mac_device_info *hw, bool en,static void dwxgmac3_fpe_configure (void __iomem *ioaddr,struct stmmac_fpe_cfg *cfg,u32 num_txq, -u32 num_rxq,bool enable) +u32 num_rxq,bool tx_enable,bool pmac_enable) {u32 value; -if (!enable) { +if (!tx_enable) { value =readl (ioaddr +XGMAC_FPE_CTRL_STS ); value &= ~XGMAC_EFPE ;
drivers/net/ethernet/stmicro/stmmac/hwif.h +7 -1
@@ -421,11 +421,13 @@ struct stmmac_ops {void (*set_arp_offload)(struct mac_device_info *hw,bool en,u32 addr);void (*fpe_configure)(void __iomem *ioaddr,struct stmmac_fpe_cfg *cfg,u32 num_txq,u32 num_rxq, -bool enable); +bool tx_enable,bool pmac_enable);void (*fpe_send_mpacket)(void __iomem *ioaddr,struct stmmac_fpe_cfg *cfg,enum stmmac_mpacket_type type);int (*fpe_irq_status)(void __iomem *ioaddr,struct net_device *dev); +int (*fpe_get_add_frag_size)(void __iomem *ioaddr); +void (*fpe_set_add_frag_size)(void __iomem *ioaddr,u32 add_frag_size); }; #define stmmac_core_init(__priv, __args...) \
@@ -530,6 +532,10 @@ struct stmmac_ops { stmmac_do_void_callback(__priv, mac, fpe_send_mpacket, __args) #define stmmac_fpe_irq_status(__priv, __args...) \ stmmac_do_callback(__priv, mac, fpe_irq_status, __args) +#define stmmac_fpe_get_add_frag_size(__priv, __args...) \ + stmmac_do_callback(__priv, mac, fpe_get_add_frag_size, __args) +#define stmmac_fpe_set_add_frag_size(__priv, __args...) \ + stmmac_do_void_callback(__priv, mac, fpe_set_add_frag_size, __args)/* PTP and HW Timer helpers */ struct stmmac_hwtimestamp {
drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +110 -0
128 lines not on this page · raw message
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +15 -2
@@ -3537,8 +3537,21 @@ static int stmmac_hw_setup(struct net_device *dev, bool ptp_register)stmmac_set_hw_vlan_mode (priv, priv->hw); -if (priv->dma_cap.fpesel) +if (priv->dma_cap.fpesel) { +/* A SW reset just happened in stmmac_init_dma_engine(), +* we should restore fpe_cfg to HW, or FPE will stop working +* from suspend/resume. +*/ +spin_lock (&priv->fpe_cfg.lock); +stmmac_fpe_configure (priv, priv->ioaddr, + &priv->fpe_cfg, + priv->plat->tx_queues_to_use, + priv->plat->rx_queues_to_use, + false, priv->fpe_cfg.pmac_enabled); +spin_unlock (&priv->fpe_cfg.lock); +stmmac_fpe_start_wq (priv); + }return 0 ; }
@@ -7417,7 +7430,7 @@ static void stmmac_fpe_verify_task(struct work_struct *work)stmmac_fpe_configure (priv, priv->ioaddr, fpe_cfg, priv->plat->tx_queues_to_use, priv->plat->rx_queues_to_use, - false); + false, fpe_cfg->pmac_enabled);spin_unlock_irqrestore (&priv->fpe_cfg.lock, flags);break ; }
drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c +1 -1
@@ -1093,7 +1093,7 @@ static int tc_taprio_configure(struct stmmac_priv *priv, &priv->fpe_cfg, priv->plat->tx_queues_to_use, priv->plat->rx_queues_to_use, - false); + false, false);netdev_info (priv->dev,"disabled FPE\n" );return ret;
Signature · 1 line
2.34.1
Re: [PATCH net-next v4 4/7] net: stmmac: configure FPE via ethtool-mm
From: Furong Xu <[email protected]>
Date: Tue, 20 Aug 2024 17:38:32 +0800
Quoted 6 lines
Implement ethtool --show-mm and --set-mm callbacks.
NIC up/down, link up/down, suspend/resume, kselftest-ethtool_mm, all tested okay.
Signed-off-by Furong Xu <[email protected]>
[...]
drivers/net/ethernet/stmicro/stmmac/dwmac5.c void dwmac5_fpe_configure(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg, · line 598
Quoted 11 lines
drivers/net/ethernet/stmicro/stmmac/dwmac5.c +7
-0@@ -589,6 +589,21 @@ void dwmac5_fpe_configure(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg, cfg->fpe_csr =0 ; }writel (cfg->fpe_csr, ioaddr +MAC_FPE_CTRL_STS ); + + value =readl (ioaddr +GMAC_INT_EN ); + +if (pmac_enable) { +if (!(value &GMAC_INT_FPE_EN )) { +/* Dummy read to clear any pending masked interrupts */ + (void )readl (ioaddr +MAC_FPE_CTRL_STS );
Are you sure this cast to void is needed? Have you seen readl() with __must_check anywhere?
Quoted 12 lines
drivers/net/ethernet/stmicro/stmmac/dwmac5.c +8
-0+ + value |=GMAC_INT_FPE_EN ; + } + }else { + value &= ~GMAC_INT_FPE_EN ; + } + +writel (value, ioaddr +GMAC_INT_EN ); }int dwmac5_fpe_irq_status (void __iomem *ioaddr,struct net_device *dev)
drivers/net/ethernet/stmicro/stmmac/dwmac5.c void dwmac5_fpe_send_mpacket(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg, · line 657
Quoted 5 lines
drivers/net/ethernet/stmicro/stmmac/dwmac5.c +2
-0@@ -638,3 +653,20 @@ void dwmac5_fpe_send_mpacket(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg,writel (value, ioaddr +MAC_FPE_CTRL_STS ); } + +int dwmac5_fpe_get_add_frag_size (void __iomem *ioaddr)
@ioaddr can be const.
Quoted 4 lines
drivers/net/ethernet/stmicro/stmmac/dwmac5.c +4
-0+{ +return FIELD_GET (AFSZ ,readl (ioaddr +MTL_FPE_CTRL_STS )); +} +
drivers/net/ethernet/stmicro/stmmac/dwmac5.c void dwmac5_fpe_send_mpacket(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg, · line 671
Quoted 10 lines
drivers/net/ethernet/stmicro/stmmac/dwmac5.c +10
-0+void dwmac5_fpe_set_add_frag_size (void __iomem *ioaddr,u32 add_frag_size) +{ +u32 value; + + value =readl (ioaddr +MTL_FPE_CTRL_STS ); + + value &= ~AFSZ ; + value |=FIELD_PREP (AFSZ , add_frag_size); + +writel (value, ioaddr +MTL_FPE_CTRL_STS );
value = readl(ioaddr + MTL_FPE_CTRL_STS); writel(u32_replace_bits(value, add_frag_size, AFSZ), ioaddr + MTL_FPE_CTRL_STS);
drivers/net/ethernet/stmicro/stmmac/dwmac5.h line 43
Quoted 11 lines
(quoted diff) +1
-0+}drivers/net/ethernet/stmicro/stmmac/dwmac5.h +2
-0@@ -39,6 +39,9 @@#define MAC_PPSx_INTERVAL (x) (0x00000b88 + ((x) * 0x10))#define MAC_PPSx_WIDTH (x) (0x00000b8c + ((x) * 0x10)) +#define MTL_FPE_CTRL_STS 0x00000c90 +#define AFSZ GENMASK(1, 0)
Can you leave comments next to definitions explaining what this is? I guessed AFSZ is "added frag size", but meh...
Also, I'd prefix every definition with some vendor prefix (STMMAC_ or so), otherwise it may conflict one day with some generic one.
Quoted 4 lines
drivers/net/ethernet/stmicro/stmmac/dwmac5.h +1
-0+#define MTL_RXP_CONTROL_STATUS 0x00000ca0#define RXPI BIT(31)#define NPE GENMASK(23, 16)
[...]
Quoted 10 lines
drivers/net/ethernet/stmicro/stmmac/dwmac5.h +6
-0@@ -1270,6 +1271,112 @@ static int stmmac_set_tunable(struct net_device *dev,return ret; } +static int stmmac_get_mm (struct net_device *ndev, +struct ethtool_mm_state *state) +{ +struct stmmac_priv *priv =netdev_priv (ndev); +unsigned long flags; +u32 add_frag_size;
drivers/net/ethernet/stmicro/stmmac/dwmac5.h static int stmmac_set_tunable(struct net_device *dev, · line 1289
Quoted 10 lines
drivers/net/ethernet/stmicro/stmmac/dwmac5.h +10
-0+ +if (!priv->dma_cap.fpesel) +return -EOPNOTSUPP ; + +spin_lock_irqsave (&priv->fpe_cfg.lock, flags); + + state->pmac_enabled = priv->fpe_cfg.pmac_enabled; + state->verify_time = priv->fpe_cfg.verify_time; + state->verify_enabled = priv->fpe_cfg.verify_enabled; + state->verify_status = priv->fpe_cfg.status;
See, you could embed ðtool_mm_state into &fpe_cfg as I wrote under the previous patch, so that you could do a direct assignment here :D
drivers/net/ethernet/stmicro/stmmac/dwmac5.h static int stmmac_set_tunable(struct net_device *dev, · line 1294
Quoted 5 lines
drivers/net/ethernet/stmicro/stmmac/dwmac5.h +5
-0+ state->rx_min_frag_size =ETH_ZLEN ; + +/* 802.3-2018 clause 30.14.1.6, says that the aMACMergeVerifyTime +* variable has a range between 1 and 128 ms inclusive. Limit to that. +*/
Also make it a definition.
drivers/net/ethernet/stmicro/stmmac/dwmac5.h static int stmmac_set_tunable(struct net_device *dev, · line 1300
Quoted 6 lines
drivers/net/ethernet/stmicro/stmmac/dwmac5.h +6
-0+ state->max_verify_time =128 ; + +/* Cannot read MAC_FPE_CTRL_STS register here, or FPE interrupt events +* can be lost. +* +* See commit 37e4b8df27bc ("net: stmmac: fix FPE events losing")
I think it's not needed to leave commit references in the code?
drivers/net/ethernet/stmicro/stmmac/dwmac5.h static int stmmac_set_tunable(struct net_device *dev, · line 1302
Quoted 2 lines
drivers/net/ethernet/stmicro/stmmac/dwmac5.h +2
-0+*/ + state->tx_enabled = !!(priv->fpe_cfg.fpe_csr ==EFPE );
tx_enabled is bool, you don't need to add a double negation here (the parenthesis are redundant as well).
Quoted 13 lines
drivers/net/ethernet/stmicro/stmmac/dwmac5.h +13
-0+ +/* FPE active if common tx_enabled and verification success or disabled (forced) */ + state->tx_active = state->tx_enabled && + (state->verify_status ==ETHTOOL_MM_VERIFY_STATUS_SUCCEEDED || + state->verify_status ==ETHTOOL_MM_VERIFY_STATUS_DISABLED ); + + add_frag_size =stmmac_fpe_get_add_frag_size (priv, priv->ioaddr); + state->tx_min_frag_size =ethtool_mm_frag_size_add_to_min (add_frag_size); + +spin_unlock_irqrestore (&priv->fpe_cfg.lock, flags); + +return 0 ; +}
[...]
Quoted 5 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +0
-0
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c static int stmmac_hw_setup(struct net_device *dev, bool ptp_register) · line 3545
Quoted 10 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +6
-1@@ -3537,8 +3537,21 @@ static int stmmac_hw_setup(struct net_device *dev, bool ptp_register)stmmac_set_hw_vlan_mode (priv, priv->hw); -if (priv->dma_cap.fpesel) +if (priv->dma_cap.fpesel) { +/* A SW reset just happened in stmmac_init_dma_engine(), +* we should restore fpe_cfg to HW, or FPE will stop working +* from suspend/resume. +*/ +spin_lock (&priv->fpe_cfg.lock);
I don't think this happens in the interrupt context, so you need _irqsave() version here?
Quoted 13 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +8
-0+stmmac_fpe_configure (priv, priv->ioaddr, + &priv->fpe_cfg, + priv->plat->tx_queues_to_use, + priv->plat->rx_queues_to_use, + false, priv->fpe_cfg.pmac_enabled); +spin_unlock (&priv->fpe_cfg.lock); +stmmac_fpe_start_wq (priv); + }return 0 ; }
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c static void stmmac_fpe_verify_task(struct work_struct *work) · line 7436
Quoted 8 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +1
-1@@ -7417,7 +7430,7 @@ static void stmmac_fpe_verify_task(struct work_struct *work)stmmac_fpe_configure (priv, priv->ioaddr, fpe_cfg, priv->plat->tx_queues_to_use, priv->plat->rx_queues_to_use, - false); + false, fpe_cfg->pmac_enabled);spin_unlock_irqrestore (&priv->fpe_cfg.lock, flags);break ; }
[...]
Thanks,
Olek
PATCH v4 5/7 net: stmmac: support fp parameter of tc-mqprio
In reply to Furong Xutc-mqprio can select whether traffic classes are express or preemptible.
After some traffic tests, MAC merge layer statistics are all good.
Local device:
ethtool --include-statistics --json --show-mm eth1
[ {
"ifname": "eth1",
"pmac-enabled": true,
"tx-enabled": true,
"tx-active": true,
"tx-min-frag-size": 60,
"rx-min-frag-size": 60,
"verify-enabled": true,
"verify-time": 100,
"max-verify-time": 128,
"verify-status": "SUCCEEDED",
"statistics": {
"MACMergeFrameAssErrorCount": 0,
"MACMergeFrameSmdErrorCount": 0,
"MACMergeFrameAssOkCount": 0,
"MACMergeFragCountRx": 0,
"MACMergeFragCountTx": 35105,
"MACMergeHoldCount": 0
}
} ]Remote device:
ethtool --include-statistics --json --show-mm end1
[ {
"ifname": "end1",
"pmac-enabled": true,
"tx-enabled": true,
"tx-active": true,
"tx-min-frag-size": 60,
"rx-min-frag-size": 60,
"verify-enabled": true,
"verify-time": 100,
"max-verify-time": 128,
"verify-status": "SUCCEEDED",
"statistics": {
"MACMergeFrameAssErrorCount": 0,
"MACMergeFrameSmdErrorCount": 0,
"MACMergeFrameAssOkCount": 35105,
"MACMergeFragCountRx": 35105,
"MACMergeFragCountTx": 0,
"MACMergeHoldCount": 0
}
} ]Tested on DWMAC CORE 5.10a
--- .../net/ethernet/stmicro/stmmac/dwmac4_core.c | 2 + drivers/net/ethernet/stmicro/stmmac/dwmac5.c | 52 ++++++++++++ drivers/net/ethernet/stmicro/stmmac/dwmac5.h | 4 + drivers/net/ethernet/stmicro/stmmac/hwif.h | 10 +++ .../net/ethernet/stmicro/stmmac/stmmac_main.c | 2 + .../net/ethernet/stmicro/stmmac/stmmac_tc.c | 81 +++++++++++++++++++ 6 files changed, 151 insertions(+)
drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +2 -0
@@ -1266,6 +1266,7 @@ const struct stmmac_ops dwmac410_ops = { .fpe_irq_status = dwmac5_fpe_irq_status, .fpe_get_add_frag_size = dwmac5_fpe_get_add_frag_size, .fpe_set_add_frag_size = dwmac5_fpe_set_add_frag_size, + .fpe_set_preemptible_tcs = dwmac5_fpe_set_preemptible_tcs, .add_hw_vlan_rx_fltr = dwmac4_add_hw_vlan_rx_fltr, .del_hw_vlan_rx_fltr = dwmac4_del_hw_vlan_rx_fltr, .restore_hw_vlan_rx_fltr = dwmac4_restore_hw_vlan_rx_fltr,
@@ -1320,6 +1321,7 @@ const struct stmmac_ops dwmac510_ops = { .fpe_irq_status = dwmac5_fpe_irq_status, .fpe_get_add_frag_size = dwmac5_fpe_get_add_frag_size, .fpe_set_add_frag_size = dwmac5_fpe_set_add_frag_size, + .fpe_set_preemptible_tcs = dwmac5_fpe_set_preemptible_tcs, .add_hw_vlan_rx_fltr = dwmac4_add_hw_vlan_rx_fltr, .del_hw_vlan_rx_fltr = dwmac4_del_hw_vlan_rx_fltr, .restore_hw_vlan_rx_fltr = dwmac4_restore_hw_vlan_rx_fltr,
drivers/net/ethernet/stmicro/stmmac/dwmac5.c +52 -0
55 lines not on this page · raw message
drivers/net/ethernet/stmicro/stmmac/dwmac5.h +4 -0
@@ -40,6 +40,7 @@#define MAC_PPSx_WIDTH (x) (0x00000b8c + ((x) * 0x10))#define MTL_FPE_CTRL_STS 0x00000c90 +#define PEC GENMASK(15, 8)#define AFSZ GENMASK(1, 0)#define MTL_RXP_CONTROL_STATUS 0x00000ca0
@@ -114,5 +115,8 @@ void dwmac5_fpe_send_mpacket(void __iomem *ioaddr,int dwmac5_fpe_irq_status (void __iomem *ioaddr,struct net_device *dev);int dwmac5_fpe_get_add_frag_size (void __iomem *ioaddr);void dwmac5_fpe_set_add_frag_size (void __iomem *ioaddr,u32 add_frag_size); +int dwmac5_fpe_set_preemptible_tcs (struct net_device *ndev, +struct netlink_ext_ack *extack, +unsigned long tcs);#endif /* __DWMAC5_H__ */
drivers/net/ethernet/stmicro/stmmac/hwif.h +10 -0
@@ -7,6 +7,7 @@#include <linux/netdevice.h> #include <linux/stmmac.h> +#include <net/pkt_cls.h> #define stmmac_do_void_callback(__priv, __module, __cname, __arg0, __args...) \ ({ \
@@ -428,6 +429,9 @@ struct stmmac_ops {int (*fpe_irq_status)(void __iomem *ioaddr,struct net_device *dev);int (*fpe_get_add_frag_size)(void __iomem *ioaddr);void (*fpe_set_add_frag_size)(void __iomem *ioaddr,u32 add_frag_size); +int (*fpe_set_preemptible_tcs)(struct net_device *ndev, +struct netlink_ext_ack *extack, +unsigned long tcs); }; #define stmmac_core_init(__priv, __args...) \
@@ -536,6 +540,8 @@ struct stmmac_ops { stmmac_do_callback(__priv, mac, fpe_get_add_frag_size, __args) #define stmmac_fpe_set_add_frag_size(__priv, __args...) \ stmmac_do_void_callback(__priv, mac, fpe_set_add_frag_size, __args) +#define stmmac_fpe_set_preemptible_tcs(__priv, __args...) \ + stmmac_do_callback(__priv, mac, fpe_set_preemptible_tcs, __args)/* PTP and HW Timer helpers */ struct stmmac_hwtimestamp {
@@ -623,6 +629,8 @@ struct stmmac_tc_ops { struct tc_etf_qopt_offload *qopt);int (*query_caps)(struct stmmac_priv *priv,struct tc_query_caps_base *base); +int (*setup_mqprio)(struct stmmac_priv *priv, +struct tc_mqprio_qopt_offload *qopt); }; #define stmmac_tc_init(__priv, __args...) \
@@ -639,6 +647,8 @@ struct stmmac_tc_ops { stmmac_do_callback(__priv, tc, setup_etf, __args) #define stmmac_tc_query_caps(__priv, __args...) \ stmmac_do_callback(__priv, tc, query_caps, __args) +#define stmmac_tc_setup_mqprio(__priv, __args...) \ + stmmac_do_callback(__priv, tc, setup_mqprio, __args)struct stmmac_counters ;
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +2 -0
@@ -6274,6 +6274,8 @@ static int stmmac_setup_tc(struct net_device *ndev, enum tc_setup_type type,switch (type) {case TC_QUERY_CAPS :return stmmac_tc_query_caps (priv, priv, type_data); +case TC_SETUP_QDISC_MQPRIO : +return stmmac_tc_setup_mqprio (priv, priv, type_data);case TC_SETUP_BLOCK : return flow_block_cb_setup_simple(type_data, &stmmac_block_cb_list,
drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c +81 -0
103 lines not on this page · raw message
Signature · 1 line
2.34.1
Re: [PATCH net-next v4 5/7] net: stmmac: support fp parameter of tc-mqprio
Quoted 10 lines · Furong Xu
drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c +10
-0+static int tc_setup_mqprio (struct stmmac_priv *priv, +struct tc_mqprio_qopt_offload *mqprio) +{ +struct netlink_ext_ack *extack = mqprio->extack; +struct tc_mqprio_qopt *qopt = &mqprio->qopt; +struct net_device *ndev = priv->dev; +int num_stack_tx_queues =0 ; +int num_tc = qopt->num_tc; +u16 offset, count; +int tc, err;
drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c static int tc_query_caps(struct stmmac_priv *priv, · line 1231
Quoted 10 lines
drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c +10
-0+ +if (!num_tc) { +stmmac_reset_tc_mqprio (ndev, extack); +return 0 ; + } + +if (mqprio->preemptible_tcs && !ethtool_dev_mm_supported (ndev)) { +NL_SET_ERR_MSG_MOD (extack,"Device does not support preemption" ); +return -EOPNOTSUPP ; + }
When I said that "this condition is dealt with by the core, now"
https://lore.kernel.org/netdev/20240819114242.2m6okk7bq64e437c@skbuf/
I meant that the driver doesn't need to check anything - the check has already run once, in the Qdisc layer. See taprio_parse_tc_entries() and mqprio_parse_tc_entries(). I was not asking to insert this test, just to completely remove, rather than adapt, the entire block:
if (fpe && !priv->dma_cap.fpesel) {
mutex_unlock(&priv->est_lock);
return -EOPNOTSUPP;
}Re: [PATCH net-next v4 5/7] net: stmmac: support fp parameter of tc-mqprio
In reply to Furong XuFrom: Furong Xu <[email protected]>
Date: Tue, 20 Aug 2024 17:38:33 +0800
Quoted 3 lines
tc-mqprio can select whether traffic classes are express or preemptible.
After some traffic tests, MAC merge layer statistics are all good.
[...]
Quoted 5 lines
drivers/net/ethernet/stmicro/stmmac/dwmac5.c +0
-0
drivers/net/ethernet/stmicro/stmmac/dwmac5.c void dwmac5_fpe_set_add_frag_size(void __iomem *ioaddr, u32 add_frag_size) · line 678
Quoted 9 lines
drivers/net/ethernet/stmicro/stmmac/dwmac5.c +6
-0@@ -670,3 +670,55 @@ void dwmac5_fpe_set_add_frag_size(void __iomem *ioaddr, u32 add_frag_size)writel (value, ioaddr +MTL_FPE_CTRL_STS ); } + +int dwmac5_fpe_set_preemptible_tcs (struct net_device *ndev, +struct netlink_ext_ack *extack, +unsigned long tcs) +{ +struct stmmac_priv *priv =netdev_priv (ndev);
Can't it be const?
drivers/net/ethernet/stmicro/stmmac/dwmac5.c void dwmac5_fpe_set_add_frag_size(void __iomem *ioaddr, u32 add_frag_size) · line 680
Quoted 2 lines
drivers/net/ethernet/stmicro/stmmac/dwmac5.c +2
-0+void __iomem *ioaddr = priv->ioaddr; +unsigned long queue_tcs =0 ;
Why is @tcs and @queue_tcs unsigned long? You write @queue_tcs via writel(), IOW it can't go past %U32_MAX.
drivers/net/ethernet/stmicro/stmmac/dwmac5.c void dwmac5_fpe_set_add_frag_size(void __iomem *ioaddr, u32 add_frag_size) · line 683
Quoted 3 lines
drivers/net/ethernet/stmicro/stmmac/dwmac5.c +3
-0+int num_tc = ndev->num_tc; +u32 value, queue_weight; +u16 offset, count;
Just use u32 here for all three.
drivers/net/ethernet/stmicro/stmmac/dwmac5.c void dwmac5_fpe_set_add_frag_size(void __iomem *ioaddr, u32 add_frag_size) · line 689
Quoted 6 lines
drivers/net/ethernet/stmicro/stmmac/dwmac5.c +6
-0+int tc, i; + +if (!tcs) + goto __update_queue_tcs; + +for (tc =0 ; tc < num_tc; tc++) {
@tc can be declared right here in the loop declaration. Also it's u32 as it can't be negative.
Quoted 7 lines
drivers/net/ethernet/stmicro/stmmac/dwmac5.c +7
-0+ count = ndev->tc_to_txq[tc].count; + offset = ndev->tc_to_txq[tc].offset; + +if (tcs &BIT (tc)) + queue_tcs |=GENMASK (offset + count -1 , offset); + +/* This is 1:1 mapping, go to next TC */
drivers/net/ethernet/stmicro/stmmac/dwmac5.c void dwmac5_fpe_set_add_frag_size(void __iomem *ioaddr, u32 add_frag_size) · line 706
Quoted 10 lines
drivers/net/ethernet/stmicro/stmmac/dwmac5.c +10
-0+if (count ==1 ) +continue ; + +if (priv->plat->tx_sched_algorithm ==MTL_TX_ALGORITHM_SP ) { +NL_SET_ERR_MSG_MOD (extack,"TX algorithm SP is not suitable for one TC to multiple TXQs mapping" ); +return -EINVAL ; + } + + queue_weight = priv->plat->tx_queues_cfg[offset].weight; +for (i =1 ; i < count; i++) {
Same as with @tc for everything.
drivers/net/ethernet/stmicro/stmmac/dwmac5.c void dwmac5_fpe_set_add_frag_size(void __iomem *ioaddr, u32 add_frag_size) · line 715
Quoted 9 lines
drivers/net/ethernet/stmicro/stmmac/dwmac5.c +9
-0+if (queue_weight != priv->plat->tx_queues_cfg[offset + i].weight) { +NL_SET_ERR_MSG_FMT_MOD (extack,"TXQ weight [%u] differs across other TXQs in TC: [%u]" , + queue_weight, tc); +return -EINVAL ; + } + } + } + +__update_queue_tcs:
Again underscores.
drivers/net/ethernet/stmicro/stmmac/dwmac5.c void dwmac5_fpe_set_add_frag_size(void __iomem *ioaddr, u32 add_frag_size) · line 721
Quoted 6 lines
drivers/net/ethernet/stmicro/stmmac/dwmac5.c +6
-0+ value =readl (ioaddr +MTL_FPE_CTRL_STS ); + + value &= ~PEC ; + value |=FIELD_PREP (PEC , queue_tcs); + +writel (value, ioaddr +MTL_FPE_CTRL_STS );
These are also u32_replace_bits() as in the previous patch.
drivers/net/ethernet/stmicro/stmmac/dwmac5.h line 43
Quoted 12 lines
drivers/net/ethernet/stmicro/stmmac/dwmac5.c +3
-0+ +return 0 ; +}drivers/net/ethernet/stmicro/stmmac/dwmac5.h +1
-0@@ -40,6 +40,7 @@#define MAC_PPSx_WIDTH (x) (0x00000b8c + ((x) * 0x10))#define MTL_FPE_CTRL_STS 0x00000c90 +#define PEC GENMASK(15, 8)
Again some driver prefix would be nice to see.
Quoted 3 lines
drivers/net/ethernet/stmicro/stmmac/dwmac5.h +0
-0#define AFSZ GENMASK(1, 0)#define MTL_RXP_CONTROL_STATUS 0x00000ca0
[...]
drivers/net/ethernet/stmicro/stmmac/dwmac5.h static int tc_query_caps(struct stmmac_priv *priv, · line 1181
Quoted 8 lines
drivers/net/ethernet/stmicro/stmmac/dwmac5.h +4
-0@@ -1174,6 +1175,13 @@ static int tc_query_caps(struct stmmac_priv *priv, struct tc_query_caps_base *base) {switch (base->type) { +case TC_SETUP_QDISC_MQPRIO : { +struct tc_mqprio_caps *caps = base->caps; + + caps->validate_queue_counts = true;
Why not base->caps->blah directly? I think it would fit 80 cols?
Quoted 20 lines
drivers/net/ethernet/stmicro/stmmac/dwmac5.h +13
-0+ +return 0 ; + }case TC_SETUP_QDISC_TAPRIO : {struct tc_taprio_caps *caps = base->caps;@@ -1190,6 +1198,78 @@ static int tc_query_caps(struct stmmac_priv *priv, } } +static void stmmac_reset_tc_mqprio (struct net_device *ndev, +struct netlink_ext_ack *extack) +{ +struct stmmac_priv *priv =netdev_priv (ndev); + +netdev_reset_tc (ndev); +netif_set_real_num_tx_queues (ndev, priv->plat->tx_queues_to_use); + +stmmac_fpe_set_preemptible_tcs (priv, ndev, extack,0 ); +}
drivers/net/ethernet/stmicro/stmmac/dwmac5.h static int tc_query_caps(struct stmmac_priv *priv, · line 1220
Quoted 10 lines
drivers/net/ethernet/stmicro/stmmac/dwmac5.h +10
-0+ +static int tc_setup_mqprio (struct stmmac_priv *priv, +struct tc_mqprio_qopt_offload *mqprio) +{ +struct netlink_ext_ack *extack = mqprio->extack; +struct tc_mqprio_qopt *qopt = &mqprio->qopt; +struct net_device *ndev = priv->dev; +int num_stack_tx_queues =0 ; +int num_tc = qopt->num_tc; +u16 offset, count;
Also u32 for most of these.
Quoted 7 lines
drivers/net/ethernet/stmicro/stmmac/dwmac5.h +7
-0+int tc, err; + +if (!num_tc) { +stmmac_reset_tc_mqprio (ndev, extack); +return 0 ; + } +
drivers/net/ethernet/stmicro/stmmac/dwmac5.h static int tc_query_caps(struct stmmac_priv *priv, · line 1237
Quoted 10 lines
drivers/net/ethernet/stmicro/stmmac/dwmac5.h +10
-0+if (mqprio->preemptible_tcs && !ethtool_dev_mm_supported (ndev)) { +NL_SET_ERR_MSG_MOD (extack,"Device does not support preemption" ); +return -EOPNOTSUPP ; + } + + err =netdev_set_num_tc (ndev, num_tc); +if (err) +return err; + +/* DWMAC CORE4+ can not programming TC:TXQ mapping to hardware.
"can't program" or "can't do programming" or "doesn't support programming".
drivers/net/ethernet/stmicro/stmmac/dwmac5.h static int tc_query_caps(struct stmmac_priv *priv, · line 1245
Quoted 8 lines
drivers/net/ethernet/stmicro/stmmac/dwmac5.h +8
-0+* Synopsys Databook: +* "The number of Tx DMA channels is equal to the number of Tx queues, +* and is direct one-to-one mapping." +* +* Luckily, DWXGMAC CORE can. +* +* Thus preemptible_tcs should be handled in a per core manner. +*/
[...]
Thanks,
Olek
PATCH v4 6/7 net: stmmac: support fp parameter of tc-taprio
In reply to Furong Xutc-taprio can select whether traffic classes are express or preemptible.
0) tc qdisc add dev eth1 parent root handle 100 taprio \
num_tc 4 \
map 0 1 2 3 2 2 2 2 2 2 2 2 2 2 2 3 \
queues 1@0 1@1 1@2 1@3 \
base-time 1000000000 \
sched-entry S 03 10000000 \
sched-entry S 0e 10000000 \
flags 0x2 fp P E E E1) After some traffic tests, MAC merge layer statistics are all good.
Local device:
[ {
"ifname": "eth1",
"pmac-enabled": true,
"tx-enabled": true,
"tx-active": true,
"tx-min-frag-size": 60,
"rx-min-frag-size": 60,
"verify-enabled": true,
"verify-time": 100,
"max-verify-time": 128,
"verify-status": "SUCCEEDED",
"statistics": {
"MACMergeFrameAssErrorCount": 0,
"MACMergeFrameSmdErrorCount": 0,
"MACMergeFrameAssOkCount": 0,
"MACMergeFragCountRx": 0,
"MACMergeFragCountTx": 17837,
"MACMergeHoldCount": 18639
}
} ]Remote device:
[ {
"ifname": "end1",
"pmac-enabled": true,
"tx-enabled": true,
"tx-active": true,
"tx-min-frag-size": 60,
"rx-min-frag-size": 60,
"verify-enabled": true,
"verify-time": 100,
"max-verify-time": 128,
"verify-status": "SUCCEEDED",
"statistics": {
"MACMergeFrameAssErrorCount": 0,
"MACMergeFrameSmdErrorCount": 0,
"MACMergeFrameAssOkCount": 17189,
"MACMergeFragCountRx": 17837,
"MACMergeFragCountTx": 0,
"MACMergeHoldCount": 0
}
} ]Tested on DWMAC CORE 5.10a
--- .../net/ethernet/stmicro/stmmac/stmmac_tc.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-)
drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c +8 -11
@@ -932,9 +932,9 @@ static int tc_taprio_configure(struct stmmac_priv *priv, struct tc_taprio_qopt_offload *qopt) {u32 size, wid = priv->dma_cap.estwid, dep = priv->dma_cap.estdep; +struct netlink_ext_ack *extack = qopt->mqprio.extack;struct timespec64 time, current_time, qopt_time;ktime_t current_time_ns; -bool fpe = false;int i, ret =0 ;u64 ctr;
@@ -1019,16 +1019,12 @@ static int tc_taprio_configure(struct stmmac_priv *priv,switch (qopt->entries[i].command) {case TC_TAPRIO_CMD_SET_GATES : -if (fpe) -return -EINVAL ;break ;case TC_TAPRIO_CMD_SET_AND_HOLD : gates |=BIT (0 ); - fpe = true;break ;case TC_TAPRIO_CMD_SET_AND_RELEASE : gates &= ~BIT (0 ); - fpe = true;break ;default :return -EOPNOTSUPP ;
@@ -1059,7 +1055,8 @@ static int tc_taprio_configure(struct stmmac_priv *priv,tc_taprio_map_maxsdu_txq (priv, qopt); -if (fpe && !priv->dma_cap.fpesel) { +if (qopt->mqprio.preemptible_tcs && !ethtool_dev_mm_supported (priv->dev)) { +NL_SET_ERR_MSG_MOD (extack,"Device does not support preemption" );mutex_unlock (&priv->est_lock);return -EOPNOTSUPP ; }
@@ -1072,6 +1069,9 @@ static int tc_taprio_configure(struct stmmac_priv *priv, goto disable; } +stmmac_fpe_set_preemptible_tcs (priv, priv->dev, extack, + qopt->mqprio.preemptible_tcs); +netdev_info (priv->dev,"configured EST\n" );return 0 ;
@@ -1090,11 +1090,8 @@ static int tc_taprio_configure(struct stmmac_priv *priv,mutex_unlock (&priv->est_lock); } -stmmac_fpe_configure (priv, priv->ioaddr, - &priv->fpe_cfg, - priv->plat->tx_queues_to_use, - priv->plat->rx_queues_to_use, - false, false); +stmmac_fpe_set_preemptible_tcs (priv, priv->dev, extack,0 ); +netdev_info (priv->dev,"disabled FPE\n" );return ret;
Signature · 1 line
2.34.1
PATCH v4 7/7 net: stmmac: silence FPE kernel logs
In reply to Furong Xuethtool --show-mm can get real-time state of FPE.
Those kernel logs should keep quiet.
--- drivers/net/ethernet/stmicro/stmmac/dwmac5.c | 8 ++++---- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-)
drivers/net/ethernet/stmicro/stmmac/dwmac5.c +4 -4
@@ -620,22 +620,22 @@ int dwmac5_fpe_irq_status(void __iomem *ioaddr, struct net_device *dev)if (value &TRSP ) { status |=FPE_EVENT_TRSP ; -netdev_info (dev,"FPE: Respond mPacket is transmitted\n" ); +netdev_dbg (dev,"FPE: Respond mPacket is transmitted\n" ); }if (value &TVER ) { status |=FPE_EVENT_TVER ; -netdev_info (dev,"FPE: Verify mPacket is transmitted\n" ); +netdev_dbg (dev,"FPE: Verify mPacket is transmitted\n" ); }if (value &RRSP ) { status |=FPE_EVENT_RRSP ; -netdev_info (dev,"FPE: Respond mPacket is received\n" ); +netdev_dbg (dev,"FPE: Respond mPacket is received\n" ); }if (value &RVER ) { status |=FPE_EVENT_RVER ; -netdev_info (dev,"FPE: Verify mPacket is received\n" ); +netdev_dbg (dev,"FPE: Verify mPacket is received\n" ); }return status;
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +2 -2
@@ -3378,7 +3378,7 @@ static int stmmac_fpe_start_wq(struct stmmac_priv *priv)return -ENOMEM ; } -netdev_info (priv->dev,"FPE workqueue start" ); +netdev_dbg (priv->dev,"FPE workqueue start" );return 0 ; }
@@ -4058,7 +4058,7 @@ static void stmmac_fpe_stop_wq(struct stmmac_priv *priv) priv->fpe_wq =NULL ; } -netdev_info (priv->dev,"FPE workqueue stop" ); +netdev_dbg (priv->dev,"FPE workqueue stop" ); }/**
Signature · 1 line
2.34.1