FILE
en_accel.h
File preview with syntax highlighting.
linux-6.19.14/drivers/net/ethernet/mellanox/mlx5/core/en_accel/en_accel.h
1/* 2 * Copyright (c) 2018 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#ifndef __MLX5E_EN_ACCEL_H__ 35#define __MLX5E_EN_ACCEL_H__ 36 37#include <linux/skbuff.h> 38#include <linux/netdevice.h> 39#include "en_accel/ipsec_rxtx.h" 40#include "en_accel/ktls.h" 41#include "en_accel/ktls_txrx.h" 42#include <en_accel/macsec.h> 43#include "en.h" 44#include "en/txrx.h" 45#include "en_accel/psp.h" 46#include "en_accel/psp_rxtx.h" 47 48#if IS_ENABLED(CONFIG_GENEVE) 49#include <net/geneve.h> 50 51static inline bool mlx5_geneve_tx_allowed(struct mlx5_core_dev *mdev) 52{ 53 return mlx5_tx_swp_supported(mdev); 54} 55 56static inline void 57mlx5e_tx_tunnel_accel(struct sk_buff *skb, struct mlx5_wqe_eth_seg *eseg, u16 ihs) 58{ 59 struct mlx5e_swp_spec swp_spec = {}; 60 unsigned int offset = 0; 61 __be16 l3_proto; 62 u8 l4_proto; 63 64 l3_proto = vlan_get_protocol(skb); 65 switch (l3_proto) { 66 case htons(ETH_P_IP): 67 l4_proto = ip_hdr(skb)->protocol; 68 break; 69 case htons(ETH_P_IPV6): 70 l4_proto = ipv6_find_hdr(skb, &offset, -1, NULL, NULL); 71 break; 72 default: 73 return; 74 } 75 76 if (l4_proto != IPPROTO_UDP || 77 udp_hdr(skb)->dest != cpu_to_be16(GENEVE_UDP_PORT)) 78 return; 79 swp_spec.l3_proto = l3_proto; 80 swp_spec.l4_proto = l4_proto; 81 swp_spec.is_tun = true; 82 if (inner_ip_hdr(skb)->version == 6) { 83 swp_spec.tun_l3_proto = htons(ETH_P_IPV6); 84 swp_spec.tun_l4_proto = inner_ipv6_hdr(skb)->nexthdr; 85 } else { 86 swp_spec.tun_l3_proto = htons(ETH_P_IP); 87 swp_spec.tun_l4_proto = inner_ip_hdr(skb)->protocol; 88 } 89 90 mlx5e_set_eseg_swp(skb, eseg, &swp_spec); 91 if (skb_vlan_tag_present(skb) && ihs) 92 mlx5e_eseg_swp_offsets_add_vlan(eseg); 93} 94 95#else 96static inline bool mlx5_geneve_tx_allowed(struct mlx5_core_dev *mdev) 97{ 98 return false; 99} 100 101#endif /* CONFIG_GENEVE */ 102 103static inline void 104mlx5e_udp_gso_handle_tx_skb(struct sk_buff *skb) 105{ 106 int payload_len = skb_shinfo(skb)->gso_size + sizeof(struct udphdr); 107 struct udphdr *udphdr; 108 109 if (skb->encapsulation) 110 udphdr = (struct udphdr *)skb_inner_transport_header(skb); 111 else 112 udphdr = udp_hdr(skb); 113 114 udphdr->len = htons(payload_len); 115} 116 117struct mlx5e_accel_tx_state { 118#ifdef CONFIG_MLX5_EN_TLS 119 struct mlx5e_accel_tx_tls_state tls; 120#endif 121#ifdef CONFIG_MLX5_EN_IPSEC 122 struct mlx5e_accel_tx_ipsec_state ipsec; 123#endif 124#ifdef CONFIG_MLX5_EN_PSP 125 struct mlx5e_accel_tx_psp_state psp_st; 126#endif 127}; 128 129static inline bool mlx5e_accel_tx_begin(struct net_device *dev, 130 struct mlx5e_txqsq *sq, 131 struct sk_buff *skb, 132 struct mlx5e_accel_tx_state *state) 133{ 134 if (skb_is_gso(skb) && skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4) 135 mlx5e_udp_gso_handle_tx_skb(skb); 136 137#ifdef CONFIG_MLX5_EN_TLS 138 /* May send WQEs. */ 139 if (tls_is_skb_tx_device_offloaded(skb)) 140 if (unlikely(!mlx5e_ktls_handle_tx_skb(dev, sq, skb, 141 &state->tls))) 142 return false; 143#endif 144 145#ifdef CONFIG_MLX5_EN_PSP 146 if (mlx5e_psp_is_offload(skb, dev)) { 147 if (unlikely(!mlx5e_psp_handle_tx_skb(dev, skb, &state->psp_st))) 148 return false; 149 } 150#endif 151 152#ifdef CONFIG_MLX5_EN_IPSEC 153 if (test_bit(MLX5E_SQ_STATE_IPSEC, &sq->state) && xfrm_offload(skb)) { 154 if (unlikely(!mlx5e_ipsec_handle_tx_skb(dev, skb, &state->ipsec))) 155 return false; 156 } 157#endif 158 159#ifdef CONFIG_MLX5_MACSEC 160 if (unlikely(mlx5e_macsec_skb_is_offload(skb))) { 161 struct mlx5e_priv *priv = netdev_priv(dev); 162 163 if (unlikely(!mlx5e_macsec_handle_tx_skb(priv->macsec, skb))) 164 return false; 165 } 166#endif 167 168 return true; 169} 170 171static inline unsigned int mlx5e_accel_tx_ids_len(struct mlx5e_txqsq *sq, 172 struct sk_buff *skb, 173 struct mlx5e_accel_tx_state *state) 174{ 175#ifdef CONFIG_MLX5_EN_PSP 176 if (mlx5e_psp_is_offload_state(&state->psp_st)) 177 return mlx5e_psp_tx_ids_len(&state->psp_st); 178#endif 179 180#ifdef CONFIG_MLX5_EN_IPSEC 181 if (test_bit(MLX5E_SQ_STATE_IPSEC, &sq->state)) 182 return mlx5e_ipsec_tx_ids_len(&state->ipsec); 183#endif 184 185 return 0; 186} 187 188/* Part of the eseg touched by TX offloads */ 189#define MLX5E_ACCEL_ESEG_LEN offsetof(struct mlx5_wqe_eth_seg, mss) 190 191static inline void mlx5e_accel_tx_eseg(struct mlx5e_priv *priv, 192 struct sk_buff *skb, 193 struct mlx5e_accel_tx_state *accel, 194 struct mlx5_wqe_eth_seg *eseg, u16 ihs) 195{ 196#ifdef CONFIG_MLX5_EN_PSP 197 if (mlx5e_psp_is_offload_state(&accel->psp_st)) 198 mlx5e_psp_tx_build_eseg(priv, skb, &accel->psp_st, eseg); 199#endif 200 201#ifdef CONFIG_MLX5_EN_IPSEC 202 if (xfrm_offload(skb)) 203 mlx5e_ipsec_tx_build_eseg(priv, skb, eseg); 204#endif 205 206#ifdef CONFIG_MLX5_MACSEC 207 if (unlikely(mlx5e_macsec_skb_is_offload(skb))) 208 mlx5e_macsec_tx_build_eseg(priv->macsec, skb, eseg); 209#endif 210 211#if IS_ENABLED(CONFIG_GENEVE) 212 if (skb->encapsulation && skb->ip_summed == CHECKSUM_PARTIAL) 213 mlx5e_tx_tunnel_accel(skb, eseg, ihs); 214#endif 215} 216 217static inline void mlx5e_accel_tx_finish(struct mlx5e_txqsq *sq, 218 struct mlx5e_tx_wqe *wqe, 219 struct mlx5e_accel_tx_state *state, 220 struct mlx5_wqe_inline_seg *inlseg) 221{ 222#ifdef CONFIG_MLX5_EN_TLS 223 mlx5e_ktls_handle_tx_wqe(&wqe->ctrl, &state->tls); 224#endif 225 226#ifdef CONFIG_MLX5_EN_PSP 227 if (mlx5e_psp_is_offload_state(&state->psp_st)) 228 mlx5e_psp_handle_tx_wqe(wqe, &state->psp_st, inlseg); 229#endif 230 231#ifdef CONFIG_MLX5_EN_IPSEC 232 if (test_bit(MLX5E_SQ_STATE_IPSEC, &sq->state) && 233 state->ipsec.xo && state->ipsec.tailen) 234 mlx5e_ipsec_handle_tx_wqe(wqe, &state->ipsec, inlseg); 235#endif 236} 237 238static inline int mlx5e_accel_init_rx(struct mlx5e_priv *priv) 239{ 240 int err; 241 242 err = mlx5_accel_psp_fs_init_rx_tables(priv); 243 if (err) 244 goto out; 245 246 err = mlx5e_ktls_init_rx(priv); 247 if (err) 248 mlx5_accel_psp_fs_cleanup_rx_tables(priv); 249 250out: 251 return err; 252} 253 254static inline void mlx5e_accel_cleanup_rx(struct mlx5e_priv *priv) 255{ 256 mlx5e_ktls_cleanup_rx(priv); 257 mlx5_accel_psp_fs_cleanup_rx_tables(priv); 258} 259 260static inline int mlx5e_accel_init_tx(struct mlx5e_priv *priv) 261{ 262 int err; 263 264 err = mlx5_accel_psp_fs_init_tx_tables(priv); 265 if (err) 266 return err; 267 268 return mlx5e_ktls_init_tx(priv); 269} 270 271static inline void mlx5e_accel_cleanup_tx(struct mlx5e_priv *priv) 272{ 273 mlx5e_ktls_cleanup_tx(priv); 274 mlx5_accel_psp_fs_cleanup_tx_tables(priv); 275} 276#endif /* __MLX5E_EN_ACCEL_H__ */
~/
Read-only file preview.