1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB 2 // Copyright (c) 2019 Mellanox Technologies. 3 4 #include "en.h" 5 #include "lib/mlx5.h" 6 #include "en_accel/ktls.h" 7 #include "en_accel/ktls_utils.h" 8 #include "en_accel/fs_tcp.h" 9 10 int mlx5_ktls_create_key(struct mlx5_core_dev *mdev, 11 struct tls_crypto_info *crypto_info, 12 u32 *p_key_id) 13 { 14 u32 sz_bytes; 15 void *key; 16 17 switch (crypto_info->cipher_type) { 18 case TLS_CIPHER_AES_GCM_128: { 19 struct tls12_crypto_info_aes_gcm_128 *info = 20 (struct tls12_crypto_info_aes_gcm_128 *)crypto_info; 21 22 key = info->key; 23 sz_bytes = sizeof(info->key); 24 break; 25 } 26 case TLS_CIPHER_AES_GCM_256: { 27 struct tls12_crypto_info_aes_gcm_256 *info = 28 (struct tls12_crypto_info_aes_gcm_256 *)crypto_info; 29 30 key = info->key; 31 sz_bytes = sizeof(info->key); 32 break; 33 } 34 default: 35 return -EINVAL; 36 } 37 38 return mlx5_create_encryption_key(mdev, key, sz_bytes, 39 MLX5_ACCEL_OBJ_TLS_KEY, 40 p_key_id); 41 } 42 43 void mlx5_ktls_destroy_key(struct mlx5_core_dev *mdev, u32 key_id) 44 { 45 mlx5_destroy_encryption_key(mdev, key_id); 46 } 47 48 static int mlx5e_ktls_add(struct net_device *netdev, struct sock *sk, 49 enum tls_offload_ctx_dir direction, 50 struct tls_crypto_info *crypto_info, 51 u32 start_offload_tcp_sn) 52 { 53 struct mlx5e_priv *priv = netdev_priv(netdev); 54 struct mlx5_core_dev *mdev = priv->mdev; 55 int err; 56 57 if (!mlx5e_ktls_type_check(mdev, crypto_info)) 58 return -EOPNOTSUPP; 59 60 if (direction == TLS_OFFLOAD_CTX_DIR_TX) 61 err = mlx5e_ktls_add_tx(netdev, sk, crypto_info, start_offload_tcp_sn); 62 else 63 err = mlx5e_ktls_add_rx(netdev, sk, crypto_info, start_offload_tcp_sn); 64 65 return err; 66 } 67 68 static void mlx5e_ktls_del(struct net_device *netdev, 69 struct tls_context *tls_ctx, 70 enum tls_offload_ctx_dir direction) 71 { 72 if (direction == TLS_OFFLOAD_CTX_DIR_TX) 73 mlx5e_ktls_del_tx(netdev, tls_ctx); 74 else 75 mlx5e_ktls_del_rx(netdev, tls_ctx); 76 } 77 78 static int mlx5e_ktls_resync(struct net_device *netdev, 79 struct sock *sk, u32 seq, u8 *rcd_sn, 80 enum tls_offload_ctx_dir direction) 81 { 82 if (unlikely(direction != TLS_OFFLOAD_CTX_DIR_RX)) 83 return -EOPNOTSUPP; 84 85 mlx5e_ktls_rx_resync(netdev, sk, seq, rcd_sn); 86 return 0; 87 } 88 89 static const struct tlsdev_ops mlx5e_ktls_ops = { 90 .tls_dev_add = mlx5e_ktls_add, 91 .tls_dev_del = mlx5e_ktls_del, 92 .tls_dev_resync = mlx5e_ktls_resync, 93 }; 94 95 void mlx5e_ktls_build_netdev(struct mlx5e_priv *priv) 96 { 97 struct net_device *netdev = priv->netdev; 98 struct mlx5_core_dev *mdev = priv->mdev; 99 100 if (!mlx5e_is_ktls_tx(mdev) && !mlx5e_is_ktls_rx(mdev)) 101 return; 102 103 if (mlx5e_is_ktls_tx(mdev)) { 104 netdev->hw_features |= NETIF_F_HW_TLS_TX; 105 netdev->features |= NETIF_F_HW_TLS_TX; 106 } 107 108 if (mlx5e_is_ktls_rx(mdev)) 109 netdev->hw_features |= NETIF_F_HW_TLS_RX; 110 111 netdev->tlsdev_ops = &mlx5e_ktls_ops; 112 } 113 114 int mlx5e_ktls_set_feature_rx(struct net_device *netdev, bool enable) 115 { 116 struct mlx5e_priv *priv = netdev_priv(netdev); 117 int err = 0; 118 119 mutex_lock(&priv->state_lock); 120 if (enable) 121 err = mlx5e_accel_fs_tcp_create(priv); 122 else 123 mlx5e_accel_fs_tcp_destroy(priv); 124 mutex_unlock(&priv->state_lock); 125 126 return err; 127 } 128 129 int mlx5e_ktls_init_rx(struct mlx5e_priv *priv) 130 { 131 int err; 132 133 if (!mlx5e_is_ktls_rx(priv->mdev)) 134 return 0; 135 136 priv->tls->rx_wq = create_singlethread_workqueue("mlx5e_tls_rx"); 137 if (!priv->tls->rx_wq) 138 return -ENOMEM; 139 140 if (priv->netdev->features & NETIF_F_HW_TLS_RX) { 141 err = mlx5e_accel_fs_tcp_create(priv); 142 if (err) { 143 destroy_workqueue(priv->tls->rx_wq); 144 return err; 145 } 146 } 147 148 return 0; 149 } 150 151 void mlx5e_ktls_cleanup_rx(struct mlx5e_priv *priv) 152 { 153 if (!mlx5e_is_ktls_rx(priv->mdev)) 154 return; 155 156 if (priv->netdev->features & NETIF_F_HW_TLS_RX) 157 mlx5e_accel_fs_tcp_destroy(priv); 158 159 destroy_workqueue(priv->tls->rx_wq); 160 } 161 162 int mlx5e_ktls_init(struct mlx5e_priv *priv) 163 { 164 struct mlx5e_tls *tls; 165 166 if (!mlx5e_is_ktls_device(priv->mdev)) 167 return 0; 168 169 tls = kzalloc(sizeof(*tls), GFP_KERNEL); 170 if (!tls) 171 return -ENOMEM; 172 173 priv->tls = tls; 174 return 0; 175 } 176 177 void mlx5e_ktls_cleanup(struct mlx5e_priv *priv) 178 { 179 kfree(priv->tls); 180 priv->tls = NULL; 181 } 182