All of lore.kernel.org
 help / color / mirror / Atom feed
From: Akhil Goyal <akhil.goyal@nxp.com>
To: <dev@dpdk.org>
Cc: <declan.doherty@intel.com>, <pablo.de.lara.guarch@intel.com>,
	<hemant.agrawal@nxp.com>, <radu.nicolau@intel.com>,
	<borisp@mellanox.com>, <aviadye@mellanox.com>,
	<thomas@monjalon.net>, <sandeep.malik@nxp.com>,
	<jerin.jacob@caviumnetworks.com>, <john.mcnamara@intel.com>,
	<konstantin.ananyev@intel.com>, <shahafs@mellanox.com>,
	<olivier.matz@6wind.com>
Subject: [PATCH v4 11/12] crypto/dpaa2_sec: add support for protocol offload ipsec
Date: Sun, 15 Oct 2017 03:47:33 +0530	[thread overview]
Message-ID: <20171014221734.15511-12-akhil.goyal@nxp.com> (raw)
In-Reply-To: <20171014221734.15511-1-akhil.goyal@nxp.com>

Driver implementation to support rte_security APIs

Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com>
---
 doc/guides/cryptodevs/features/dpaa2_sec.ini |   1 +
 drivers/crypto/Makefile                      |   2 +-
 drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c  | 420 ++++++++++++++++++++++++++-
 drivers/crypto/dpaa2_sec/dpaa2_sec_priv.h    |  62 ++++
 4 files changed, 473 insertions(+), 12 deletions(-)

diff --git a/doc/guides/cryptodevs/features/dpaa2_sec.ini b/doc/guides/cryptodevs/features/dpaa2_sec.ini
index c3bb3dd..8fd07d6 100644
--- a/doc/guides/cryptodevs/features/dpaa2_sec.ini
+++ b/doc/guides/cryptodevs/features/dpaa2_sec.ini
@@ -7,6 +7,7 @@
 Symmetric crypto       = Y
 Sym operation chaining = Y
 HW Accelerated         = Y
+Protocol offload       = Y
 
 ;
 ; Supported crypto algorithms of the 'dpaa2_sec' crypto driver.
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index d8c8740..ec297f2 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -56,7 +56,7 @@ DEPDIRS-mrvl = $(core-libs)
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_NULL_CRYPTO) += null
 DEPDIRS-null = $(core-libs)
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_SEC) += dpaa2_sec
-DEPDIRS-dpaa2_sec = $(core-libs)
+DEPDIRS-dpaa2_sec = $(core-libs) librte_security
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA_SEC) += dpaa_sec
 DEPDIRS-dpaa_sec = $(core-libs)
 
diff --git a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
index 672cacf..c768313 100644
--- a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
+++ b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c
@@ -36,6 +36,7 @@
 
 #include <rte_mbuf.h>
 #include <rte_cryptodev.h>
+#include <rte_security_driver.h>
 #include <rte_malloc.h>
 #include <rte_memcpy.h>
 #include <rte_string_fns.h>
@@ -73,12 +74,44 @@
 #define FLE_POOL_NUM_BUFS	32000
 #define FLE_POOL_BUF_SIZE	256
 #define FLE_POOL_CACHE_SIZE	512
+#define SEC_FLC_DHR_OUTBOUND	-114
+#define SEC_FLC_DHR_INBOUND	0
 
 enum rta_sec_era rta_sec_era = RTA_SEC_ERA_8;
 
 static uint8_t cryptodev_driver_id;
 
 static inline int
+build_proto_fd(dpaa2_sec_session *sess,
+	       struct rte_crypto_op *op,
+	       struct qbman_fd *fd, uint16_t bpid)
+{
+	struct rte_crypto_sym_op *sym_op = op->sym;
+	struct ctxt_priv *priv = sess->ctxt;
+	struct sec_flow_context *flc;
+	struct rte_mbuf *mbuf = sym_op->m_src;
+
+	if (likely(bpid < MAX_BPID))
+		DPAA2_SET_FD_BPID(fd, bpid);
+	else
+		DPAA2_SET_FD_IVP(fd);
+
+	/* Save the shared descriptor */
+	flc = &priv->flc_desc[0].flc;
+
+	DPAA2_SET_FD_ADDR(fd, DPAA2_MBUF_VADDR_TO_IOVA(sym_op->m_src));
+	DPAA2_SET_FD_OFFSET(fd, sym_op->m_src->data_off);
+	DPAA2_SET_FD_LEN(fd, sym_op->m_src->pkt_len);
+	DPAA2_SET_FD_FLC(fd, ((uint64_t)flc));
+
+	/* save physical address of mbuf */
+	op->sym->aead.digest.phys_addr = mbuf->buf_physaddr;
+	mbuf->buf_physaddr = (uint64_t)op;
+
+	return 0;
+}
+
+static inline int
 build_authenc_gcm_fd(dpaa2_sec_session *sess,
 		     struct rte_crypto_op *op,
 		     struct qbman_fd *fd, uint16_t bpid)
@@ -545,13 +578,23 @@ build_cipher_fd(dpaa2_sec_session *sess, struct rte_crypto_op *op,
 }
 
 static inline int
