From: Ilya Lesokhin <il...@mellanox.com>

Implement the transmit and receive callbacks as well as the netdev
operations for adding and removing sockets.

Signed-off-by: Guy Shapiro <gu...@mellanox.com>
Signed-off-by: Ilya Lesokhin <il...@mellanox.com>
Signed-off-by: Matan Barak <mat...@mellanox.com>
Signed-off-by: Haggai Eran <hagg...@mellanox.com>
Signed-off-by: Aviad Yehezkel <avia...@mellanox.com>
---
 .../net/ethernet/mellanox/accelerator/tls/tls.c    | 652 +++++++++++++++++++++
 .../net/ethernet/mellanox/accelerator/tls/tls.h    | 100 ++++
 2 files changed, 752 insertions(+)
 create mode 100644 drivers/net/ethernet/mellanox/accelerator/tls/tls.c
 create mode 100644 drivers/net/ethernet/mellanox/accelerator/tls/tls.h

diff --git a/drivers/net/ethernet/mellanox/accelerator/tls/tls.c 
b/drivers/net/ethernet/mellanox/accelerator/tls/tls.c
new file mode 100644
index 0000000..07a4b67
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/accelerator/tls/tls.c
@@ -0,0 +1,652 @@
+/*
+ * Copyright (c) 2015-2017 Mellanox Technologies. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+#include "tls.h"
+#include "tls_sysfs.h"
+#include "tls_hw.h"
+#include "tls_cmds.h"
+#include <linux/mlx5/driver.h>
+#include <linux/netdevice.h>
+
+static LIST_HEAD(mlx_tls_devs);
+static DEFINE_MUTEX(mlx_tls_mutex);
+
+/* Start of context identifiers range (inclusive) */
+#define SWID_START     5
+/* End of context identifiers range (exclusive) */
+#define SWID_END       BIT(24)
+
+static netdev_features_t mlx_tls_feature_chk(struct sk_buff *skb,
+                                            struct net_device *netdev,
+                                            netdev_features_t features,
+                                            bool *done)
+{
+       return features;
+}
+
+int mlx_tls_get_count(struct net_device *netdev)
+{
+       return 0;
+}
+
+int mlx_tls_get_strings(struct net_device *netdev, uint8_t *data)
+{
+       return 0;
+}
+
+int mlx_tls_get_stats(struct net_device *netdev, u64 *data)
+{
+       return 0;
+}
+
+/* must hold mlx_tls_mutex to call this function */
+static struct mlx_tls_dev *find_mlx_tls_dev_by_netdev(
+               struct net_device *netdev)
+{
+       struct mlx_tls_dev *dev;
+
+       list_for_each_entry(dev, &mlx_tls_devs, accel_dev_list) {
+               if (dev->netdev == netdev)
+                       return dev;
+       }
+
+       return NULL;
+}
+
+struct mlx_tls_offload_context *get_tls_context(struct sock *sk)
+{
+       struct tls_context *tls_ctx = tls_get_ctx(sk);
+
+       return container_of(tls_offload_ctx(tls_ctx),
+                           struct mlx_tls_offload_context,
+                           context);
+}
+
+static int mlx_tls_add(struct net_device *netdev,
+                      struct sock *sk,
+                      enum tls_offload_ctx_dir direction,
+                      struct tls_crypto_info *crypto_info,
+                      struct tls_offload_context **ctx)
+{
+       struct tls_crypto_info_aes_gcm_128 *crypto_info_aes_gcm_128;
+       struct mlx_tls_offload_context *context;
+       struct mlx_tls_dev *dev;
+       int swid;
+       int ret;
+
+       pr_info("mlx_tls_add called\n");
+
+       if (direction == TLS_OFFLOAD_CTX_DIR_RX) {
+               pr_err("mlx_tls_add(): do not support recv\n");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (!crypto_info ||
+           crypto_info->cipher_type != TLS_CIPHER_AES_GCM_128) {
+               pr_err("mlx_tls_add(): support only aes_gcm_128\n");
+               ret = -EINVAL;
+               goto out;
+       }
+       crypto_info_aes_gcm_128 =
+                       (struct tls_crypto_info_aes_gcm_128 *)crypto_info;
+
+       dev = mlx_tls_find_dev_by_netdev(netdev);
+       if (!dev) {
+               pr_err("mlx_tls_add(): tls dev not found\n");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       swid = ida_simple_get(&dev->swid_ida, SWID_START, SWID_END,
+                             GFP_KERNEL);
+       if (swid < 0) {
+               pr_err("mlx_tls_add(): Failed to allocate swid\n");
+               ret = swid;
+               goto out;
+       }
+
+       context = kzalloc(sizeof(*context), GFP_KERNEL);
+       if (!context) {
+               ret = -ENOMEM;
+               goto release_swid;
+       }
+
+       context->swid = htonl(swid);
+       context->context.expectedSN = tcp_sk(sk)->write_seq;
+
+       ret = mlx_tls_hw_start_cmd(dev,
+                                  sk,
+                                  crypto_info_aes_gcm_128,
+                                  context);
+       if (ret)
+               goto relese_context;
+
+       try_module_get(THIS_MODULE);
+       *ctx = &context->context;
+out:
+       return ret;
+
+relese_context:
+       kfree(context);
+release_swid:
+       ida_simple_remove(&dev->swid_ida, swid);
+       return ret;
+}
+
+static void mlx_tls_del(struct net_device *netdev,
+                       struct sock *sk,
+                       enum tls_offload_ctx_dir direction)
+{
+       struct mlx_tls_offload_context *context = NULL;
+
+       if (direction == TLS_OFFLOAD_CTX_DIR_RX) {
+               pr_err("mlx_tls_del(): do not support recv\n");
+               return;
+       }
+
+       context = get_tls_context(sk);
+       if (context)
+               mlx_tls_hw_stop_cmd(netdev, context);
+       else
+               pr_err("delete non-offloaded context\n");
+}
+
+static const struct tlsdev_ops mlx_tls_ops = {
+       .tls_dev_add = mlx_tls_add,
+       .tls_dev_del = mlx_tls_del,
+};
+
+struct mlx_tls_dev *mlx_tls_find_dev_by_netdev(struct net_device *netdev)
+{
+       struct mlx_tls_dev *dev;
+
+       mutex_lock(&mlx_tls_mutex);
+       dev = find_mlx_tls_dev_by_netdev(netdev);
+       mutex_unlock(&mlx_tls_mutex);
+       return dev;
+}
+
+#define SYNDROME_OFFLOAD_REQUIRED 32
+#define SYNDROME_SYNC 33.
+#define SYNDROME_BYPASS 34
+
+#define MIN_BYPASS_RECORD_SIZE 29
+#define BYPASS_RECORD_PADDING_SIZE \
+               (MIN_BYPASS_RECORD_SIZE - TLS_HEADER_SIZE)
+
+#define MAX_BYPASS_SIZE ((1 << 15) - BYPASS_RECORD_PADDING_SIZE - 1)
+
+static void create_bypass_record(u8 *buf, u16 len)
+{
+       len += BYPASS_RECORD_PADDING_SIZE;
+       buf[0] = TLS_RECORD_TYPE_DATA;
+       buf[1] = TLS_1_2_VERSION_MAJOR;
+       buf[2] = TLS_1_2_VERSION_MINOR;
+       buf[3] = len >> 8;
+       buf[4] = len & 0xFF;
+       memset(buf + TLS_HEADER_SIZE, 0, BYPASS_RECORD_PADDING_SIZE);
+}
+
+struct sync_info {
+       s32 sync_len;
+       int nr_frags;
+       skb_frag_t frags[MAX_SKB_FRAGS];
+};
+
+static int get_sync_data(struct mlx_tls_offload_context *context,
+                        u32 tcp_seq, struct sync_info *info)
+{
+       struct tls_record_info *record;
+       unsigned long flags;
+       int remaining;
+       s32 sync_size;
+       int ret = -EINVAL;
+       int i = 0;
+
+       spin_lock_irqsave(&context->context.lock, flags);
+       record = tls_get_record(&context->context, tcp_seq);
+
+       if (unlikely(!record)) {
+               pr_err("record not found for seq %u\n", tcp_seq);
+               goto out;
+       }
+
+       sync_size = tcp_seq - (record->end_seq - record->len);
+       info->sync_len = sync_size;
+       if (unlikely(sync_size < 0)) {
+               if (record->len != 0) {
+                       pr_err("Invalid record for seq %u\n", tcp_seq);
+                       goto out;
+               }
+               goto done;
+       }
+
+       remaining = sync_size;
+       while (remaining > 0) {
+               info->frags[i] = record->frags[i];
+               __skb_frag_ref(&info->frags[i]);
+               remaining -= skb_frag_size(&info->frags[i]);
+
+               if (remaining < 0) {
+                       skb_frag_size_add(
+                                       &info->frags[i],
+                                       remaining);
+               }
+
+               i++;
+       }
+       info->nr_frags = i;
+done:
+       ret = 0;
+out:
+       spin_unlock_irqrestore(&context->context.lock, flags);
+       return ret;
+}
+
+static struct sk_buff *complete_sync_skb(
+               struct sk_buff *skb,
+               struct sk_buff *nskb,
+               u32 tcp_seq,
+               int headln,
+               unsigned char syndrome
+               )
+{
+       struct iphdr *iph;
+       struct tcphdr *th;
+       int mss;
+       struct pet *pet;
+       __be16 tcp_seq_low;
+
+       nskb->dev = skb->dev;
+       skb_reset_mac_header(nskb);
+       skb_set_network_header(nskb, skb_network_offset(skb));
+       skb_set_transport_header(nskb, skb_transport_offset(skb));
+       memcpy(nskb->data, skb->data, headln);
+
+       iph = ip_hdr(nskb);
+       iph->tot_len = htons(nskb->len - skb_network_offset(nskb));
+       th = tcp_hdr(nskb);
+       tcp_seq -= nskb->data_len;
+       th->seq = htonl(tcp_seq);
+       tcp_seq_low = htons(tcp_seq);
+
+       mss = nskb->dev->mtu - (headln - skb_network_offset(nskb));
+       skb_shinfo(nskb)->gso_size = 0;
+       if (nskb->data_len > mss) {
+               skb_shinfo(nskb)->gso_size = mss;
+               skb_shinfo(nskb)->gso_segs = DIV_ROUND_UP(nskb->data_len, mss);
+       }
+       skb_shinfo(nskb)->gso_type = skb_shinfo(skb)->gso_type;
+
+       nskb->queue_mapping = skb->queue_mapping;
+
+       pet = (struct pet *)(nskb->data + sizeof(struct ethhdr));
+       pet->syndrome = syndrome;
+       memcpy(pet->content.raw, &tcp_seq_low, sizeof(tcp_seq_low));
+
+       nskb->ip_summed = CHECKSUM_PARTIAL;
+       __skb_pull(nskb, skb_transport_offset(skb));
+       inet_csk(skb->sk)->icsk_af_ops->send_check(skb->sk, nskb);
+       __skb_push(nskb, skb_transport_offset(skb));
+
+       nskb->next = skb;
+       nskb->xmit_more = 1;
+       return nskb;
+}
+
+static void strip_pet(struct sk_buff *skb)
+{
+       struct ethhdr *old_eth;
+       struct ethhdr *new_eth;
+
+       old_eth = (struct ethhdr *)((skb->data)  - sizeof(struct ethhdr));
+       new_eth = (struct ethhdr *)((skb_pull_inline(skb, sizeof(struct pet)))
+                       - sizeof(struct ethhdr));
+       skb->mac_header += sizeof(struct pet);
+
+       memmove(new_eth, old_eth, 2 * ETH_ALEN);
+       /* Ethertype is already in its new place */
+}
+
+static struct sk_buff *handle_ooo(struct mlx_tls_offload_context *context,
+                                 struct sk_buff *skb)
+{
+       struct sync_info info;
+       u32 tcp_seq = ntohl(tcp_hdr(skb)->seq);
+       struct sk_buff *nskb;
+       int linear_len = 0;
+       int headln;
+       unsigned char syndrome = SYNDROME_SYNC;
+
+       if (get_sync_data(context, tcp_seq, &info)) {
+               dev_kfree_skb_any(skb);
+               return NULL;
+       }
+
+       headln = skb_transport_offset(skb) + tcp_hdrlen(skb);
+
+       if (unlikely(info.sync_len < 0)) {
+               if (-info.sync_len > MAX_BYPASS_SIZE) {
+                       if (skb->len - headln > -info.sync_len) {
+                               pr_err("Required bypass record is too big\n");
+                               /* can fragment into two large SKBs in SW */
+                               return NULL;
+                       }
+                       skb_push(skb, sizeof(struct ethhdr));
+                       strip_pet(skb);
+                       skb_pull(skb, sizeof(struct ethhdr));
+                       return skb;
+               }
+
+               linear_len = MIN_BYPASS_RECORD_SIZE;
+       }
+
+       linear_len += headln;
+       nskb = alloc_skb(linear_len, GFP_ATOMIC);
+       if (unlikely(!nskb)) {
+               dev_kfree_skb_any(skb);
+               return NULL;
+       }
+
+       skb_put(nskb, linear_len);
+       syndrome = SYNDROME_SYNC;
+       if (likely(info.sync_len >= 0)) {
+               int i;
+
+               for (i = 0; i < info.nr_frags; i++)
+                       skb_shinfo(nskb)->frags[i] = info.frags[i];
+
+               skb_shinfo(nskb)->nr_frags = info.nr_frags;
+               nskb->data_len = info.sync_len;
+               nskb->len += info.sync_len;
+       } else {
+               create_bypass_record(nskb->data + headln, -info.sync_len);
+               tcp_seq -= MIN_BYPASS_RECORD_SIZE;
+               syndrome = SYNDROME_BYPASS;
+       }
+
+       return complete_sync_skb(skb, nskb, tcp_seq, headln, syndrome);
+}
+
+static int insert_pet(struct sk_buff *skb)
+{
+       struct ethhdr *eth;
+       struct pet *pet;
+       struct mlx_tls_offload_context *context;
+
+       pr_debug("insert_pet started\n");
+       if (skb_cow_head(skb, sizeof(struct pet)))
+               return -ENOMEM;
+
+       eth = (struct ethhdr *)skb_push(skb, sizeof(struct pet));
+       skb->mac_header -= sizeof(struct pet);
+       pet = (struct pet *)(eth + 1);
+
+       memmove(skb->data, skb->data + sizeof(struct pet), 2 * ETH_ALEN);
+
+       eth->h_proto = cpu_to_be16(MLX5_METADATA_ETHER_TYPE);
+       pet->syndrome = SYNDROME_OFFLOAD_REQUIRED;
+
+       memset(pet->content.raw, 0, sizeof(pet->content.raw));
+       context = get_tls_context(skb->sk);
+       memcpy(pet->content.send.sid, &context->swid,
+              sizeof(pet->content.send.sid));
+
+       return 0;
+}
+
+static struct sk_buff *mlx_tls_tx_handler(struct sk_buff *skb,
+                                         struct mlx5_swp_info *swp_info)
+{
+       struct mlx_tls_offload_context *context;
+       int datalen;
+       u32 skb_seq;
+
+       pr_debug("mlx_tls_tx_handler started\n");
+
+       if (!skb->sk || !tls_is_sk_tx_device_offloaded(skb->sk))
+               goto out;
+
+       datalen = skb->len - (skb_transport_offset(skb) + tcp_hdrlen(skb));
+       if (!datalen)
+               goto out;
+
+       skb_seq =  ntohl(tcp_hdr(skb)->seq);
+
+       context = get_tls_context(skb->sk);
+       pr_debug("mlx_tls_tx_handler: mapping: %u cpu %u size %u with swid %u 
expectedSN: %u actualSN: %u\n",
+                skb->queue_mapping, smp_processor_id(), skb->len,
+                ntohl(context->swid), context->context.expectedSN, skb_seq);
+
+       insert_pet(skb);
+
+       if (unlikely(context->context.expectedSN != skb_seq)) {
+               skb = handle_ooo(context, skb);
+               if (!skb)
+                       goto out;
+
+               pr_info("Sending sync packet\n");
+
+               if (!skb->next)
+                       goto out;
+       }
+       context->context.expectedSN = skb_seq + datalen;
+
+out:
+       return skb;
+}
+
+static struct sk_buff *mlx_tls_rx_handler(struct sk_buff *skb, u8 *rawpet,
+                                         u8 petlen)
+{
+       struct pet *pet = (struct pet *)rawpet;
+
+       if (petlen != sizeof(*pet))
+               goto out;
+
+       dev_dbg(&skb->dev->dev, ">> rx_handler %u bytes\n", skb->len);
+       dev_dbg(&skb->dev->dev, "   RX PET: size %lu, etherType %04X, syndrome 
%02x\n",
+               sizeof(*pet), be16_to_cpu(pet->ethertype), pet->syndrome);
+
+       if (pet->syndrome != 48) {
+               dev_dbg(&skb->dev->dev, "unexpected pet syndrome %d\n",
+                       pet->syndrome);
+               goto out;
+       }
+
+out:
+       return skb;
+}
+
+/* Must hold mlx_tls_mutex to call this function.
+ * Assumes that dev->core_ctx is destroyed be the caller
+ */
+static void mlx_tls_free(struct mlx_tls_dev *dev)
+{
+       list_del(&dev->accel_dev_list);
+#ifdef MLX_TLS_SADB_RDMA
+       kobject_put(&dev->kobj);
+#endif
+       dev_put(dev->netdev);
+       kfree(dev);
+}
+
+int mlx_tls_netdev_event(struct notifier_block *this, unsigned long event,
+                        void *ptr)
+{
+       struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
+       struct mlx_tls_dev *accel_dev = NULL;
+
+       if (!netdev)
+               goto out;
+
+       pr_debug("mlx_tls_netdev_event: %lu\n", event);
+
+       /* We are interested only in net devices going down */
+       if (event != NETDEV_UNREGISTER)
+               goto out;
+
+       /* Take down all connections using a netdev that is going down */
+       mutex_lock(&mlx_tls_mutex);
+       accel_dev = find_mlx_tls_dev_by_netdev(netdev);
+       if (!accel_dev) {
+               pr_debug("mlx_tls_netdev_event: Failed to find tls device for 
net device\n");
+               goto unlock;
+       }
+       mlx_tls_free(accel_dev);
+
+unlock:
+       mutex_unlock(&mlx_tls_mutex);
+out:
+       return NOTIFY_DONE;
+}
+
+static struct mlx5_accel_ops mlx_tls_client_ops = {
+       .rx_handler   = mlx_tls_rx_handler,
+       .tx_handler   = mlx_tls_tx_handler,
+       .feature_chk  = mlx_tls_feature_chk,
+       .get_count = mlx_tls_get_count,
+       .get_strings = mlx_tls_get_strings,
+       .get_stats = mlx_tls_get_stats,
+       .mtu_extra = sizeof(struct pet),
+       .features = 0,
+};
+
+int mlx_tls_add_one(struct mlx_accel_core_device *accel_device)
+{
+       int ret = 0;
+       struct mlx_tls_dev *dev = NULL;
+       struct net_device *netdev = NULL;
+#ifdef MLX_TLS_SADB_RDMA
+       struct mlx_accel_core_conn_init_attr init_attr = {0};
+#endif
+       pr_debug("mlx_tls_add_one called for %s\n", accel_device->name);
+
+       dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+       if (!dev) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       INIT_LIST_HEAD(&dev->accel_dev_list);
+       dev->accel_device = accel_device;
+       ida_init(&dev->swid_ida);
+
+#ifdef MLX_TLS_SADB_RDMA
+       init_attr.rx_size = 128;
+       init_attr.tx_size = 32;
+       init_attr.recv_cb = mlx_tls_hw_qp_recv_cb;
+       init_attr.cb_arg = dev;
+       dev->conn = mlx_accel_core_conn_create(accel_device, &init_attr);
+       if (IS_ERR(dev->conn)) {
+               ret = PTR_ERR(dev->conn);
+               pr_err("mlx_tls_add_one(): Got error while creating connection 
%d\n",
+                      ret);
+               goto err_dev;
+       }
+#endif
+       netdev = accel_device->ib_dev->get_netdev(accel_device->ib_dev,
+                       accel_device->port);
+       if (!netdev) {
+               pr_err("mlx_tls_add_one(): Failed to retrieve net device from 
ib device\n");
+               ret = -EINVAL;
+               goto err_conn;
+       }
+       dev->netdev = netdev;
+
+       ret = mlx_accel_core_client_ops_register(accel_device,
+                                                &mlx_tls_client_ops);
+       if (ret) {
+               pr_err("mlx_tls_add_one(): Failed to register client ops %d\n",
+                      ret);
+               goto err_netdev;
+       }
+
+#ifdef MLX_TLS_SADB_RDMA
+       ret = tls_sysfs_init_and_add(&dev->kobj,
+                                    mlx_accel_core_kobj(dev->accel_device),
+                                    "%s",
+                                    "accel_dev");
+       if (ret) {
+               pr_err("mlx_tls_add_one(): Got error from kobject_init_and_add 
%d\n",
+                      ret);
+               goto err_ops_register;
+       }
+#endif
+
+       mutex_lock(&mlx_tls_mutex);
+       list_add(&dev->accel_dev_list, &mlx_tls_devs);
+       mutex_unlock(&mlx_tls_mutex);
+
+       dev->netdev->tlsdev_ops = &mlx_tls_ops;
+       goto out;
+
+#ifdef MLX_TLS_SADB_RDMA
+err_ops_register:
+       mlx_accel_core_client_ops_unregister(accel_device);
+#endif
+err_netdev:
+       dev_put(netdev);
+err_conn:
+       mlx_accel_core_conn_destroy(dev->conn);
+#ifdef MLX_TLS_SADB_RDMA
+err_dev:
+#endif
+       kfree(dev);
+out:
+       return ret;
+}
+
+void mlx_tls_remove_one(struct mlx_accel_core_device *accel_device)
+{
+       struct mlx_tls_dev *dev;
+       struct net_device *netdev = NULL;
+
+       pr_debug("mlx_tls_remove_one called for %s\n", accel_device->name);
+
+       mutex_lock(&mlx_tls_mutex);
+
+       list_for_each_entry(dev, &mlx_tls_devs, accel_dev_list) {
+               if (dev->accel_device == accel_device) {
+                       netdev = dev->netdev;
+                       netdev->tlsdev_ops = NULL;
+                       mlx_accel_core_client_ops_unregister(accel_device);
+#ifdef MLX_TLS_SADB_RDMA
+                       mlx_accel_core_conn_destroy(dev->conn);
+#endif
+                       mlx_tls_free(dev);
+                       break;
+               }
+       }
+       mutex_unlock(&mlx_tls_mutex);
+}
diff --git a/drivers/net/ethernet/mellanox/accelerator/tls/tls.h 
b/drivers/net/ethernet/mellanox/accelerator/tls/tls.h
new file mode 100644
index 0000000..7c7539a
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/accelerator/tls/tls.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2015-2017 Mellanox Technologies. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+#ifndef __TLS_H__
+#define __TLS_H__
+
+#include <linux/types.h>
+#include <linux/kobject.h>
+#include <linux/kfifo.h>
+#include <linux/list.h>
+#include <linux/skbuff.h>
+#include <linux/hashtable.h>
+#include <net/sock.h>
+#include <net/inet_common.h>
+#include <net/tls.h>
+#include <linux/mlx5/accel_sdk.h>
+
+#include "tls_cmds.h"
+
+#define DRIVER_NAME    "mlx_tls"
+#define DRIVER_VERSION "0.1"
+#define DRIVER_RELDATE "January 2016"
+
+#define MLX_TLS_DEVICE_NAME                                    "mlx_tls"
+/* TODO: Consider moving this to include/uapi/linux/if_ether.h */
+
+struct send_pet_content {
+       /* The next field is meaningful only for sync packets with LSO
+        * enabled (by the syndrome field))
+        */
+       __be16 first_seq;       /* LSBs of the first TCP seq in the packet */
+       unsigned char sid[3];
+} __packed;
+
+/*TODO: move this to HW/cmds header files when added*/
+struct pet {
+       unsigned char syndrome;
+       union {
+               unsigned char raw[5];
+               /* from host to FPGA */
+               struct send_pet_content send;
+       } __packed content;
+       /* packet type ID field */
+       __be16 ethertype;
+} __packed;
+
+struct mlx_tls_dev {
+       struct kobject kobj;
+       struct list_head accel_dev_list;
+       struct mlx_accel_core_device *accel_device;
+       struct mlx_accel_core_conn *conn;
+       struct net_device *netdev;
+       struct ida swid_ida;
+};
+
+struct mlx_tls_offload_context {
+       struct tls_offload_context context;
+       struct list_head tls_del_list;
+       struct net_device *netdev;
+       __be32 swid;
+};
+
+int mlx_tls_netdev_event(struct notifier_block *this,
+                        unsigned long event, void *ptr);
+
+int mlx_tls_add_one(struct mlx_accel_core_device *accel_device);
+void mlx_tls_remove_one(struct mlx_accel_core_device *accel_device);
+
+struct mlx_tls_dev *mlx_tls_find_dev_by_netdev(struct net_device *netdev);
+
+#endif /* __TLS_H__ */
-- 
2.7.4

Reply via email to