Skip to content

Commit

Permalink
crypto/chcr: Moving chelsio's inline ipsec functionality to /drivers/net
Browse files Browse the repository at this point in the history
This patch seperates inline ipsec functionality from coprocessor
driver chcr. Now inline ipsec is separate ULD, moved from
"drivers/crypto/chelsio/" to "drivers/net/ethernet/chelsio/inline_crypto/ch_ipsec/"

Signed-off-by: Ayush Sawal <[email protected]>
Signed-off-by: Vinay Kumar Yadav <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
vinaychelsio authored and davem330 committed Aug 21, 2020
1 parent 44fd1c1 commit 1b77be4
Show file tree
Hide file tree
Showing 13 changed files with 205 additions and 91 deletions.
10 changes: 0 additions & 10 deletions drivers/crypto/chelsio/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,6 @@ config CRYPTO_DEV_CHELSIO
To compile this driver as a module, choose M here: the module
will be called chcr.

config CHELSIO_IPSEC_INLINE
bool "Chelsio IPSec XFRM Tx crypto offload"
depends on CHELSIO_T4
depends on CRYPTO_DEV_CHELSIO
depends on XFRM_OFFLOAD
depends on INET_ESP_OFFLOAD || INET6_ESP_OFFLOAD
default n
help
Enable support for IPSec Tx Inline.

config CHELSIO_TLS_DEVICE
bool "Chelsio Inline KTLS Offload"
depends on CHELSIO_T4
Expand Down
1 change: 0 additions & 1 deletion drivers/crypto/chelsio/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,3 @@ chcr-objs := chcr_core.o chcr_algo.o
#ifdef CONFIG_CHELSIO_TLS_DEVICE
chcr-objs += chcr_ktls.o
#endif
chcr-$(CONFIG_CHELSIO_IPSEC_INLINE) += chcr_ipsec.o
42 changes: 2 additions & 40 deletions drivers/crypto/chelsio/chcr_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,6 @@ static const struct tlsdev_ops chcr_ktls_ops = {
};
#endif

#ifdef CONFIG_CHELSIO_IPSEC_INLINE
static void update_netdev_features(void);
#endif /* CONFIG_CHELSIO_IPSEC_INLINE */

static chcr_handler_func work_handlers[NUM_CPL_CMDS] = {
[CPL_FW6_PLD] = cpl_fw6_pld_handler,
#ifdef CONFIG_CHELSIO_TLS_DEVICE
Expand All @@ -60,10 +56,8 @@ static struct cxgb4_uld_info chcr_uld_info = {
.add = chcr_uld_add,
.state_change = chcr_uld_state_change,
.rx_handler = chcr_uld_rx_handler,
#if defined(CONFIG_CHELSIO_IPSEC_INLINE) || defined(CONFIG_CHELSIO_TLS_DEVICE)
.tx_handler = chcr_uld_tx_handler,
#endif /* CONFIG_CHELSIO_IPSEC_INLINE || CONFIG_CHELSIO_TLS_DEVICE */
#if defined(CONFIG_CHELSIO_TLS_DEVICE)
.tx_handler = chcr_uld_tx_handler,
.tlsdev_ops = &chcr_ktls_ops,
#endif
};
Expand Down Expand Up @@ -241,19 +235,11 @@ int chcr_uld_rx_handler(void *handle, const __be64 *rsp,
return 0;
}

#if defined(CONFIG_CHELSIO_IPSEC_INLINE) || defined(CONFIG_CHELSIO_TLS_DEVICE)
#if defined(CONFIG_CHELSIO_TLS_DEVICE)
int chcr_uld_tx_handler(struct sk_buff *skb, struct net_device *dev)
{
/* In case if skb's decrypted bit is set, it's nic tls packet, else it's
* ipsec packet.
*/
#ifdef CONFIG_CHELSIO_TLS_DEVICE
if (skb->decrypted)
return chcr_ktls_xmit(skb, dev);
#endif
#ifdef CONFIG_CHELSIO_IPSEC_INLINE
return chcr_ipsec_xmit(skb, dev);
#endif
return 0;
}
#endif /* CONFIG_CHELSIO_IPSEC_INLINE || CONFIG_CHELSIO_TLS_DEVICE */
Expand Down Expand Up @@ -305,24 +291,6 @@ static int chcr_uld_state_change(void *handle, enum cxgb4_state state)
return ret;
}