-build_sec_fd(dpaa2_sec_session *sess, struct rte_crypto_op *op,
+build_sec_fd(struct rte_crypto_op *op,
 	     struct qbman_fd *fd, uint16_t bpid)
 {
 	int ret = -1;
+	dpaa2_sec_session *sess;
 
 	PMD_INIT_FUNC_TRACE();
 
+	if (op->sess_type == RTE_CRYPTO_OP_WITH_SESSION)
+		sess = (dpaa2_sec_session *)get_session_private_data(
+				op->sym->session, cryptodev_driver_id);
+	else if (op->sess_type == RTE_CRYPTO_OP_SECURITY_SESSION)
+		sess = (dpaa2_sec_session *)get_sec_session_private_data(
+				op->sym->sec_session);
+	else
+		return -1;
+
 	switch (sess->ctxt_type) {
 	case DPAA2_SEC_CIPHER:
 		ret = build_cipher_fd(sess, op, fd, bpid);
@@ -565,6 +608,9 @@ build_sec_fd(dpaa2_sec_session *sess, struct rte_crypto_op *op,
 	case DPAA2_SEC_CIPHER_HASH:
 		ret = build_authenc_fd(sess, op, fd, bpid);
 		break;
+	case DPAA2_SEC_IPSEC:
+		ret = build_proto_fd(sess, op, fd, bpid);
+		break;
 	case DPAA2_SEC_HASH_CIPHER:
 	default:
 		RTE_LOG(ERR, PMD, "error: Unsupported session\n");
@@ -588,12 +634,11 @@ dpaa2_sec_enqueue_burst(void *qp, struct rte_crypto_op **ops,
 	/*todo - need to support multiple buffer pools */
 	uint16_t bpid;
 	struct rte_mempool *mb_pool;
-	dpaa2_sec_session *sess;
 
 	if (unlikely(nb_ops == 0))
 		return 0;
 
-	if (ops[0]->sess_type != RTE_CRYPTO_OP_WITH_SESSION) {
+	if (ops[0]->sess_type == RTE_CRYPTO_OP_SESSIONLESS) {
 		RTE_LOG(ERR, PMD, "sessionless crypto op not supported\n");
 		return 0;
 	}
@@ -618,13 +663,9 @@ dpaa2_sec_enqueue_burst(void *qp, struct rte_crypto_op **ops,
 		for (loop = 0; loop < frames_to_send; loop++) {
 			/*Clear the unused FD fields before sending*/
 			memset(&fd_arr[loop], 0, sizeof(struct qbman_fd));
-			sess = (dpaa2_sec_session *)
-					get_session_private_data(
-					(*ops)->sym->session,
-					cryptodev_driver_id);
 			mb_pool = (*ops)->sym->m_src->pool;
 			bpid = mempool_to_bpid(mb_pool);
-			ret = build_sec_fd(sess, *ops, &fd_arr[loop], bpid);
+			ret = build_sec_fd(*ops, &fd_arr[loop], bpid);
 			if (ret) {
 				PMD_DRV_LOG(ERR, "error: Improper packet"
 					    " contents for crypto operation\n");
@@ -649,12 +690,44 @@ dpaa2_sec_enqueue_burst(void *qp, struct rte_crypto_op **ops,
 }
 
 static inline struct rte_crypto_op *
-sec_fd_to_mbuf(const struct qbman_fd *fd)
+sec_simple_fd_to_mbuf(const struct qbman_fd *fd, __rte_unused uint8_t id)
+{
+	struct rte_crypto_op *op;
+	uint16_t len = DPAA2_GET_FD_LEN(fd);
+	uint16_t diff = 0;
+	dpaa2_sec_session *sess_priv;
+
+	struct rte_mbuf *mbuf = DPAA2_INLINE_MBUF_FROM_BUF(
+		DPAA2_IOVA_TO_VADDR(DPAA2_GET_FD_ADDR(fd)),
+		rte_dpaa2_bpid_info[DPAA2_GET_FD_BPID(fd)].meta_data_size);
+
+	op = (struct rte_crypto_op *)mbuf->buf_physaddr;
+	mbuf->buf_physaddr = op->sym->aead.digest.phys_addr;
+	op->sym->aead.digest.phys_addr = 0L;
+
+	sess_priv = (dpaa2_sec_session *)get_sec_session_private_data(
+				op->sym->sec_session);
+	if (sess_priv->dir == DIR_ENC)
+		mbuf->data_off += SEC_FLC_DHR_OUTBOUND;
+	else
+		mbuf->data_off += SEC_FLC_DHR_INBOUND;
+	diff = len - mbuf->pkt_len;
+	mbuf->pkt_len += diff;
+	mbuf->data_len += diff;
+
+	return op;
+}
+
+static inline struct rte_crypto_op *
+sec_fd_to_mbuf(const struct qbman_fd *fd, uint8_t driver_id)
 {
 	struct qbman_fle *fle;
 	struct rte_crypto_op *op;
 	struct ctxt_priv *priv;
 
+	if (DPAA2_FD_GET_FORMAT(fd) == qbman_fd_single)
+		return sec_simple_fd_to_mbuf(fd, driver_id);
+
 	fle = (struct qbman_fle *)DPAA2_IOVA_TO_VADDR(DPAA2_GET_FD_ADDR(fd));
 
 	PMD_RX_LOG(DEBUG, "FLE addr = %x - %x, offset = %x",
@@ -701,6 +774,8 @@ dpaa2_sec_dequeue_burst(void *qp, struct rte_crypto_op **ops,
 {
 	/* Function is responsible to receive frames for a given device and VQ*/
 	struct dpaa2_sec_qp *dpaa2_qp = (struct dpaa2_sec_qp *)qp;
+	struct rte_cryptodev *dev =
+			(struct rte_cryptodev *)(dpaa2_qp->rx_vq.dev);
 	struct qbman_result *dq_storage;
 	uint32_t fqid = dpaa2_qp->rx_vq.fqid;
 	int ret, num_rx = 0;
@@ -770,7 +845,7 @@ dpaa2_sec_dequeue_burst(void *qp, struct rte_crypto_op **ops,
 		}
 
 		fd = qbman_result_DQ_fd(dq_storage);
-		ops[num_rx] = sec_fd_to_mbuf(fd);
+		ops[num_rx] = sec_fd_to_mbuf(fd, dev->driver_id);
 
 		if (unlikely(fd->simple.frc)) {
 			/* TODO Parse SEC errors */
@@ -1547,6 +1622,300 @@ dpaa2_sec_set_session_parameters(struct rte_cryptodev *dev,
 }
 
 static int
+dpaa2_sec_set_ipsec_session(struct rte_cryptodev *dev,
+			    struct rte_security_session_conf *conf,
+			    void *sess)
+{
+	struct rte_security_ipsec_xform *ipsec_xform = &conf->ipsec;
+	struct rte_crypto_auth_xform *auth_xform;
+	struct rte_crypto_cipher_xform *cipher_xform;
+	dpaa2_sec_session *session = (dpaa2_sec_session *)sess;
+	struct ctxt_priv *priv;
+	struct ipsec_encap_pdb encap_pdb;
+	struct ipsec_decap_pdb decap_pdb;
+	struct alginfo authdata, cipherdata;
+	unsigned int bufsize;
+	struct sec_flow_context *flc;
+
+	PMD_INIT_FUNC_TRACE();
+
+	if (ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) {
+		cipher_xform = &conf->crypto_xform->cipher;
+		auth_xform = &conf->crypto_xform->next->auth;
+	} else {
+		auth_xform = &conf->crypto_xform->auth;
+		cipher_xform = &conf->crypto_xform->next->cipher;
+	}
+	priv = (struct ctxt_priv *)rte_zmalloc(NULL,
+				sizeof(struct ctxt_priv) +
+				sizeof(struct sec_flc_desc),
+				RTE_CACHE_LINE_SIZE);
+
+	if (priv == NULL) {
+		RTE_LOG(ERR, PMD, "\nNo memory for priv CTXT");
+		return -ENOMEM;
+	}
+
+	flc = &priv->flc_desc[0].flc;
+
+	session->ctxt_type = DPAA2_SEC_IPSEC;
+	session->cipher_key.data = rte_zmalloc(NULL,
+					       cipher_xform->key.length,
+					       RTE_CACHE_LINE_SIZE);
+	if (session->cipher_key.data == NULL &&
+			cipher_xform->key.length > 0) {
+		RTE_LOG(ERR, PMD, "No Memory for cipher key\n");
+		rte_free(priv);
+		return -ENOMEM;
+	}
+
+	session->cipher_key.length = cipher_xform->key.length;
+	session->auth_key.data = rte_zmalloc(NULL,
+					auth_xform->key.length,
+					RTE_CACHE_LINE_SIZE);
+	if (session->auth_key.data == NULL &&
+			auth_xform->key.length > 0) {
+		RTE_LOG(ERR, PMD, "No Memory for auth key\n");
+		rte_free(session->cipher_key.data);
+		rte_free(priv);
+		return -ENOMEM;
+	}
+	session->auth_key.length = auth_xform->key.length;
+	memcpy(session->cipher_key.data, cipher_xform->key.data,
+			cipher_xform->key.length);
+	memcpy(session->auth_key.data, auth_xform->key.data,
+			auth_xform->key.length);
+
+	authdata.key = (uint64_t)session->auth_key.data;
+	authdata.keylen = session->auth_key.length;
+	authdata.key_enc_flags = 0;
+	authdata.key_type = RTA_DATA_IMM;
+	switch (auth_xform->algo) {
+	case RTE_CRYPTO_AUTH_SHA1_HMAC:
+		authdata.algtype = OP_PCL_IPSEC_HMAC_SHA1_96;
+		authdata.algmode = OP_ALG_AAI_HMAC;
+		session->auth_alg = RTE_CRYPTO_AUTH_SHA1_HMAC;
+		break;
+	case RTE_CRYPTO_AUTH_MD5_HMAC:
+		authdata.algtype = OP_PCL_IPSEC_HMAC_MD5_96;
+		authdata.algmode = OP_ALG_AAI_HMAC;
+		session->auth_alg = RTE_CRYPTO_AUTH_MD5_HMAC;
+		break;
+	case RTE_CRYPTO_AUTH_SHA256_HMAC:
+		authdata.algtype = OP_PCL_IPSEC_HMAC_SHA2_256_128;
+		authdata.algmode = OP_ALG_AAI_HMAC;
+		session->auth_alg = RTE_CRYPTO_AUTH_SHA256_HMAC;
+		break;
+	case RTE_CRYPTO_AUTH_SHA384_HMAC:
+		authdata.algtype = OP_PCL_IPSEC_HMAC_SHA2_384_192;
+		authdata.algmode = OP_ALG_AAI_HMAC;
+		session->auth_alg = RTE_CRYPTO_AUTH_SHA384_HMAC;
+		break;
+	case RTE_CRYPTO_AUTH_SHA512_HMAC:
+		authdata.algtype = OP_PCL_IPSEC_HMAC_SHA2_512_256;
+		authdata.algmode = OP_ALG_AAI_HMAC;
+		session->auth_alg = RTE_CRYPTO_AUTH_SHA512_HMAC;
+		break;
+	case RTE_CRYPTO_AUTH_AES_CMAC:
+		authdata.algtype = OP_PCL_IPSEC_AES_CMAC_96;
+		session->auth_alg = RTE_CRYPTO_AUTH_AES_CMAC;
+		break;
+	case RTE_CRYPTO_AUTH_NULL:
+		authdata.algtype = OP_PCL_IPSEC_HMAC_NULL;
+		session->auth_alg = RTE_CRYPTO_AUTH_NULL;
+		break;
+	case RTE_CRYPTO_AUTH_SHA224_HMAC:
+	case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
+	case RTE_CRYPTO_AUTH_SNOW3G_UIA2:
+	case RTE_CRYPTO_AUTH_SHA1:
+	case RTE_CRYPTO_AUTH_SHA256:
+	case RTE_CRYPTO_AUTH_SHA512:
+	case RTE_CRYPTO_AUTH_SHA224:
+	case RTE_CRYPTO_AUTH_SHA384:
+	case RTE_CRYPTO_AUTH_MD5:
+	case RTE_CRYPTO_AUTH_AES_GMAC:
+	case RTE_CRYPTO_AUTH_KASUMI_F9:
+	case RTE_CRYPTO_AUTH_AES_CBC_MAC:
+	case RTE_CRYPTO_AUTH_ZUC_EIA3:
+		RTE_LOG(ERR, PMD, "Crypto: Unsupported auth alg %u\n",
+			auth_xform->algo);
+		goto out;
+	default:
+		RTE_LOG(ERR, PMD, "Crypto: Undefined Auth specified %u\n",
+			auth_xform->algo);
+		goto out;
+	}
+	cipherdata.key = (uint64_t)session->cipher_key.data;
+	cipherdata.keylen = session->cipher_key.length;
+	cipherdata.key_enc_flags = 0;
+	cipherdata.key_type = RTA_DATA_IMM;
+
+	switch (cipher_xform->algo) {
+	case RTE_CRYPTO_CIPHER_AES_CBC:
+		cipherdata.algtype = OP_PCL_IPSEC_AES_CBC;
+		cipherdata.algmode = OP_ALG_AAI_CBC;
+		session->cipher_alg = RTE_CRYPTO_CIPHER_AES_CBC;
+		break;
+	case RTE_CRYPTO_CIPHER_3DES_CBC:
+		cipherdata.algtype = OP_PCL_IPSEC_3DES;
+		cipherdata.algmode = OP_ALG_AAI_CBC;
+		session->cipher_alg = RTE_CRYPTO_CIPHER_3DES_CBC;
+		break;
+	case RTE_CRYPTO_CIPHER_AES_CTR:
+		cipherdata.algtype = OP_PCL_IPSEC_AES_CTR;
+		cipherdata.algmode = OP_ALG_AAI_CTR;
+		session->cipher_alg = RTE_CRYPTO_CIPHER_AES_CTR;
+		break;
+	case RTE_CRYPTO_CIPHER_NULL:
+		cipherdata.algtype = OP_PCL_IPSEC_NULL;
+		break;
+	case RTE_CRYPTO_CIPHER_SNOW3G_UEA2:
+	case RTE_CRYPTO_CIPHER_3DES_ECB:
+	case RTE_CRYPTO_CIPHER_AES_ECB:
+	case RTE_CRYPTO_CIPHER_KASUMI_F8:
+		RTE_LOG(ERR, PMD, "Crypto: Unsupported Cipher alg %u\n",
+			cipher_xform->algo);
+		goto out;
+	default:
+		RTE_LOG(ERR, PMD, "Crypto: Undefined Cipher specified %u\n",
+			cipher_xform->algo);
+		goto out;
+	}
+
+	if (ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) {
+		struct ip ip4_hdr;
+
+		flc->dhr = SEC_FLC_DHR_OUTBOUND;
+		ip4_hdr.ip_v = IPVERSION;
+		ip4_hdr.ip_hl = 5;
+		ip4_hdr.ip_len = rte_cpu_to_be_16(sizeof(ip4_hdr));
+		ip4_hdr.ip_tos = ipsec_xform->tunnel.ipv4.dscp;
+		ip4_hdr.ip_id = 0;
+		ip4_hdr.ip_off = 0;
+		ip4_hdr.ip_ttl = ipsec_xform->tunnel.ipv4.ttl;
+		ip4_hdr.ip_p = 0x32;
+		ip4_hdr.ip_sum = 0;
+		ip4_hdr.ip_src = ipsec_xform->tunnel.ipv4.src_ip;
+		ip4_hdr.ip_dst = ipsec_xform->tunnel.ipv4.dst_ip;
+		ip4_hdr.ip_sum = calc_chksum((uint16_t *)(void *)&ip4_hdr,
+			sizeof(struct ip));
+
+		/* For Sec Proto only one descriptor is required. */
+		memset(&encap_pdb, 0, sizeof(struct ipsec_encap_pdb));
+		encap_pdb.options = (IPVERSION << PDBNH_ESP_ENCAP_SHIFT) |
+			PDBOPTS_ESP_OIHI_PDB_INL |
+			PDBOPTS_ESP_IVSRC |
+			PDBHMO_ESP_ENCAP_DTTL;
+		encap_pdb.spi = ipsec_xform->spi;
+		encap_pdb.ip_hdr_len = sizeof(struct ip);
+
+		session->dir = DIR_ENC;
+		bufsize = cnstr_shdsc_ipsec_new_encap(priv->flc_desc[0].desc,
+				1, 0, &encap_pdb,
+				(uint8_t *)&ip4_hdr,
+				&cipherdata, &authdata);
+	} else if (ipsec_xform->direction ==
+			RTE_SECURITY_IPSEC_SA_DIR_INGRESS) {
+		flc->dhr = SEC_FLC_DHR_INBOUND;
+		memset(&decap_pdb, 0, sizeof(struct ipsec_decap_pdb));
+		decap_pdb.options = sizeof(struct ip) << 16;
+		session->dir = DIR_DEC;
+		bufsize = cnstr_shdsc_ipsec_new_decap(priv->flc_desc[0].desc,
+				1, 0, &decap_pdb, &cipherdata, &authdata);
+	} else
+		goto out;
+	flc->word1_sdl = (uint8_t)bufsize;
+
+	/* Enable the stashing control bit */
+	DPAA2_SET_FLC_RSC(flc);
+	flc->word2_rflc_31_0 = lower_32_bits(
+			(uint64_t)&(((struct dpaa2_sec_qp *)
+			dev->data->queue_pairs[0])->rx_vq) | 0x14);
+	flc->word3_rflc_63_32 = upper_32_bits(
+			(uint64_t)&(((struct dpaa2_sec_qp *)
+			dev->data->queue_pairs[0])->rx_vq));
+
+	/* Set EWS bit i.e. enable write-safe */
+	DPAA2_SET_FLC_EWS(flc);
+	/* Set BS = 1 i.e reuse input buffers as output buffers */
+	DPAA2_SET_FLC_REUSE_BS(flc);
+	/* Set FF = 10; reuse input buffers if they provide sufficient space */
+	DPAA2_SET_FLC_REUSE_FF(flc);
+
+	session->ctxt = priv;
+
+	return 0;
+out:
+	rte_free(session->auth_key.data);
+	rte_free(session->cipher_key.data);
+	rte_free(priv);
+	return -1;
+}
+
+static int
+dpaa2_sec_security_session_create(void *dev,
+				  struct rte_security_session_conf *conf,
+				  struct rte_security_session *sess,
+				  struct rte_mempool *mempool)
+{
+	void *sess_private_data;
+	struct rte_cryptodev *cdev = (struct rte_cryptodev *)dev;
+	int ret;
+
+	if (rte_mempool_get(mempool, &sess_private_data)) {
+		CDEV_LOG_ERR(
+			"Couldn't get object from session mempool");
+		return -ENOMEM;
+	}
+
+	switch (conf->protocol) {
+	case RTE_SECURITY_PROTOCOL_IPSEC:
+		ret = dpaa2_sec_set_ipsec_session(cdev, conf,
+				sess_private_data);
+		break;
+	case RTE_SECURITY_PROTOCOL_MACSEC:
+		return -ENOTSUP;
+	default:
+		return -EINVAL;
+	}
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR,
+			"DPAA2 PMD: failed to configure session parameters");
+
+		/* Return session to mempool */
+		rte_mempool_put(mempool, sess_private_data);
+		return ret;
+	}
+
+	set_sec_session_private_data(sess, sess_private_data);
+
+	return ret;
+}
+
+/** Clear the memory of session so it doesn't leave key material behind */
+static int
+dpaa2_sec_security_session_destroy(void *dev __rte_unused,
+		struct rte_security_session *sess)
+{
+	PMD_INIT_FUNC_TRACE();
+	void *sess_priv = get_sec_session_private_data(sess);
+
+	dpaa2_sec_session *s = (dpaa2_sec_session *)sess_priv;
+
+	if (sess_priv) {
+		struct rte_mempool *sess_mp = rte_mempool_from_obj(sess_priv);
+
+		rte_free(s->ctxt);
+		rte_free(s->cipher_key.data);
+		rte_free(s->auth_key.data);
+		memset(sess, 0, sizeof(dpaa2_sec_session));
+		set_sec_session_private_data(sess, NULL);
+		rte_mempool_put(sess_mp, sess_priv);
+	}
+	return 0;
+}
+
+static int
 dpaa2_sec_session_configure(struct rte_cryptodev *dev,
 		struct rte_crypto_sym_xform *xform,
 		struct rte_cryptodev_sym_session *sess,
@@ -1820,11 +2189,28 @@ static struct rte_cryptodev_ops crypto_ops = {
 	.session_clear        = dpaa2_sec_session_clear,
 };
 
+static const struct rte_security_capability *
+dpaa2_sec_capabilities_get(void *device __rte_unused)
+{
+	return dpaa2_sec_security_cap;
+}
+
+struct rte_security_ops dpaa2_sec_security_ops = {
+	.session_create = dpaa2_sec_security_session_create,
+	.session_update = NULL,
+	.session_stats_get = NULL,
+	.session_destroy = dpaa2_sec_security_session_destroy,
+	.set_pkt_metadata = NULL,
+	.capabilities_get = dpaa2_sec_capabilities_get
+};
+
 static int
 dpaa2_sec_uninit(const struct rte_cryptodev *dev)
 {
 	struct dpaa2_sec_dev_private *internals = dev->data->dev_private;
 
+	rte_free(dev->data->security_ctx);
+
 	rte_mempool_free(internals->fle_pool);
 
 	PMD_INIT_LOG(INFO, "Closing DPAA2_SEC device %s on numa socket %u\n",
@@ -1839,6 +2225,7 @@ dpaa2_sec_dev_init(struct rte_cryptodev *cryptodev)
 	struct dpaa2_sec_dev_private *internals;
 	struct rte_device *dev = cryptodev->device;
 	struct rte_dpaa2_device *dpaa2_dev;
+	struct rte_security_ctx *security_instance;
 	struct fsl_mc_io *dpseci;
 	uint16_t token;
 	struct dpseci_attr attr;
@@ -1855,12 +2242,23 @@ dpaa2_sec_dev_init(struct rte_cryptodev *cryptodev)
 
 	cryptodev->driver_id = cryptodev_driver_id;
 	cryptodev->dev_ops = &crypto_ops;
+	security_instance = rte_malloc("rte_security_instances_ops",
+				sizeof(struct rte_security_ctx), 0);
+	if (security_instance == NULL)
+		return -ENOMEM;
+	security_instance->state = RTE_SECURITY_INSTANCE_VALID;
+	security_instance->device = (void *)cryptodev;
+	security_instance->ops = &dpaa2_sec_security_ops;
+	security_instance->sess_cnt = 0;
+
+	cryptodev->data->security_ctx = security_instance;
 
 	cryptodev->enqueue_burst = dpaa2_sec_enqueue_burst;
 	cryptodev->dequeue_burst = dpaa2_sec_dequeue_burst;
 	cryptodev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
 			RTE_CRYPTODEV_FF_HW_ACCELERATED |
-			RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING;
+			RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
+			RTE_CRYPTODEV_FF_SECURITY;
 
 	internals = cryptodev->data->dev_private;
 	internals->max_nb_sessions = RTE_DPAA2_SEC_PMD_MAX_NB_SESSIONS;
diff --git a/drivers/crypto/dpaa2_sec/dpaa2_sec_priv.h b/drivers/crypto/dpaa2_sec/dpaa2_sec_priv.h
index 3849a05..14e71df 100644
--- a/drivers/crypto/dpaa2_sec/dpaa2_sec_priv.h
+++ b/drivers/crypto/dpaa2_sec/dpaa2_sec_priv.h
@@ -67,6 +67,11 @@ enum shr_desc_type {
 #define DIR_ENC                 1
 #define DIR_DEC                 0
 
+#define DPAA2_SET_FLC_EWS(flc)  (flc->word1_bits23_16 |= 0x1)
+#define DPAA2_SET_FLC_RSC(flc)  (flc->word1_bits31_24 |= 0x1)
+#define DPAA2_SET_FLC_REUSE_BS(flc) (flc->mode_bits |= 0x8000)
+#define DPAA2_SET_FLC_REUSE_FF(flc) (flc->mode_bits |= 0x2000)
+
 /* SEC Flow Context Descriptor */
 struct sec_flow_context {
 	/* word 0 */
@@ -411,4 +416,61 @@ static const struct rte_cryptodev_capabilities dpaa2_sec_capabilities[] = {
 
 	RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
 };
+
+static const struct rte_security_capability dpaa2_sec_security_cap[] = {
+	{ /* IPsec Lookaside Protocol offload ESP Transport Egress */
+		.action = RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL,
+		.protocol = RTE_SECURITY_PROTOCOL_IPSEC,
+		.ipsec = {
+			.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP,
+			.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL,
+			.direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS,
+			.options = { 0 }
+		},
+		.crypto_capabilities = dpaa2_sec_capabilities
+	},
+	{ /* IPsec Lookaside Protocol offload ESP Tunnel Ingress */
+		.action = RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL,
+		.protocol = RTE_SECURITY_PROTOCOL_IPSEC,
+		.ipsec = {
+			.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP,
+			.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL,
+			.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS,
+			.options = { 0 }
+		},
+		.crypto_capabilities = dpaa2_sec_capabilities
+	},
+	{
+		.action = RTE_SECURITY_ACTION_TYPE_NONE
+	}
+};
+
+/**
+ * Checksum
+ *
+ * @param buffer calculate chksum for buffer
+ * @param len    buffer length
+ *
+ * @return checksum value in host cpu order
+ */
+static inline uint16_t
+calc_chksum(void *buffer, int len)
+{
+	uint16_t *buf = (uint16_t *)buffer;
+	uint32_t sum = 0;
+	uint16_t result;
+
+	for (sum = 0; len > 1; len -= 2)
+		sum += *buf++;
+
+	if (len == 1)
+		sum += *(unsigned char *)buf;
+
+	sum = (sum >> 16) + (sum & 0xFFFF);
+	sum += (sum >> 16);
+	result = ~sum;
+
+	return  result;
+}
+
 #endif /* _RTE_DPAA2_SEC_PMD_PRIVATE_H_ */
-- 
2.9.3

  parent reply	other threads:[~2017-10-14 22:21 UTC|newest]

Thread overview: 195+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-09-14  8:26 [PATCH 00/11] introduce security offload library Akhil Goyal
2017-09-14  8:26 ` [PATCH 01/11] lib/rte_security: add security library Akhil Goyal
2017-09-15  5:32   ` Hemant Agrawal
2017-09-17 13:31     ` Boris Pismenny
2017-09-20 11:35     ` Akhil Goyal
2017-09-18 13:13   ` Jerin Jacob
2017-09-22 11:55     ` Radu Nicolau
2017-09-14  8:26 ` [PATCH 02/11] doc: add details of rte security Akhil Goyal
2017-09-18 11:13   ` Jerin Jacob
2017-09-20 10:59     ` Akhil Goyal
2017-09-18 15:38   ` Mcnamara, John
2017-09-20 11:00     ` Akhil Goyal
2017-09-14  8:26 ` [PATCH 03/11] cryptodev: extend cryptodev to support security APIs Akhil Goyal
2017-09-14  8:26 ` [PATCH 04/11] lib/librte_net: add ESP header to generic flow steering Akhil Goyal
2017-09-15  4:51   ` Hemant Agrawal
2017-09-17  7:19     ` Boris Pismenny
2017-09-14  8:26 ` [PATCH 05/11] lib/librte_mbuf: add security crypto flags and mbuf fields Akhil Goyal
2017-09-18  7:54   ` Boris Pismenny
2017-09-20  9:43     ` Olivier MATZ
2017-09-26 10:19       ` Boris Pismenny
2017-09-14  8:26 ` [PATCH 06/11] ethdev: extend ethdev to support security APIs Akhil Goyal
2017-09-17 13:45   ` Shahaf Shuler
2017-09-22 11:42     ` Radu Nicolau
2017-09-18  7:57   ` Jerin Jacob
2017-09-22 11:49     ` Radu Nicolau
2017-09-14  8:26 ` [PATCH 07/11] ethdev: add rte flow action for crypto Akhil Goyal
2017-09-21  9:16   ` Jerin Jacob
2017-09-21 16:53     ` Boris Pismenny
2017-09-14  8:26 ` [PATCH 08/11] mk: add rte security into build system Akhil Goyal
2017-09-14  8:26 ` [PATCH 09/11] net/ixgbe: enable inline ipsec Akhil Goyal
2017-09-15  4:48   ` Hemant Agrawal
2017-09-15 13:14     ` Doherty, Declan
2017-09-14  8:26 ` [PATCH 10/11] crypto/dpaa2_sec: add support for protocol offload ipsec Akhil Goyal
2017-09-14  8:26 ` [PATCH 11/11] examples/ipsec-secgw: add support for security offload Akhil Goyal
2017-10-03 13:14 ` [PATCH v2 00/12] introduce security offload library Akhil Goyal
2017-10-03 13:14   ` [PATCH v2 01/12] lib/rte_security: add security library Akhil Goyal
2017-10-05 15:32     ` De Lara Guarch, Pablo
2017-10-05 16:30     ` Ananyev, Konstantin
2017-10-06 18:11       ` Akhil Goyal
2017-10-09 13:42         ` Ananyev, Konstantin
2017-10-10 12:17           ` Akhil Goyal
2017-10-11  9:02             ` Ananyev, Konstantin
2017-10-03 13:14   ` [PATCH v2 02/12] doc: add details of rte security Akhil Goyal
2017-10-03 15:56     ` Mcnamara, John
2017-10-03 13:14   ` [PATCH v2 03/12] cryptodev: extend cryptodev to support security APIs Akhil Goyal
2017-10-05  8:49     ` De Lara Guarch, Pablo
2017-10-03 13:14   ` [PATCH v2 04/12] lib/librte_net: add ESP header to generic flow steering Akhil Goyal
2017-10-03 13:14   ` [PATCH v2 05/12] lib/librte_mbuf: add security crypto flags and mbuf fields Akhil Goyal
2017-10-05  8:54     ` De Lara Guarch, Pablo
2017-10-03 13:14   ` [PATCH v2 06/12] ethdev: extend ethdev to support security APIs Akhil Goyal
2017-10-04 10:52     ` Shahaf Shuler
2017-10-06 16:31       ` Radu Nicolau
2017-10-05 18:01     ` Ananyev, Konstantin
2017-10-03 13:14   ` [PATCH v2 07/12] ethdev: add rte flow action for crypto Akhil Goyal
2017-10-03 13:14   ` [PATCH v2 08/12] doc: add details of rte_flow security actions Akhil Goyal
2017-10-03 15:38     ` Mcnamara, John
2017-10-03 15:39       ` Mcnamara, John
2017-10-05 15:34     ` De Lara Guarch, Pablo
2017-10-03 13:14   ` [PATCH v2 09/12] mk: add rte security into build system Akhil Goyal
2017-10-03 13:14   ` [PATCH v2 10/12] net/ixgbe: enable inline ipsec Akhil Goyal
2017-10-05 17:55     ` Ananyev, Konstantin
2017-10-06  9:17       ` Radu Nicolau
2017-10-06 18:33         ` Ananyev, Konstantin
2017-10-10 16:10           ` Radu Nicolau
2017-10-03 13:14   ` [PATCH v2 11/12] crypto/dpaa2_sec: add support for protocol offload ipsec Akhil Goyal
2017-10-05  9:13     ` De Lara Guarch, Pablo
2017-10-03 13:14   ` [PATCH v2 12/12] examples/ipsec-secgw: add support for security offload Akhil Goyal
2017-10-06 18:11   ` [PATCH v3 00/12] introduce security offload library Akhil Goyal
2017-10-06 18:11     ` [PATCH v3 01/12] lib/rte_security: add security library Akhil Goyal
2017-10-06 18:11     ` [PATCH v3 02/12] doc: add details of rte security Akhil Goyal
2017-10-06 18:11     ` [PATCH v3 03/12] cryptodev: support security APIs Akhil Goyal
2017-10-10 13:43       ` De Lara Guarch, Pablo
2017-10-21 15:22         ` Akhil Goyal
2017-10-06 18:11     ` [PATCH v3 04/12] net: add ESP header to generic flow steering Akhil Goyal
2017-10-06 18:11     ` [PATCH v3 05/12] mbuf: add security crypto flags and mbuf fields Akhil Goyal
2017-10-06 18:11     ` [PATCH v3 06/12] ethdev: support security APIs Akhil Goyal
2017-10-06 18:11     ` [PATCH v3 07/12] ethdev: add rte flow action for crypto Akhil Goyal
2017-10-06 18:11     ` [PATCH v3 08/12] doc: add details of rte_flow security actions Akhil Goyal
2017-10-12 13:41       ` Mcnamara, John
2017-10-06 18:11     ` [PATCH v3 09/12] mk: add rte security into build system Akhil Goyal
2017-10-06 18:11     ` [PATCH v3 10/12] net/ixgbe: enable inline ipsec Akhil Goyal
2017-10-06 18:11     ` [PATCH v3 11/12] crypto/dpaa2_sec: add support for protocol offload ipsec Akhil Goyal
2017-10-06 18:11     ` [PATCH v3 12/12] examples/ipsec-secgw: add support for security offload Akhil Goyal
2017-10-09 13:49     ` [PATCH v3 00/12] introduce security offload library Ananyev, Konstantin
2017-10-10 12:22       ` Akhil Goyal
2017-10-14 22:17     ` [PATCH v4 " Akhil Goyal
2017-10-14 22:17       ` [PATCH v4 01/12] lib/rte_security: add security library Akhil Goyal
2017-10-15 12:47         ` Aviad Yehezkel
2017-10-19  9:30         ` Ananyev, Konstantin
2017-10-21 15:54           ` Akhil Goyal
2017-10-20  9:37         ` Thomas Monjalon
2017-10-20  9:39           ` Thomas Monjalon
2017-10-21 19:46             ` Akhil Goyal
2017-10-21 19:45           ` Akhil Goyal
2017-10-14 22:17       ` [PATCH v4 02/12] doc: add details of rte security Akhil Goyal
2017-10-15 12:47         ` Aviad Yehezkel
2017-10-20  9:41         ` Thomas Monjalon
2017-10-21 19:48           ` Akhil Goyal
2017-10-14 22:17       ` [PATCH v4 03/12] cryptodev: support security APIs Akhil Goyal
2017-10-15 12:48         ` Aviad Yehezkel
2017-10-14 22:17       ` [PATCH v4 04/12] net: add ESP header to generic flow steering Akhil Goyal
2017-10-15 12:48         ` Aviad Yehezkel
2017-10-20 10:15         ` Thomas Monjalon
2017-10-21 19:49           ` Akhil Goyal
2017-10-14 22:17       ` [PATCH v4 05/12] mbuf: add security crypto flags and mbuf fields Akhil Goyal
2017-10-15 12:49         ` Aviad Yehezkel
2017-10-14 22:17       ` [PATCH v4 06/12] ethdev: support security APIs Akhil Goyal
2017-10-15 12:49         ` Aviad Yehezkel
2017-10-15 13:13         ` Shahaf Shuler
2017-10-16  8:46           ` Nicolau, Radu
2017-10-19  9:23         ` Ananyev, Konstantin
2017-10-21 16:00           ` Akhil Goyal
2017-10-23  9:56             ` Ananyev, Konstantin
2017-10-23 13:08               ` Nicolau, Radu
2017-10-20 10:58         ` Thomas Monjalon
2017-10-21 19:50           ` Akhil Goyal
2017-10-14 22:17       ` [PATCH v4 07/12] ethdev: add rte flow action for crypto Akhil Goyal
2017-10-15 12:49         ` Aviad Yehezkel
2017-10-14 22:17       ` [PATCH v4 08/12] doc: add details of rte_flow security actions Akhil Goyal
2017-10-15 12:50         ` Aviad Yehezkel
2017-10-16 19:17         ` Mcnamara, John
2017-10-20 11:00         ` Thomas Monjalon
2017-10-21 19:50           ` Akhil Goyal
2017-10-14 22:17       ` [PATCH v4 09/12] mk: add rte security into build system Akhil Goyal
2017-10-15 12:50         ` Aviad Yehezkel
2017-10-20 11:06         ` Thomas Monjalon
2017-10-21 19:44           ` Akhil Goyal
2017-10-14 22:17       ` [PATCH v4 10/12] net/ixgbe: enable inline ipsec Akhil Goyal
2017-10-15 12:51         ` Aviad Yehezkel
2017-10-16 10:41           ` Thomas Monjalon
2017-10-18 21:29         ` Ananyev, Konstantin
2017-10-19 10:51           ` Radu Nicolau
2017-10-19 11:04             ` Ananyev, Konstantin
2017-10-19 11:57               ` Nicolau, Radu
2017-10-19 12:16                 ` Ananyev, Konstantin
2017-10-19 12:29                   ` Ananyev, Konstantin
2017-10-19 13:14                     ` Radu Nicolau
2017-10-19 13:22                       ` Ananyev, Konstantin
2017-10-19 14:19                         ` Nicolau, Radu
2017-10-19 14:36                           ` Ananyev, Konstantin
2017-10-19 13:09                   ` Radu Nicolau
2017-10-19  9:04         ` Ananyev, Konstantin
2017-10-14 22:17       ` Akhil Goyal [this message]
2017-10-14 22:17       ` [PATCH v4 12/12] examples/ipsec-secgw: add support for security offload Akhil Goyal
2017-10-15 12:51         ` Aviad Yehezkel
2017-10-16 10:44       ` [PATCH v4 00/12] introduce security offload library Thomas Monjalon
2017-10-20  9:32         ` Thomas Monjalon
2017-10-21 16:13           ` Akhil Goyal
2017-10-22 20:37             ` Akhil Goyal
2017-10-22 20:59               ` Thomas Monjalon
2017-10-23 11:44                 ` Aviad Yehezkel
2017-10-24  9:41                 ` Akhil Goyal
2017-10-24  9:52                   ` Thomas Monjalon
2017-10-24 14:27                     ` Akhil Goyal
2017-10-24 14:15       ` [PATCH v5 00/11] " Akhil Goyal
2017-10-24 14:15         ` [PATCH v5 01/11] lib/rte_security: add security library Akhil Goyal
2017-10-24 15:15           ` De Lara Guarch, Pablo
2017-10-25 11:06             ` Akhil Goyal
2017-10-24 20:47           ` Thomas Monjalon
2017-10-25 11:08             ` Akhil Goyal
2017-10-25  5:13           ` Hemant Agrawal
2017-10-24 14:15         ` [PATCH v5 02/11] doc: add details of rte security Akhil Goyal
2017-10-24 14:15         ` [PATCH v5 03/11] cryptodev: support security APIs Akhil Goyal
2017-10-24 14:15         ` [PATCH v5 04/11] net: add ESP header to generic flow steering Akhil Goyal
2017-10-24 14:15         ` [PATCH v5 05/11] mbuf: add security crypto flags and mbuf fields Akhil Goyal
2017-10-25  9:38           ` Olivier MATZ
2017-10-25 12:05             ` Akhil Goyal
2017-10-24 14:15         ` [PATCH v5 06/11] ethdev: support security APIs Akhil Goyal
2017-10-25  5:05           ` Hemant Agrawal
2017-10-25  7:01           ` Shahaf Shuler
2017-10-25 12:35             ` Aviad Yehezkel
2017-10-24 14:15         ` [PATCH v5 07/11] ethdev: add rte flow action for crypto Akhil Goyal
2017-10-24 14:15         ` [PATCH v5 08/11] mk: add rte security into build system Akhil Goyal
2017-10-24 20:48           ` Thomas Monjalon
2017-10-25 11:12             ` Akhil Goyal
2017-10-25  5:04           ` Hemant Agrawal
2017-10-24 14:15         ` [PATCH v5 09/11] net/ixgbe: enable inline ipsec Akhil Goyal
2017-10-24 14:15         ` [PATCH v5 10/11] crypto/dpaa2_sec: add support for protocol offload ipsec Akhil Goyal
2017-10-24 14:15         ` [PATCH v5 11/11] examples/ipsec-secgw: add support for security offload Akhil Goyal
2017-10-25 15:07         ` [PATCH v6 00/10] introduce security offload library Akhil Goyal
2017-10-25 15:07           ` [PATCH v6 01/10] cryptodev: support security APIs Akhil Goyal
2017-10-25 15:07           ` [PATCH v6 02/10] net: add ESP header to generic flow steering Akhil Goyal
2017-10-25 15:07           ` [PATCH v6 03/10] mbuf: add security crypto flags and mbuf fields Akhil Goyal
2017-10-25 15:07           ` [PATCH v6 04/10] ethdev: support security APIs Akhil Goyal
2017-10-25 15:07           ` [PATCH v6 05/10] ethdev: add rte flow action for crypto Akhil Goyal
2017-10-25 15:07           ` [PATCH v6 06/10] security: introduce security API and framework Akhil Goyal
2017-10-25 15:07           ` [PATCH v6 07/10] doc: add details of rte security Akhil Goyal
2017-10-25 15:07           ` [PATCH v6 08/10] net/ixgbe: enable inline ipsec Akhil Goyal
2017-10-26  7:09             ` David Marchand
2017-10-26  7:19               ` David Marchand
2017-11-01 19:58             ` Thomas Monjalon
2017-11-01 20:10               ` Ferruh Yigit
2017-10-25 15:07           ` [PATCH v6 09/10] crypto/dpaa2_sec: add support for protocol offload ipsec Akhil Goyal
2017-10-25 15:07           ` [PATCH v6 10/10] examples/ipsec-secgw: add support for security offload Akhil Goyal
2017-10-26  1:16           ` [PATCH v6 00/10] introduce security offload library Thomas Monjalon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20171014221734.15511-12-akhil.goyal@nxp.com \
    --to=akhil.goyal@nxp.com \
    --cc=aviadye@mellanox.com \
    --cc=borisp@mellanox.com \
    --cc=declan.doherty@intel.com \
    --cc=dev@dpdk.org \
    --cc=hemant.agrawal@nxp.com \
    --cc=jerin.jacob@caviumnetworks.com \
    --cc=john.mcnamara@intel.com \
    --cc=konstantin.ananyev@intel.com \
    --cc=olivier.matz@6wind.com \
    --cc=pablo.de.lara.guarch@intel.com \
    --cc=radu.nicolau@intel.com \
    --cc=sandeep.malik@nxp.com \
    --cc=shahafs@mellanox.com \
    --cc=thomas@monjalon.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.