2727#define STMMAC_MAC_FPE_CTRL_STS_SVER BIT(1)
2828#define STMMAC_MAC_FPE_CTRL_STS_EFPE BIT(0)
2929
30- /* FPE link-partner hand-shaking mPacket type */
31- enum stmmac_mpacket_type {
32- MPACKET_VERIFY = 0 ,
33- MPACKET_RESPONSE = 1 ,
34- };
35-
3630struct stmmac_fpe_reg {
3731 const u32 mac_fpe_reg ; /* offset of MAC_FPE_CTRL_STS */
3832 const u32 mtl_fpe_reg ; /* offset of MTL_FPE_CTRL_STS */
@@ -48,10 +42,10 @@ bool stmmac_fpe_supported(struct stmmac_priv *priv)
4842 priv -> hw -> mac -> fpe_map_preemption_class ;
4943}
5044
51- static void stmmac_fpe_configure (struct stmmac_priv * priv , bool tx_enable ,
52- bool pmac_enable )
45+ static void stmmac_fpe_configure_tx (struct ethtool_mmsv * mmsv , bool tx_enable )
5346{
54- struct stmmac_fpe_cfg * cfg = & priv -> fpe_cfg ;
47+ struct stmmac_fpe_cfg * cfg = container_of (mmsv , struct stmmac_fpe_cfg , mmsv );
48+ struct stmmac_priv * priv = container_of (cfg , struct stmmac_priv , fpe_cfg );
5549 const struct stmmac_fpe_reg * reg = cfg -> reg ;
5650 u32 num_rxq = priv -> plat -> rx_queues_to_use ;
5751 void __iomem * ioaddr = priv -> ioaddr ;
@@ -68,6 +62,15 @@ static void stmmac_fpe_configure(struct stmmac_priv *priv, bool tx_enable,
6862 cfg -> fpe_csr = 0 ;
6963 }
7064 writel (cfg -> fpe_csr , ioaddr + reg -> mac_fpe_reg );
65+ }
66+
67+ static void stmmac_fpe_configure_pmac (struct ethtool_mmsv * mmsv , bool pmac_enable )
68+ {
69+ struct stmmac_fpe_cfg * cfg = container_of (mmsv , struct stmmac_fpe_cfg , mmsv );
70+ struct stmmac_priv * priv = container_of (cfg , struct stmmac_priv , fpe_cfg );
71+ const struct stmmac_fpe_reg * reg = cfg -> reg ;
72+ void __iomem * ioaddr = priv -> ioaddr ;
73+ u32 value ;
7174
7275 value = readl (ioaddr + reg -> int_en_reg );
7376
@@ -85,47 +88,45 @@ static void stmmac_fpe_configure(struct stmmac_priv *priv, bool tx_enable,
8588 writel (value , ioaddr + reg -> int_en_reg );
8689}
8790
88- static void stmmac_fpe_send_mpacket (struct stmmac_priv * priv ,
89- enum stmmac_mpacket_type type )
91+ static void stmmac_fpe_send_mpacket (struct ethtool_mmsv * mmsv ,
92+ enum ethtool_mpacket type )
9093{
91- const struct stmmac_fpe_reg * reg = priv -> fpe_cfg .reg ;
94+ struct stmmac_fpe_cfg * cfg = container_of (mmsv , struct stmmac_fpe_cfg , mmsv );
95+ struct stmmac_priv * priv = container_of (cfg , struct stmmac_priv , fpe_cfg );
96+ const struct stmmac_fpe_reg * reg = cfg -> reg ;
9297 void __iomem * ioaddr = priv -> ioaddr ;
93- u32 value = priv -> fpe_cfg . fpe_csr ;
98+ u32 value = cfg -> fpe_csr ;
9499
95- if (type == MPACKET_VERIFY )
100+ if (type == ETHTOOL_MPACKET_VERIFY )
96101 value |= STMMAC_MAC_FPE_CTRL_STS_SVER ;
97- else if (type == MPACKET_RESPONSE )
102+ else if (type == ETHTOOL_MPACKET_RESPONSE )
98103 value |= STMMAC_MAC_FPE_CTRL_STS_SRSP ;
99104
100105 writel (value , ioaddr + reg -> mac_fpe_reg );
101106}
102107
108+ static const struct ethtool_mmsv_ops stmmac_mmsv_ops = {
109+ .configure_tx = stmmac_fpe_configure_tx ,
110+ .configure_pmac = stmmac_fpe_configure_pmac ,
111+ .send_mpacket = stmmac_fpe_send_mpacket ,
112+ };
113+
103114static void stmmac_fpe_event_status (struct stmmac_priv * priv , int status )
104115{
105116 struct stmmac_fpe_cfg * fpe_cfg = & priv -> fpe_cfg ;
117+ struct ethtool_mmsv * mmsv = & fpe_cfg -> mmsv ;
106118
107- /* This is interrupt context, just spin_lock() */
108- spin_lock (& fpe_cfg -> lock );
109-
110- if (!fpe_cfg -> pmac_enabled || status == FPE_EVENT_UNKNOWN )
111- goto unlock_out ;
119+ if (status == FPE_EVENT_UNKNOWN )
120+ return ;
112121
113- /* LP has sent verify mPacket */
114122 if ((status & FPE_EVENT_RVER ) == FPE_EVENT_RVER )
115- stmmac_fpe_send_mpacket ( priv , MPACKET_RESPONSE );
123+ ethtool_mmsv_event_handle ( mmsv , ETHTOOL_MMSV_LP_SENT_VERIFY_MPACKET );
116124
117- /* Local has sent verify mPacket */
118- if ((status & FPE_EVENT_TVER ) == FPE_EVENT_TVER &&
119- fpe_cfg -> status != ETHTOOL_MM_VERIFY_STATUS_SUCCEEDED )
120- fpe_cfg -> status = ETHTOOL_MM_VERIFY_STATUS_VERIFYING ;
125+ if ((status & FPE_EVENT_TVER ) == FPE_EVENT_TVER )
126+ ethtool_mmsv_event_handle (mmsv , ETHTOOL_MMSV_LD_SENT_VERIFY_MPACKET );
121127
122- /* LP has sent response mPacket */
123- if ((status & FPE_EVENT_RRSP ) == FPE_EVENT_RRSP &&
124- fpe_cfg -> status == ETHTOOL_MM_VERIFY_STATUS_VERIFYING )
125- fpe_cfg -> status = ETHTOOL_MM_VERIFY_STATUS_SUCCEEDED ;
126-
127- unlock_out :
128- spin_unlock (& fpe_cfg -> lock );
128+ if ((status & FPE_EVENT_RRSP ) == FPE_EVENT_RRSP )
129+ ethtool_mmsv_event_handle (mmsv , ETHTOOL_MMSV_LP_SENT_RESPONSE_MPACKET );
129130}
130131
131132void stmmac_fpe_irq_status (struct stmmac_priv * priv )
@@ -164,119 +165,16 @@ void stmmac_fpe_irq_status(struct stmmac_priv *priv)
164165 stmmac_fpe_event_status (priv , status );
165166}
166167
167- /**
168- * stmmac_fpe_verify_timer - Timer for MAC Merge verification
169- * @t: timer_list struct containing private info
170- *
171- * Verify the MAC Merge capability in the local TX direction, by
172- * transmitting Verify mPackets up to 3 times. Wait until link
173- * partner responds with a Response mPacket, otherwise fail.
174- */
175- static void stmmac_fpe_verify_timer (struct timer_list * t )
176- {
177- struct stmmac_fpe_cfg * fpe_cfg = from_timer (fpe_cfg , t , verify_timer );
178- struct stmmac_priv * priv = container_of (fpe_cfg , struct stmmac_priv ,
179- fpe_cfg );
180- unsigned long flags ;
181- bool rearm = false;
182-
183- spin_lock_irqsave (& fpe_cfg -> lock , flags );
184-
185- switch (fpe_cfg -> status ) {
186- case ETHTOOL_MM_VERIFY_STATUS_INITIAL :
187- case ETHTOOL_MM_VERIFY_STATUS_VERIFYING :
188- if (fpe_cfg -> verify_retries != 0 ) {
189- stmmac_fpe_send_mpacket (priv , MPACKET_VERIFY );
190- rearm = true;
191- } else {
192- fpe_cfg -> status = ETHTOOL_MM_VERIFY_STATUS_FAILED ;
193- }
194-
195- fpe_cfg -> verify_retries -- ;
196- break ;
197-
198- case ETHTOOL_MM_VERIFY_STATUS_SUCCEEDED :
199- stmmac_fpe_configure (priv , true, true);
200- break ;
201-
202- default :
203- break ;
204- }
205-
206- if (rearm ) {
207- mod_timer (& fpe_cfg -> verify_timer ,
208- jiffies + msecs_to_jiffies (fpe_cfg -> verify_time ));
209- }
210-
211- spin_unlock_irqrestore (& fpe_cfg -> lock , flags );
212- }
213-
214- static void stmmac_fpe_verify_timer_arm (struct stmmac_fpe_cfg * fpe_cfg )
215- {
216- if (fpe_cfg -> pmac_enabled && fpe_cfg -> tx_enabled &&
217- fpe_cfg -> verify_enabled &&
218- fpe_cfg -> status != ETHTOOL_MM_VERIFY_STATUS_FAILED &&
219- fpe_cfg -> status != ETHTOOL_MM_VERIFY_STATUS_SUCCEEDED ) {
220- timer_setup (& fpe_cfg -> verify_timer , stmmac_fpe_verify_timer , 0 );
221- mod_timer (& fpe_cfg -> verify_timer , jiffies );
222- }
223- }
224-
225168void stmmac_fpe_init (struct stmmac_priv * priv )
226169{
227- priv -> fpe_cfg .verify_retries = STMMAC_FPE_MM_MAX_VERIFY_RETRIES ;
228- priv -> fpe_cfg .verify_time = STMMAC_FPE_MM_MAX_VERIFY_TIME_MS ;
229- priv -> fpe_cfg .status = ETHTOOL_MM_VERIFY_STATUS_DISABLED ;
230- timer_setup (& priv -> fpe_cfg .verify_timer , stmmac_fpe_verify_timer , 0 );
231- spin_lock_init (& priv -> fpe_cfg .lock );
170+ ethtool_mmsv_init (& priv -> fpe_cfg .mmsv , priv -> dev ,
171+ & stmmac_mmsv_ops );
232172
233173 if ((!priv -> fpe_cfg .reg || !priv -> hw -> mac -> fpe_map_preemption_class ) &&
234174 priv -> dma_cap .fpesel )
235175 dev_info (priv -> device , "FPE is not supported by driver.\n" );
236176}
237177
238- void stmmac_fpe_apply (struct stmmac_priv * priv )
239- {
240- struct stmmac_fpe_cfg * fpe_cfg = & priv -> fpe_cfg ;
241-
242- /* If verification is disabled, configure FPE right away.
243- * Otherwise let the timer code do it.
244- */
245- if (!fpe_cfg -> verify_enabled ) {
246- stmmac_fpe_configure (priv , fpe_cfg -> tx_enabled ,
247- fpe_cfg -> pmac_enabled );
248- } else {
249- fpe_cfg -> status = ETHTOOL_MM_VERIFY_STATUS_INITIAL ;
250- fpe_cfg -> verify_retries = STMMAC_FPE_MM_MAX_VERIFY_RETRIES ;
251-
252- if (netif_running (priv -> dev ))
253- stmmac_fpe_verify_timer_arm (fpe_cfg );
254- }
255- }
256-
257- void stmmac_fpe_link_state_handle (struct stmmac_priv * priv , bool is_up )
258- {
259- struct stmmac_fpe_cfg * fpe_cfg = & priv -> fpe_cfg ;
260- unsigned long flags ;
261-
262- timer_shutdown_sync (& fpe_cfg -> verify_timer );
263-
264- spin_lock_irqsave (& fpe_cfg -> lock , flags );
265-
266- if (is_up && fpe_cfg -> pmac_enabled ) {
267- /* VERIFY process requires pmac enabled when NIC comes up */
268- stmmac_fpe_configure (priv , false, true);
269-
270- /* New link => maybe new partner => new verification process */
271- stmmac_fpe_apply (priv );
272- } else {
273- /* No link => turn off EFPE */
274- stmmac_fpe_configure (priv , false, false);
275- }
276-
277- spin_unlock_irqrestore (& fpe_cfg -> lock , flags );
278- }
279-
280178int stmmac_fpe_get_add_frag_size (struct stmmac_priv * priv )
281179{
282180 const struct stmmac_fpe_reg * reg = priv -> fpe_cfg .reg ;
0 commit comments