#ifdef CONFIG_CHELSIO_IPSEC_INLINE
static void update_netdev_features(void)
{
struct uld_ctx *u_ctx, *tmp;

mutex_lock(&drv_data.drv_mutex);
list_for_each_entry_safe(u_ctx, tmp, &drv_data.inact_dev, entry) {
if (u_ctx->lldi.crypto & ULP_CRYPTO_IPSEC_INLINE)
chcr_add_xfrmops(&u_ctx->lldi);
}
list_for_each_entry_safe(u_ctx, tmp, &drv_data.act_dev, entry) {
if (u_ctx->lldi.crypto & ULP_CRYPTO_IPSEC_INLINE)
chcr_add_xfrmops(&u_ctx->lldi);
}
mutex_unlock(&drv_data.drv_mutex);
}
#endif /* CONFIG_CHELSIO_IPSEC_INLINE */

static int __init chcr_crypto_init(void)
{
INIT_LIST_HEAD(&drv_data.act_dev);
Expand All @@ -332,12 +300,6 @@ static int __init chcr_crypto_init(void)
drv_data.last_dev = NULL;
cxgb4_register_uld(CXGB4_ULD_CRYPTO, &chcr_uld_info);

#ifdef CONFIG_CHELSIO_IPSEC_INLINE
rtnl_lock();
update_netdev_features();
rtnl_unlock();
#endif /* CONFIG_CHELSIO_IPSEC_INLINE */

return 0;
}

Expand Down
31 changes: 0 additions & 31 deletions drivers/crypto/chelsio/chcr_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,37 +109,6 @@ struct uld_ctx {
struct chcr_dev dev;
};

struct chcr_ipsec_req {
struct ulp_txpkt ulptx;
struct ulptx_idata sc_imm;
struct cpl_tx_sec_pdu sec_cpl;
struct _key_ctx key_ctx;
};

struct chcr_ipsec_wr {
struct fw_ulptx_wr wreq;
struct chcr_ipsec_req req;
};

#define ESN_IV_INSERT_OFFSET 12
struct chcr_ipsec_aadiv {
__be32 spi;
u8 seq_no[8];
u8 iv[8];
};

struct ipsec_sa_entry {
int hmac_ctrl;
u16 esn;
u16 resv;
unsigned int enckey_len;
unsigned int kctx_len;
unsigned int authsize;
__be32 key_ctx_hdr;
char salt[MAX_SALT];
char key[2 * AES_MAX_KEY_SIZE];
};

