@@ -167,6 +167,24 @@ static bool enetc_skb_is_tcp(struct sk_buff *skb)
167
167
return skb -> csum_offset == offsetof(struct tcphdr , check );
168
168
}
169
169
170
+ /**
171
+ * enetc_unwind_tx_frame() - Unwind the DMA mappings of a multi-buffer Tx frame
172
+ * @tx_ring: Pointer to the Tx ring on which the buffer descriptors are located
173
+ * @count: Number of Tx buffer descriptors which need to be unmapped
174
+ * @i: Index of the last successfully mapped Tx buffer descriptor
175
+ */
176
+ static void enetc_unwind_tx_frame (struct enetc_bdr * tx_ring , int count , int i )
177
+ {
178
+ while (count -- ) {
179
+ struct enetc_tx_swbd * tx_swbd = & tx_ring -> tx_swbd [i ];
180
+
181
+ enetc_free_tx_frame (tx_ring , tx_swbd );
182
+ if (i == 0 )
183
+ i = tx_ring -> bd_count ;
184
+ i -- ;
185
+ }
186
+ }
187
+
170
188
static int enetc_map_tx_buffs (struct enetc_bdr * tx_ring , struct sk_buff * skb )
171
189
{
172
190
bool do_vlan , do_onestep_tstamp = false, do_twostep_tstamp = false;
@@ -279,9 +297,11 @@ static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb)
279
297
}
280
298
281
299
if (do_onestep_tstamp ) {
282
- u32 lo , hi , val ;
283
- u64 sec , nsec ;
300
+ __be32 new_sec_l , new_nsec ;
301
+ u32 lo , hi , nsec , val ;
302
+ __be16 new_sec_h ;
284
303
u8 * data ;
304
+ u64 sec ;
285
305
286
306
lo = enetc_rd_hot (hw , ENETC_SICTR0 );
287
307
hi = enetc_rd_hot (hw , ENETC_SICTR1 );
@@ -295,13 +315,38 @@ static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb)
295
315
/* Update originTimestamp field of Sync packet
296
316
* - 48 bits seconds field
297
317
* - 32 bits nanseconds field
318
+ *
319
+ * In addition, the UDP checksum needs to be updated
320
+ * by software after updating originTimestamp field,
321
+ * otherwise the hardware will calculate the wrong
322
+ * checksum when updating the correction field and
323
+ * update it to the packet.
298
324
*/
299
325
data = skb_mac_header (skb );
300
- * (__be16 * )(data + offset2 ) =
301
- htons ((sec >> 32 ) & 0xffff );
302
- * (__be32 * )(data + offset2 + 2 ) =
303
- htonl (sec & 0xffffffff );
304
- * (__be32 * )(data + offset2 + 6 ) = htonl (nsec );
326
+ new_sec_h = htons ((sec >> 32 ) & 0xffff );
327
+ new_sec_l = htonl (sec & 0xffffffff );
328
+ new_nsec = htonl (nsec );
329
+ if (udp ) {
330
+ struct udphdr * uh = udp_hdr (skb );
331
+ __be32 old_sec_l , old_nsec ;
332
+ __be16 old_sec_h ;
333
+
334
+ old_sec_h = * (__be16 * )(data + offset2 );
335
+ inet_proto_csum_replace2 (& uh -> check , skb , old_sec_h ,
336
+ new_sec_h , false);
337
+
338
+ old_sec_l = * (__be32 * )(data + offset2 + 2 );
339
+ inet_proto_csum_replace4 (& uh -> check , skb , old_sec_l ,
340
+ new_sec_l , false);
341
+
342
+ old_nsec = * (__be32 * )(data + offset2 + 6 );
343
+ inet_proto_csum_replace4 (& uh -> check , skb , old_nsec ,
344
+ new_nsec , false);
345
+ }
346
+
347
+ * (__be16 * )(data + offset2 ) = new_sec_h ;
348
+ * (__be32 * )(data + offset2 + 2 ) = new_sec_l ;
349
+ * (__be32 * )(data + offset2 + 6 ) = new_nsec ;
305
350
306
351
/* Configure single-step register */
307
352
val = ENETC_PM0_SINGLE_STEP_EN ;
@@ -372,25 +417,20 @@ static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb)
372
417
dma_err :
373
418
dev_err (tx_ring -> dev , "DMA map error" );
374
419
375
- do {
376
- tx_swbd = & tx_ring -> tx_swbd [i ];
377
- enetc_free_tx_frame (tx_ring , tx_swbd );
378
- if (i == 0 )
379
- i = tx_ring -> bd_count ;
380
- i -- ;
381
- } while (count -- );
420
+ enetc_unwind_tx_frame (tx_ring , count , i );
382
421
383
422
return 0 ;
384
423
}
385
424
386
- static void enetc_map_tx_tso_hdr (struct enetc_bdr * tx_ring , struct sk_buff * skb ,
387
- struct enetc_tx_swbd * tx_swbd ,
388
- union enetc_tx_bd * txbd , int * i , int hdr_len ,
389
- int data_len )
425
+ static int enetc_map_tx_tso_hdr (struct enetc_bdr * tx_ring , struct sk_buff * skb ,
426
+ struct enetc_tx_swbd * tx_swbd ,
427
+ union enetc_tx_bd * txbd , int * i , int hdr_len ,
428
+ int data_len )
390
429
{
391
430
union enetc_tx_bd txbd_tmp ;
392
431
u8 flags = 0 , e_flags = 0 ;
393
432
dma_addr_t addr ;
433
+ int count = 1 ;
394
434
395
435
enetc_clear_tx_bd (& txbd_tmp );
396
436
addr = tx_ring -> tso_headers_dma + * i * TSO_HEADER_SIZE ;
@@ -433,7 +473,10 @@ static void enetc_map_tx_tso_hdr(struct enetc_bdr *tx_ring, struct sk_buff *skb,
433
473
/* Write the BD */
434
474
txbd_tmp .ext .e_flags = e_flags ;
435
475
* txbd = txbd_tmp ;
476
+ count ++ ;
436
477
}
478
+
479
+ return count ;
437
480
}
438
481
439
482
static int enetc_map_tx_tso_data (struct enetc_bdr * tx_ring , struct sk_buff * skb ,
@@ -790,9 +833,9 @@ static int enetc_map_tx_tso_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb
790
833
791
834
/* compute the csum over the L4 header */
792
835
csum = enetc_tso_hdr_csum (& tso , skb , hdr , hdr_len , & pos );
793
- enetc_map_tx_tso_hdr (tx_ring , skb , tx_swbd , txbd , & i , hdr_len , data_len );
836
+ count += enetc_map_tx_tso_hdr (tx_ring , skb , tx_swbd , txbd ,
837
+ & i , hdr_len , data_len );
794
838
bd_data_num = 0 ;
795
- count ++ ;
796
839
797
840
while (data_len > 0 ) {
798
841
int size ;
@@ -816,8 +859,13 @@ static int enetc_map_tx_tso_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb
816
859
err = enetc_map_tx_tso_data (tx_ring , skb , tx_swbd , txbd ,
817
860
tso .data , size ,
818
861
size == data_len );
819
- if (err )
862
+ if (err ) {
863
+ if (i == 0 )
864
+ i = tx_ring -> bd_count ;
865
+ i -- ;
866
+
820
867
goto err_map_data ;
868
+ }
821
869
822
870
data_len -= size ;
823
871
count ++ ;
@@ -846,13 +894,7 @@ static int enetc_map_tx_tso_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb
846
894
dev_err (tx_ring -> dev , "DMA map error" );
847
895
848
896
err_chained_bd :
849
- do {
850
- tx_swbd = & tx_ring -> tx_swbd [i ];
851
- enetc_free_tx_frame (tx_ring , tx_swbd );
852
- if (i == 0 )
853
- i = tx_ring -> bd_count ;
854
- i -- ;
855
- } while (count -- );
897
+ enetc_unwind_tx_frame (tx_ring , count , i );
856
898
857
899
return 0 ;
858
900
}
@@ -1901,7 +1943,7 @@ static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring,
1901
1943
enetc_xdp_drop (rx_ring , orig_i , i );
1902
1944
tx_ring -> stats .xdp_tx_drops ++ ;
1903
1945
} else {
1904
- tx_ring -> stats .xdp_tx += xdp_tx_bd_cnt ;
1946
+ tx_ring -> stats .xdp_tx ++ ;
1905
1947
rx_ring -> xdp .xdp_tx_in_flight += xdp_tx_bd_cnt ;
1906
1948
xdp_tx_frm_cnt ++ ;
1907
1949
/* The XDP_TX enqueue was successful, so we
@@ -3228,6 +3270,9 @@ static int enetc_hwtstamp_set(struct net_device *ndev, struct ifreq *ifr)
3228
3270
new_offloads |= ENETC_F_TX_TSTAMP ;
3229
3271
break ;
3230
3272
case HWTSTAMP_TX_ONESTEP_SYNC :
3273
+ if (!enetc_si_is_pf (priv -> si ))
3274
+ return - EOPNOTSUPP ;
3275
+
3231
3276
new_offloads &= ~ENETC_F_TX_TSTAMP_MASK ;
3232
3277
new_offloads |= ENETC_F_TX_ONESTEP_SYNC_TSTAMP ;
3233
3278
break ;
0 commit comments