@@ -2179,10 +2179,11 @@ int efx_ef10_tx_tso_desc(struct efx_tx_queue *tx_queue, struct sk_buff *skb,
21792179 bool * data_mapped )
21802180{
21812181 struct efx_tx_buffer * buffer ;
2182+ u16 inner_ipv4_id = 0 ;
2183+ u16 outer_ipv4_id = 0 ;
21822184 struct tcphdr * tcp ;
21832185 struct iphdr * ip ;
2184-
2185- u16 ipv4_id ;
2186+ u16 ip_tot_len ;
21862187 u32 seqnum ;
21872188 u32 mss ;
21882189
@@ -2195,21 +2196,43 @@ int efx_ef10_tx_tso_desc(struct efx_tx_queue *tx_queue, struct sk_buff *skb,
21952196 return - EINVAL ;
21962197 }
21972198
2198- ip = ip_hdr (skb );
2199+ if (skb -> encapsulation ) {
2200+ if (!tx_queue -> tso_encap )
2201+ return - EINVAL ;
2202+ ip = ip_hdr (skb );
2203+ if (ip -> version == 4 )
2204+ outer_ipv4_id = ntohs (ip -> id );
2205+
2206+ ip = inner_ip_hdr (skb );
2207+ tcp = inner_tcp_hdr (skb );
2208+ } else {
2209+ ip = ip_hdr (skb );
2210+ tcp = tcp_hdr (skb );
2211+ }
2212+
2213+ /* 8000-series EF10 hardware requires that IP Total Length be
2214+ * greater than or equal to the value it will have in each segment
2215+ * (which is at most mss + 208 + TCP header length), but also less
2216+ * than (0x10000 - inner_network_header). Otherwise the TCP
2217+ * checksum calculation will be broken for encapsulated packets.
2218+ * We fill in ip->tot_len with 0xff30, which should satisfy the
2219+ * first requirement unless the MSS is ridiculously large (which
2220+ * should be impossible as the driver max MTU is 9216); it is
2221+ * guaranteed to satisfy the second as we only attempt TSO if
2222+ * inner_network_header <= 208.
2223+ */
2224+ ip_tot_len = - EFX_TSO2_MAX_HDRLEN ;
2225+ EFX_WARN_ON_ONCE_PARANOID (mss + EFX_TSO2_MAX_HDRLEN +
2226+ (tcp -> doff << 2u ) > ip_tot_len );
2227+
21992228 if (ip -> version == 4 ) {
2200- /* Modify IPv4 header if needed. */
2201- ip -> tot_len = 0 ;
2229+ ip -> tot_len = htons (ip_tot_len );
22022230 ip -> check = 0 ;
2203- ipv4_id = ntohs (ip -> id );
2231+ inner_ipv4_id = ntohs (ip -> id );
22042232 } else {
2205- /* Modify IPv6 header if needed. */
2206- struct ipv6hdr * ipv6 = ipv6_hdr (skb );
2207-
2208- ipv6 -> payload_len = 0 ;
2209- ipv4_id = 0 ;
2233+ ((struct ipv6hdr * )ip )-> payload_len = htons (ip_tot_len );
22102234 }
22112235
2212- tcp = tcp_hdr (skb );
22132236 seqnum = ntohl (tcp -> seq );
22142237
22152238 buffer = efx_tx_queue_get_insert_buffer (tx_queue );
@@ -2222,7 +2245,7 @@ int efx_ef10_tx_tso_desc(struct efx_tx_queue *tx_queue, struct sk_buff *skb,
22222245 ESF_DZ_TX_OPTION_TYPE , ESE_DZ_TX_OPTION_DESC_TSO ,
22232246 ESF_DZ_TX_TSO_OPTION_TYPE ,
22242247 ESE_DZ_TX_TSO_OPTION_DESC_FATSO2A ,
2225- ESF_DZ_TX_TSO_IP_ID , ipv4_id ,
2248+ ESF_DZ_TX_TSO_IP_ID , inner_ipv4_id ,
22262249 ESF_DZ_TX_TSO_TCP_SEQNO , seqnum
22272250 );
22282251 ++ tx_queue -> insert_count ;
@@ -2232,11 +2255,12 @@ int efx_ef10_tx_tso_desc(struct efx_tx_queue *tx_queue, struct sk_buff *skb,
22322255 buffer -> flags = EFX_TX_BUF_OPTION ;
22332256 buffer -> len = 0 ;
22342257 buffer -> unmap_len = 0 ;
2235- EFX_POPULATE_QWORD_4 (buffer -> option ,
2258+ EFX_POPULATE_QWORD_5 (buffer -> option ,
22362259 ESF_DZ_TX_DESC_IS_OPT , 1 ,
22372260 ESF_DZ_TX_OPTION_TYPE , ESE_DZ_TX_OPTION_DESC_TSO ,
22382261 ESF_DZ_TX_TSO_OPTION_TYPE ,
22392262 ESE_DZ_TX_TSO_OPTION_DESC_FATSO2B ,
2263+ ESF_DZ_TX_TSO_OUTER_IPID , outer_ipv4_id ,
22402264 ESF_DZ_TX_TSO_TCP_MSS , mss
22412265 );
22422266 ++ tx_queue -> insert_count ;
@@ -2322,6 +2346,9 @@ static void efx_ef10_tx_init(struct efx_tx_queue *tx_queue)
23222346 ESF_DZ_TX_TIMESTAMP , tx_queue -> timestamping );
23232347 tx_queue -> write_count = 1 ;
23242348
2349+ if (tx_queue -> tso_version == 2 && efx_has_cap (efx , TX_TSO_V2_ENCAP ))
2350+ tx_queue -> tso_encap = true;
2351+
23252352 wmb ();
23262353 efx_ef10_push_tx_desc (tx_queue , txd );
23272354
0 commit comments