@@ -167,6 +167,24 @@ static bool enetc_skb_is_tcp(struct sk_buff *skb)
167167 return skb -> csum_offset == offsetof(struct tcphdr , check );
168168}
169169
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+
170188static int enetc_map_tx_buffs (struct enetc_bdr * tx_ring , struct sk_buff * skb )
171189{
172190 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)
279297 }
280298
281299 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 ;
284303 u8 * data ;
304+ u64 sec ;
285305
286306 lo = enetc_rd_hot (hw , ENETC_SICTR0 );
287307 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)
295315 /* Update originTimestamp field of Sync packet
296316 * - 48 bits seconds field
297317 * - 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.
298324 */
299325 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 ;
305350
306351 /* Configure single-step register */
307352 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)
372417dma_err :
373418 dev_err (tx_ring -> dev , "DMA map error" );
374419
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 );
382421
383422 return 0 ;
384423}
385424
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 )
390429{
391430 union enetc_tx_bd txbd_tmp ;
392431 u8 flags = 0 , e_flags = 0 ;
393432 dma_addr_t addr ;
433+ int count = 1 ;
394434
395435 enetc_clear_tx_bd (& txbd_tmp );
396436 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,
433473 /* Write the BD */
434474 txbd_tmp .ext .e_flags = e_flags ;
435475 * txbd = txbd_tmp ;
476+ count ++ ;
436477 }
478+
479+ return count ;
437480}
438481
439482static 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
790833
791834 /* compute the csum over the L4 header */
792835 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 );
794838 bd_data_num = 0 ;
795- count ++ ;
796839
797840 while (data_len > 0 ) {
798841 int size ;
@@ -816,8 +859,13 @@ static int enetc_map_tx_tso_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb
816859 err = enetc_map_tx_tso_data (tx_ring , skb , tx_swbd , txbd ,
817860 tso .data , size ,
818861 size == data_len );
819- if (err )
862+ if (err ) {
863+ if (i == 0 )
864+ i = tx_ring -> bd_count ;
865+ i -- ;
866+
820867 goto err_map_data ;
868+ }
821869
822870 data_len -= size ;
823871 count ++ ;
@@ -846,13 +894,7 @@ static int enetc_map_tx_tso_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb
846894 dev_err (tx_ring -> dev , "DMA map error" );
847895
848896err_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 );
856898
857899 return 0 ;
858900}
@@ -1901,7 +1943,7 @@ static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring,
19011943 enetc_xdp_drop (rx_ring , orig_i , i );
19021944 tx_ring -> stats .xdp_tx_drops ++ ;
19031945 } else {
1904- tx_ring -> stats .xdp_tx += xdp_tx_bd_cnt ;
1946+ tx_ring -> stats .xdp_tx ++ ;
19051947 rx_ring -> xdp .xdp_tx_in_flight += xdp_tx_bd_cnt ;
19061948 xdp_tx_frm_cnt ++ ;
19071949 /* The XDP_TX enqueue was successful, so we
@@ -3228,6 +3270,9 @@ static int enetc_hwtstamp_set(struct net_device *ndev, struct ifreq *ifr)
32283270 new_offloads |= ENETC_F_TX_TSTAMP ;
32293271 break ;
32303272 case HWTSTAMP_TX_ONESTEP_SYNC :
3273+ if (!enetc_si_is_pf (priv -> si ))
3274+ return - EOPNOTSUPP ;
3275+
32313276 new_offloads &= ~ENETC_F_TX_TSTAMP_MASK ;
32323277 new_offloads |= ENETC_F_TX_ONESTEP_SYNC_TSTAMP ;
32333278 break ;
0 commit comments