/*
* sgl_len - calculates the size of an SGL of the given capacity
* @n: the number of SGL entries
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
Original file line number Diff line number Diff line change
Expand Up @@ -1196,6 +1196,9 @@ struct adapter {
struct cxgb4_tc_u32_table *tc_u32;
struct chcr_ktls chcr_ktls;
struct chcr_stats_debug chcr_stats;
#if IS_ENABLED(CONFIG_CHELSIO_IPSEC_INLINE)
struct ch_ipsec_stats_debug ch_ipsec_stats;
#endif

/* TC flower offload */
bool tc_flower_initialized;
Expand Down
7 changes: 5 additions & 2 deletions drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -3542,14 +3542,17 @@ static int chcr_stats_show(struct seq_file *seq, void *v)
atomic_read(&adap->chcr_stats.error));
seq_printf(seq, "Fallback: %10u \n",
atomic_read(&adap->chcr_stats.fallback));
seq_printf(seq, "IPSec PDU: %10u\n",
atomic_read(&adap->chcr_stats.ipsec_cnt));
seq_printf(seq, "TLS PDU Tx: %10u\n",
atomic_read(&adap->chcr_stats.tls_pdu_tx));
seq_printf(seq, "TLS PDU Rx: %10u\n",
atomic_read(&adap->chcr_stats.tls_pdu_rx));
seq_printf(seq, "TLS Keys (DDR) Count: %10u\n",
atomic_read(&adap->chcr_stats.tls_key));
#if IS_ENABLED(CONFIG_CHELSIO_IPSEC_INLINE)
seq_puts(seq, "\nChelsio Inline IPsec Crypto Accelerator Stats\n");
seq_printf(seq, "IPSec PDU: %10u\n",
atomic_read(&adap->ch_ipsec_stats.ipsec_cnt));
#endif
#ifdef CONFIG_CHELSIO_TLS_DEVICE
seq_puts(seq, "\nChelsio KTLS Crypto Accelerator Stats\n");
seq_printf(seq, "Tx TLS offload refcount: %20u\n",
Expand Down
8 changes: 7 additions & 1 deletion drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ enum cxgb4_uld {
CXGB4_ULD_ISCSI,
CXGB4_ULD_ISCSIT,
CXGB4_ULD_CRYPTO,
CXGB4_ULD_IPSEC,
CXGB4_ULD_TLS,
CXGB4_ULD_MAX
};
Expand Down Expand Up @@ -368,7 +369,6 @@ struct chcr_stats_debug {
atomic_t complete;
atomic_t error;
atomic_t fallback;
atomic_t ipsec_cnt;
atomic_t tls_pdu_tx;
atomic_t tls_pdu_rx;
atomic_t tls_key;
Expand All @@ -394,6 +394,12 @@ struct chcr_stats_debug {
#endif
};

#if IS_ENABLED(CONFIG_CHELSIO_IPSEC_INLINE)
struct ch_ipsec_stats_debug {
atomic_t ipsec_cnt;
};
#endif

#define OCQ_WIN_OFFSET(pdev, vres) \
(pci_resource_len((pdev), 2) - roundup_pow_of_two((vres)->ocq.size))

Expand Down
4 changes: 2 additions & 2 deletions drivers/net/ethernet/chelsio/cxgb4/sge.c
Original file line number Diff line number Diff line change
Expand Up @@ -1416,9 +1416,9 @@ static netdev_tx_t cxgb4_eth_xmit(struct sk_buff *skb, struct net_device *dev)
pi = netdev_priv(dev);
adap = pi->adapter;
ssi = skb_shinfo(skb);
#ifdef CONFIG_CHELSIO_IPSEC_INLINE
#if IS_ENABLED(CONFIG_CHELSIO_IPSEC_INLINE)
if (xfrm_offload(skb) && !ssi->gso_size)
return adap->uld[CXGB4_ULD_CRYPTO].tx_handler(skb, dev);
return adap->uld[CXGB4_ULD_IPSEC].tx_handler(skb, dev);
#endif /* CHELSIO_IPSEC_INLINE */

#ifdef CONFIG_CHELSIO_TLS_DEVICE
Expand Down
12 changes: 12 additions & 0 deletions drivers/net/ethernet/chelsio/inline_crypto/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,16 @@ config CRYPTO_DEV_CHELSIO_TLS
To compile this driver as a module, choose M here: the module
will be called chtls.

config CHELSIO_IPSEC_INLINE
tristate "Chelsio IPSec XFRM Tx crypto offload"
depends on CHELSIO_T4
depends on XFRM_OFFLOAD
depends on INET_ESP_OFFLOAD || INET6_ESP_OFFLOAD
help
Support Chelsio Inline IPsec with Chelsio crypto accelerator.
Enable inline IPsec support for Tx.

To compile this driver as a module, choose M here: the module
will be called ch_ipsec.

endif # CHELSIO_INLINE_CRYPTO
1 change: 1 addition & 0 deletions drivers/net/ethernet/chelsio/inline_crypto/Makefile
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_CRYPTO_DEV_CHELSIO_TLS) += chtls/
obj-$(CONFIG_CHELSIO_IPSEC_INLINE) += ch_ipsec/
8 changes: 8 additions & 0 deletions drivers/net/ethernet/chelsio/inline_crypto/ch_ipsec/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# SPDX-License-Identifier: GPL-2.0-only
ccflags-y := -I $(srctree)/drivers/net/ethernet/chelsio/cxgb4 \
-I $(srctree)/drivers/crypto/chelsio

obj-$(CONFIG_CHELSIO_IPSEC_INLINE) += ch_ipsec.o
ch_ipsec-objs := chcr_ipsec.o


Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,7 @@
#include <crypto/scatterwalk.h>
#include <crypto/internal/hash.h>

#include "chcr_core.h"
#include "chcr_algo.h"
#include "chcr_crypto.h"
#include "chcr_ipsec.h"

/*
* Max Tx descriptor space we allow for an Ethernet packet to be inlined
Expand All @@ -71,11 +69,17 @@
#define MAX_IMM_TX_PKT_LEN 256
#define GCM_ESP_IV_SIZE 8

static LIST_HEAD(uld_ctx_list);
static DEFINE_MUTEX(dev_mutex);

static int chcr_xfrm_add_state(struct xfrm_state *x);
static void chcr_xfrm_del_state(struct xfrm_state *x);
static void chcr_xfrm_free_state(struct xfrm_state *x);
static bool chcr_ipsec_offload_ok(struct sk_buff *skb, struct xfrm_state *x);
static void chcr_advance_esn_state(struct xfrm_state *x);
static int ch_ipsec_uld_state_change(void *handle, enum cxgb4_state new_state);
static void *ch_ipsec_uld_add(const struct cxgb4_lld_info *infop);
static void update_netdev_features(void);

static const struct xfrmdev_ops chcr_xfrmdev_ops = {
.xdo_dev_state_add = chcr_xfrm_add_state,
Expand All @@ -102,6 +106,57 @@ void chcr_add_xfrmops(const struct cxgb4_lld_info *lld)
}
}

static struct cxgb4_uld_info ch_ipsec_uld_info = {
.name = CHIPSEC_DRV_MODULE_NAME,
.nrxq = MAX_ULD_QSETS,
/* Max ntxq will be derived from fw config file*/
.rxq_size = 1024,
.add = ch_ipsec_uld_add,
.state_change = ch_ipsec_uld_state_change,
.tx_handler = chcr_ipsec_xmit,
};

