Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
[platform/kernel/linux-starfive.git] / drivers / net / ethernet / mellanox / mlx5 / core / en_accel / ipsec_rxtx.c
1 /*
2  * Copyright (c) 2017 Mellanox Technologies. All rights reserved.
3  *
4  * This software is available to you under a choice of one of two
5  * licenses.  You may choose to be licensed under the terms of the GNU
6  * General Public License (GPL) Version 2, available from the file
7  * COPYING in the main directory of this source tree, or the
8  * OpenIB.org BSD license below:
9  *
10  *     Redistribution and use in source and binary forms, with or
11  *     without modification, are permitted provided that the following
12  *     conditions are met:
13  *
14  *      - Redistributions of source code must retain the above
15  *        copyright notice, this list of conditions and the following
16  *        disclaimer.
17  *
18  *      - Redistributions in binary form must reproduce the above
19  *        copyright notice, this list of conditions and the following
20  *        disclaimer in the documentation and/or other materials
21  *        provided with the distribution.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30  * SOFTWARE.
31  *
32  */
33
34 #include <crypto/aead.h>
35 #include <net/xfrm.h>
36 #include <net/esp.h>
37 #include "accel/ipsec_offload.h"
38 #include "en_accel/ipsec_rxtx.h"
39 #include "en_accel/ipsec.h"
40 #include "accel/accel.h"
41 #include "en.h"
42
43 enum {
44         MLX5E_IPSEC_RX_SYNDROME_DECRYPTED = 0x11,
45         MLX5E_IPSEC_RX_SYNDROME_AUTH_FAILED = 0x12,
46         MLX5E_IPSEC_RX_SYNDROME_BAD_PROTO = 0x17,
47 };
48
49 struct mlx5e_ipsec_rx_metadata {
50         unsigned char   nexthdr;
51         __be32          sa_handle;
52 } __packed;
53
54 enum {
55         MLX5E_IPSEC_TX_SYNDROME_OFFLOAD = 0x8,
56         MLX5E_IPSEC_TX_SYNDROME_OFFLOAD_WITH_LSO_TCP = 0x9,
57 };
58
59 struct mlx5e_ipsec_tx_metadata {
60         __be16 mss_inv;         /* 1/MSS in 16bit fixed point, only for LSO */
61         __be16 seq;             /* LSBs of the first TCP seq, only for LSO */
62         u8     esp_next_proto;  /* Next protocol of ESP */
63 } __packed;
64
65 struct mlx5e_ipsec_metadata {
66         unsigned char syndrome;
67         union {
68                 unsigned char raw[5];
69                 /* from FPGA to host, on successful decrypt */
70                 struct mlx5e_ipsec_rx_metadata rx;
71                 /* from host to FPGA */
72                 struct mlx5e_ipsec_tx_metadata tx;
73         } __packed content;
74         /* packet type ID field */
75         __be16 ethertype;
76 } __packed;
77
78 #define MAX_LSO_MSS 2048
79
80 /* Pre-calculated (Q0.16) fixed-point inverse 1/x function */
81 static __be16 mlx5e_ipsec_inverse_table[MAX_LSO_MSS];
82
83 static inline __be16 mlx5e_ipsec_mss_inv(struct sk_buff *skb)
84 {
85         return mlx5e_ipsec_inverse_table[skb_shinfo(skb)->gso_size];
86 }
87
88 static struct mlx5e_ipsec_metadata *mlx5e_ipsec_add_metadata(struct sk_buff *skb)
89 {
90         struct mlx5e_ipsec_metadata *mdata;
91         struct ethhdr *eth;
92
93         if (unlikely(skb_cow_head(skb, sizeof(*mdata))))
94                 return ERR_PTR(-ENOMEM);
95
96         eth = (struct ethhdr *)skb_push(skb, sizeof(*mdata));
97         skb->mac_header -= sizeof(*mdata);
98         mdata = (struct mlx5e_ipsec_metadata *)(eth + 1);
99
100         memmove(skb->data, skb->data + sizeof(*mdata),
101                 2 * ETH_ALEN);
102
103         eth->h_proto = cpu_to_be16(MLX5E_METADATA_ETHER_TYPE);
104
105         memset(mdata->content.raw, 0, sizeof(mdata->content.raw));
106         return mdata;
107 }
108
109 static int mlx5e_ipsec_remove_trailer(struct sk_buff *skb, struct xfrm_state *x)
110 {
111         unsigned int alen = crypto_aead_authsize(x->data);
112         struct ipv6hdr *ipv6hdr = ipv6_hdr(skb);
113         struct iphdr *ipv4hdr = ip_hdr(skb);
114         unsigned int trailer_len;
115         u8 plen;
116         int ret;
117
118         ret = skb_copy_bits(skb, skb->len - alen - 2, &plen, 1);
119         if (unlikely(ret))
120                 return ret;
121
122         trailer_len = alen + plen + 2;
123
124         pskb_trim(skb, skb->len - trailer_len);
125         if (skb->protocol == htons(ETH_P_IP)) {
126                 ipv4hdr->tot_len = htons(ntohs(ipv4hdr->tot_len) - trailer_len);
127                 ip_send_check(ipv4hdr);
128         } else {
129                 ipv6hdr->payload_len = htons(ntohs(ipv6hdr->payload_len) -
130                                              trailer_len);
131         }
132         return 0;
133 }
134
135 static void mlx5e_ipsec_set_swp(struct sk_buff *skb,
136                                 struct mlx5_wqe_eth_seg *eseg, u8 mode,
137                                 struct xfrm_offload *xo)
138 {
139         /* Tunnel Mode:
140          * SWP:      OutL3       InL3  InL4
141          * Pkt: MAC  IP     ESP  IP    L4
142          *
143          * Transport Mode:
144          * SWP:      OutL3       OutL4
145          * Pkt: MAC  IP     ESP  L4
146          *
147          * Tunnel(VXLAN TCP/UDP) over Transport Mode
148          * SWP:      OutL3                   InL3  InL4
149          * Pkt: MAC  IP     ESP  UDP  VXLAN  IP    L4
150          */
151
152         /* Shared settings */
153         eseg->swp_outer_l3_offset = skb_network_offset(skb) / 2;
154         if (skb->protocol == htons(ETH_P_IPV6))
155                 eseg->swp_flags |= MLX5_ETH_WQE_SWP_OUTER_L3_IPV6;
156
157         /* Tunnel mode */
158         if (mode == XFRM_MODE_TUNNEL) {
159                 eseg->swp_inner_l3_offset = skb_inner_network_offset(skb) / 2;
160                 if (xo->proto == IPPROTO_IPV6)
161                         eseg->swp_flags |= MLX5_ETH_WQE_SWP_INNER_L3_IPV6;
162
163                 switch (xo->inner_ipproto) {
164                 case IPPROTO_UDP:
165                         eseg->swp_flags |= MLX5_ETH_WQE_SWP_INNER_L4_UDP;
166                         fallthrough;
167                 case IPPROTO_TCP:
168                         /* IP | ESP | IP | [TCP | UDP] */
169                         eseg->swp_inner_l4_offset = skb_inner_transport_offset(skb) / 2;
170                         break;
171                 default:
172                         break;
173                 }
174                 return;
175         }
176
177         /* Transport mode */
178         if (mode != XFRM_MODE_TRANSPORT)
179                 return;
180
181         if (!xo->inner_ipproto) {
182                 switch (xo->proto) {
183                 case IPPROTO_UDP:
184                         eseg->swp_flags |= MLX5_ETH_WQE_SWP_OUTER_L4_UDP;
185                         fallthrough;
186                 case IPPROTO_TCP:
187                         /* IP | ESP | TCP */
188                         eseg->swp_outer_l4_offset = skb_inner_transport_offset(skb) / 2;
189                         break;
190                 default:
191                         break;
192                 }
193         } else {
194                 /* Tunnel(VXLAN TCP/UDP) over Transport Mode */
195                 switch (xo->inner_ipproto) {
196                 case IPPROTO_UDP:
197                         eseg->swp_flags |= MLX5_ETH_WQE_SWP_INNER_L4_UDP;
198                         fallthrough;
199                 case IPPROTO_TCP:
200                         eseg->swp_inner_l3_offset = skb_inner_network_offset(skb) / 2;
201                         eseg->swp_inner_l4_offset =
202                                 (skb->csum_start + skb->head - skb->data) / 2;
203                         if (inner_ip_hdr(skb)->version == 6)
204                                 eseg->swp_flags |= MLX5_ETH_WQE_SWP_INNER_L3_IPV6;
205                         break;
206                 default:
207                         break;
208                 }
209         }
210
211 }
212
213 void mlx5e_ipsec_set_iv_esn(struct sk_buff *skb, struct xfrm_state *x,
214                             struct xfrm_offload *xo)
215 {
216         struct xfrm_replay_state_esn *replay_esn = x->replay_esn;
217         __u32 oseq = replay_esn->oseq;
218         int iv_offset;
219         __be64 seqno;
220         u32 seq_hi;
221
222         if (unlikely(skb_is_gso(skb) && oseq < MLX5E_IPSEC_ESN_SCOPE_MID &&
223                      MLX5E_IPSEC_ESN_SCOPE_MID < (oseq - skb_shinfo(skb)->gso_segs))) {
224                 seq_hi = xo->seq.hi - 1;
225         } else {
226                 seq_hi = xo->seq.hi;
227         }
228
229         /* Place the SN in the IV field */
230         seqno = cpu_to_be64(xo->seq.low + ((u64)seq_hi << 32));
231         iv_offset = skb_transport_offset(skb) + sizeof(struct ip_esp_hdr);
232         skb_store_bits(skb, iv_offset, &seqno, 8);
233 }
234
235 void mlx5e_ipsec_set_iv(struct sk_buff *skb, struct xfrm_state *x,
236                         struct xfrm_offload *xo)
237 {
238         int iv_offset;
239         __be64 seqno;
240
241         /* Place the SN in the IV field */
242         seqno = cpu_to_be64(xo->seq.low + ((u64)xo->seq.hi << 32));
243         iv_offset = skb_transport_offset(skb) + sizeof(struct ip_esp_hdr);
244         skb_store_bits(skb, iv_offset, &seqno, 8);
245 }
246
247 static void mlx5e_ipsec_set_metadata(struct sk_buff *skb,
248                                      struct mlx5e_ipsec_metadata *mdata,
249                                      struct xfrm_offload *xo)
250 {
251         struct ip_esp_hdr *esph;
252         struct tcphdr *tcph;
253
254         if (skb_is_gso(skb)) {
255                 /* Add LSO metadata indication */
256                 esph = ip_esp_hdr(skb);
257                 tcph = inner_tcp_hdr(skb);
258                 netdev_dbg(skb->dev, "   Offloading GSO packet outer L3 %u; L4 %u; Inner L3 %u; L4 %u\n",
259                            skb->network_header,
260                            skb->transport_header,
261                            skb->inner_network_header,
262                            skb->inner_transport_header);
263                 netdev_dbg(skb->dev, "   Offloading GSO packet of len %u; mss %u; TCP sp %u dp %u seq 0x%x ESP seq 0x%x\n",
264                            skb->len, skb_shinfo(skb)->gso_size,
265                            ntohs(tcph->source), ntohs(tcph->dest),
266                            ntohl(tcph->seq), ntohl(esph->seq_no));
267                 mdata->syndrome = MLX5E_IPSEC_TX_SYNDROME_OFFLOAD_WITH_LSO_TCP;
268                 mdata->content.tx.mss_inv = mlx5e_ipsec_mss_inv(skb);
269                 mdata->content.tx.seq = htons(ntohl(tcph->seq) & 0xFFFF);
270         } else {
271                 mdata->syndrome = MLX5E_IPSEC_TX_SYNDROME_OFFLOAD;
272         }
273         mdata->content.tx.esp_next_proto = xo->proto;
274
275         netdev_dbg(skb->dev, "   TX metadata syndrome %u proto %u mss_inv %04x seq %04x\n",
276                    mdata->syndrome, mdata->content.tx.esp_next_proto,
277                    ntohs(mdata->content.tx.mss_inv),
278                    ntohs(mdata->content.tx.seq));
279 }
280
281 void mlx5e_ipsec_handle_tx_wqe(struct mlx5e_tx_wqe *wqe,
282                                struct mlx5e_accel_tx_ipsec_state *ipsec_st,
283                                struct mlx5_wqe_inline_seg *inlseg)
284 {
285         inlseg->byte_count = cpu_to_be32(ipsec_st->tailen | MLX5_INLINE_SEG);
286         esp_output_fill_trailer((u8 *)inlseg->data, 0, ipsec_st->plen, ipsec_st->xo->proto);
287 }
288
289 static int mlx5e_ipsec_set_state(struct mlx5e_priv *priv,
290                                  struct sk_buff *skb,
291                                  struct xfrm_state *x,
292                                  struct xfrm_offload *xo,
293                                  struct mlx5e_accel_tx_ipsec_state *ipsec_st)
294 {
295         unsigned int blksize, clen, alen, plen;
296         struct crypto_aead *aead;
297         unsigned int tailen;
298
299         ipsec_st->x = x;
300         ipsec_st->xo = xo;
301         if (mlx5_is_ipsec_device(priv->mdev)) {
302                 aead = x->data;
303                 alen = crypto_aead_authsize(aead);
304                 blksize = ALIGN(crypto_aead_blocksize(aead), 4);
305                 clen = ALIGN(skb->len + 2, blksize);
306                 plen = max_t(u32, clen - skb->len, 4);
307                 tailen = plen + alen;
308                 ipsec_st->plen = plen;
309                 ipsec_st->tailen = tailen;
310         }
311
312         return 0;
313 }
314
315 void mlx5e_ipsec_tx_build_eseg(struct mlx5e_priv *priv, struct sk_buff *skb,
316                                struct mlx5_wqe_eth_seg *eseg)
317 {
318         struct xfrm_offload *xo = xfrm_offload(skb);
319         struct xfrm_encap_tmpl  *encap;
320         struct xfrm_state *x;
321         struct sec_path *sp;
322         u8 l3_proto;
323
324         sp = skb_sec_path(skb);
325         if (unlikely(sp->len != 1))
326                 return;
327
328         x = xfrm_input_state(skb);
329         if (unlikely(!x))
330                 return;
331
332         if (unlikely(!x->xso.offload_handle ||
333                      (skb->protocol != htons(ETH_P_IP) &&
334                       skb->protocol != htons(ETH_P_IPV6))))
335                 return;
336
337         mlx5e_ipsec_set_swp(skb, eseg, x->props.mode, xo);
338
339         l3_proto = (x->props.family == AF_INET) ?
340                    ((struct iphdr *)skb_network_header(skb))->protocol :
341                    ((struct ipv6hdr *)skb_network_header(skb))->nexthdr;
342
343         if (mlx5_is_ipsec_device(priv->mdev)) {
344                 eseg->flow_table_metadata |= cpu_to_be32(MLX5_ETH_WQE_FT_META_IPSEC);
345                 eseg->trailer |= cpu_to_be32(MLX5_ETH_WQE_INSERT_TRAILER);
346                 encap = x->encap;
347                 if (!encap) {
348                         eseg->trailer |= (l3_proto == IPPROTO_ESP) ?
349                                 cpu_to_be32(MLX5_ETH_WQE_TRAILER_HDR_OUTER_IP_ASSOC) :
350                                 cpu_to_be32(MLX5_ETH_WQE_TRAILER_HDR_OUTER_L4_ASSOC);
351                 } else if (encap->encap_type == UDP_ENCAP_ESPINUDP) {
352                         eseg->trailer |= (l3_proto == IPPROTO_ESP) ?
353                                 cpu_to_be32(MLX5_ETH_WQE_TRAILER_HDR_INNER_IP_ASSOC) :
354                                 cpu_to_be32(MLX5_ETH_WQE_TRAILER_HDR_INNER_L4_ASSOC);
355                 }
356         }
357 }
358
359 bool mlx5e_ipsec_handle_tx_skb(struct net_device *netdev,
360                                struct sk_buff *skb,
361                                struct mlx5e_accel_tx_ipsec_state *ipsec_st)
362 {
363         struct mlx5e_priv *priv = netdev_priv(netdev);
364         struct xfrm_offload *xo = xfrm_offload(skb);
365         struct mlx5e_ipsec_sa_entry *sa_entry;
366         struct mlx5e_ipsec_metadata *mdata;
367         struct xfrm_state *x;
368         struct sec_path *sp;
369
370         sp = skb_sec_path(skb);
371         if (unlikely(sp->len != 1)) {
372                 atomic64_inc(&priv->ipsec->sw_stats.ipsec_tx_drop_bundle);
373                 goto drop;
374         }
375
376         x = xfrm_input_state(skb);
377         if (unlikely(!x)) {
378                 atomic64_inc(&priv->ipsec->sw_stats.ipsec_tx_drop_no_state);
379                 goto drop;
380         }
381
382         if (unlikely(!x->xso.offload_handle ||
383                      (skb->protocol != htons(ETH_P_IP) &&
384                       skb->protocol != htons(ETH_P_IPV6)))) {
385                 atomic64_inc(&priv->ipsec->sw_stats.ipsec_tx_drop_not_ip);
386                 goto drop;
387         }
388
389         if (!skb_is_gso(skb))
390                 if (unlikely(mlx5e_ipsec_remove_trailer(skb, x))) {
391                         atomic64_inc(&priv->ipsec->sw_stats.ipsec_tx_drop_trailer);
392                         goto drop;
393                 }
394
395         if (MLX5_CAP_GEN(priv->mdev, fpga)) {
396                 mdata = mlx5e_ipsec_add_metadata(skb);
397                 if (IS_ERR(mdata)) {
398                         atomic64_inc(&priv->ipsec->sw_stats.ipsec_tx_drop_metadata);
399                         goto drop;
400                 }
401         }
402
403         sa_entry = (struct mlx5e_ipsec_sa_entry *)x->xso.offload_handle;
404         sa_entry->set_iv_op(skb, x, xo);
405         if (MLX5_CAP_GEN(priv->mdev, fpga))
406                 mlx5e_ipsec_set_metadata(skb, mdata, xo);
407
408         mlx5e_ipsec_set_state(priv, skb, x, xo, ipsec_st);
409
410         return true;
411
412 drop:
413         kfree_skb(skb);
414         return false;
415 }
416
417 static inline struct xfrm_state *
418 mlx5e_ipsec_build_sp(struct net_device *netdev, struct sk_buff *skb,
419                      struct mlx5e_ipsec_metadata *mdata)
420 {
421         struct mlx5e_priv *priv = netdev_priv(netdev);
422         struct xfrm_offload *xo;
423         struct xfrm_state *xs;
424         struct sec_path *sp;
425         u32 sa_handle;
426
427         sp = secpath_set(skb);
428         if (unlikely(!sp)) {
429                 atomic64_inc(&priv->ipsec->sw_stats.ipsec_rx_drop_sp_alloc);
430                 return NULL;
431         }
432
433         sa_handle = be32_to_cpu(mdata->content.rx.sa_handle);
434         xs = mlx5e_ipsec_sadb_rx_lookup(priv->ipsec, sa_handle);
435         if (unlikely(!xs)) {
436                 atomic64_inc(&priv->ipsec->sw_stats.ipsec_rx_drop_sadb_miss);
437                 return NULL;
438         }
439
440         sp = skb_sec_path(skb);
441         sp->xvec[sp->len++] = xs;
442         sp->olen++;
443
444         xo = xfrm_offload(skb);
445         xo->flags = CRYPTO_DONE;
446         switch (mdata->syndrome) {
447         case MLX5E_IPSEC_RX_SYNDROME_DECRYPTED:
448                 xo->status = CRYPTO_SUCCESS;
449                 if (likely(priv->ipsec->no_trailer)) {
450                         xo->flags |= XFRM_ESP_NO_TRAILER;
451                         xo->proto = mdata->content.rx.nexthdr;
452                 }
453                 break;
454         case MLX5E_IPSEC_RX_SYNDROME_AUTH_FAILED:
455                 xo->status = CRYPTO_TUNNEL_ESP_AUTH_FAILED;
456                 break;
457         case MLX5E_IPSEC_RX_SYNDROME_BAD_PROTO:
458                 xo->status = CRYPTO_INVALID_PROTOCOL;
459                 break;
460         default:
461                 atomic64_inc(&priv->ipsec->sw_stats.ipsec_rx_drop_syndrome);
462                 return NULL;
463         }
464         return xs;
465 }
466
467 struct sk_buff *mlx5e_ipsec_handle_rx_skb(struct net_device *netdev,
468                                           struct sk_buff *skb, u32 *cqe_bcnt)
469 {
470         struct mlx5e_ipsec_metadata *mdata;
471         struct xfrm_state *xs;
472
473         if (!is_metadata_hdr_valid(skb))
474                 return skb;
475
476         /* Use the metadata */
477         mdata = (struct mlx5e_ipsec_metadata *)(skb->data + ETH_HLEN);
478         xs = mlx5e_ipsec_build_sp(netdev, skb, mdata);
479         if (unlikely(!xs)) {
480                 kfree_skb(skb);
481                 return NULL;
482         }
483
484         remove_metadata_hdr(skb);
485         *cqe_bcnt -= MLX5E_METADATA_ETHER_LEN;
486
487         return skb;
488 }
489
490 enum {
491         MLX5E_IPSEC_OFFLOAD_RX_SYNDROME_DECRYPTED,
492         MLX5E_IPSEC_OFFLOAD_RX_SYNDROME_AUTH_FAILED,
493         MLX5E_IPSEC_OFFLOAD_RX_SYNDROME_BAD_TRAILER,
494 };
495
496 void mlx5e_ipsec_offload_handle_rx_skb(struct net_device *netdev,
497                                        struct sk_buff *skb,
498                                        struct mlx5_cqe64 *cqe)
499 {
500         u32 ipsec_meta_data = be32_to_cpu(cqe->ft_metadata);
501         struct mlx5e_priv *priv;
502         struct xfrm_offload *xo;
503         struct xfrm_state *xs;
504         struct sec_path *sp;
505         u32  sa_handle;
506
507         sa_handle = MLX5_IPSEC_METADATA_HANDLE(ipsec_meta_data);
508         priv = netdev_priv(netdev);
509         sp = secpath_set(skb);
510         if (unlikely(!sp)) {
511                 atomic64_inc(&priv->ipsec->sw_stats.ipsec_rx_drop_sp_alloc);
512                 return;
513         }
514
515         xs = mlx5e_ipsec_sadb_rx_lookup(priv->ipsec, sa_handle);
516         if (unlikely(!xs)) {
517                 atomic64_inc(&priv->ipsec->sw_stats.ipsec_rx_drop_sadb_miss);
518                 return;
519         }
520
521         sp = skb_sec_path(skb);
522         sp->xvec[sp->len++] = xs;
523         sp->olen++;
524
525         xo = xfrm_offload(skb);
526         xo->flags = CRYPTO_DONE;
527
528         switch (MLX5_IPSEC_METADATA_SYNDROM(ipsec_meta_data)) {
529         case MLX5E_IPSEC_OFFLOAD_RX_SYNDROME_DECRYPTED:
530                 xo->status = CRYPTO_SUCCESS;
531                 if (WARN_ON_ONCE(priv->ipsec->no_trailer))
532                         xo->flags |= XFRM_ESP_NO_TRAILER;
533                 break;
534         case MLX5E_IPSEC_OFFLOAD_RX_SYNDROME_AUTH_FAILED:
535                 xo->status = CRYPTO_TUNNEL_ESP_AUTH_FAILED;
536                 break;
537         case MLX5E_IPSEC_OFFLOAD_RX_SYNDROME_BAD_TRAILER:
538                 xo->status = CRYPTO_INVALID_PACKET_SYNTAX;
539                 break;
540         default:
541                 atomic64_inc(&priv->ipsec->sw_stats.ipsec_rx_drop_syndrome);
542         }
543 }
544
545 void mlx5e_ipsec_build_inverse_table(void)
546 {
547         u16 mss_inv;
548         u32 mss;
549
550         /* Calculate 1/x inverse table for use in GSO data path.
551          * Using this table, we provide the IPSec accelerator with the value of
552          * 1/gso_size so that it can infer the position of each segment inside
553          * the GSO, and increment the ESP sequence number, and generate the IV.
554          * The HW needs this value in Q0.16 fixed-point number format
555          */
556         mlx5e_ipsec_inverse_table[1] = htons(0xFFFF);
557         for (mss = 2; mss < MAX_LSO_MSS; mss++) {
558                 mss_inv = div_u64(1ULL << 32, mss) >> 16;
559                 mlx5e_ipsec_inverse_table[mss] = htons(mss_inv);
560         }
561 }