static void *ch_ipsec_uld_add(const struct cxgb4_lld_info *infop)
{
struct ipsec_uld_ctx *u_ctx;

pr_info_once("%s - version %s\n", CHIPSEC_DRV_DESC,
CHIPSEC_DRV_VERSION);
u_ctx = kzalloc(sizeof(*u_ctx), GFP_KERNEL);
if (!u_ctx) {
u_ctx = ERR_PTR(-ENOMEM);
goto out;
}
u_ctx->lldi = *infop;
out:
return u_ctx;
}

static int ch_ipsec_uld_state_change(void *handle, enum cxgb4_state new_state)
{
struct ipsec_uld_ctx *u_ctx = handle;

pr_info("new_state %u\n", new_state);
switch (new_state) {
case CXGB4_STATE_UP:
pr_info("%s: Up\n", pci_name(u_ctx->lldi.pdev));
mutex_lock(&dev_mutex);
list_add_tail(&u_ctx->entry, &uld_ctx_list);
mutex_unlock(&dev_mutex);
break;
case CXGB4_STATE_START_RECOVERY:
case CXGB4_STATE_DOWN:
case CXGB4_STATE_DETACH:
pr_info("%s: Down\n", pci_name(u_ctx->lldi.pdev));
list_del(&u_ctx->entry);
break;
default:
break;
}

return 0;
}

static inline int chcr_ipsec_setauthsize(struct xfrm_state *x,
struct ipsec_sa_entry *sa_entry)
{
Expand Down Expand Up @@ -538,7 +593,7 @@ inline void *chcr_crypto_wreq(struct sk_buff *skb,
unsigned int kctx_len = sa_entry->kctx_len;
int qid = q->q.cntxt_id;

atomic_inc(&adap->chcr_stats.ipsec_cnt);
atomic_inc(&adap->ch_ipsec_stats.ipsec_cnt);

flits = calc_tx_sec_flits(skb, sa_entry, &immediate);
ndesc = DIV_ROUND_UP(flits, 2);
Expand Down Expand Up @@ -752,3 +807,51 @@ out_free: dev_kfree_skb_any(skb);
cxgb4_ring_tx_db(adap, &q->q, ndesc);
return NETDEV_TX_OK;
}

static void update_netdev_features(void)
{
struct ipsec_uld_ctx *u_ctx, *tmp;

mutex_lock(&dev_mutex);
list_for_each_entry_safe(u_ctx, tmp, &uld_ctx_list, entry) {
if (u_ctx->lldi.crypto & ULP_CRYPTO_IPSEC_INLINE)
chcr_add_xfrmops(&u_ctx->lldi);
}
mutex_unlock(&dev_mutex);
}

static int __init chcr_ipsec_init(void)
{
cxgb4_register_uld(CXGB4_ULD_IPSEC, &ch_ipsec_uld_info);

rtnl_lock();
update_netdev_features();
rtnl_unlock();

return 0;
}

static void __exit chcr_ipsec_exit(void)
{
struct ipsec_uld_ctx *u_ctx, *tmp;
struct adapter *adap;

mutex_lock(&dev_mutex);
list_for_each_entry_safe(u_ctx, tmp, &uld_ctx_list, entry) {
adap = pci_get_drvdata(u_ctx->lldi.pdev);
atomic_set(&adap->ch_ipsec_stats.ipsec_cnt, 0);
list_del(&u_ctx->entry);
kfree(u_ctx);
}
mutex_unlock(&dev_mutex);
cxgb4_unregister_uld(CXGB4_ULD_IPSEC);
}

module_init(chcr_ipsec_init);
module_exit(chcr_ipsec_exit);

MODULE_DESCRIPTION("Crypto IPSEC for Chelsio Terminator cards.");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Chelsio Communications");
MODULE_VERSION(CHIPSEC_DRV_VERSION);

Loading

0 comments on commit 1b77be4

Please sign in to comment.