summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBogdan Constantin Popescu <bogdan.c.popescu@freescale.com>2014-03-28 09:17:46 (GMT)
committerJose Rivera <German.Rivera@freescale.com>2014-03-28 16:17:28 (GMT)
commit0506e775d04d8f303f3ca3abfd18096f3c4f0df5 (patch)
tree987a1db5525e8fd55d9c0ed8ff409ddde07be966
parent14bc1055d1415408999b4ac1660a261daddd3b55 (diff)
downloadlinux-fsl-qoriq-0506e775d04d8f303f3ca3abfd18096f3c4f0df5.tar.xz
dpa_offload: dpa_ipsec - SEC outbound fqid for SA
This commit adds support for DPA IPSec functionality in order to get the frame queue id to SEC for a given outbound SA. This will allow the upper layer to bypass outbound policy lookup and directly apply IPSec encryption on a packet. Change-Id: I06203798f50d08aefff32a64c551890225dbcd62 Signed-off-by: Bogdan Constantin Popescu <bogdan.c.popescu@freescale.com> Reviewed-on: http://git.am.freescale.net:8181/10453 Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com> Reviewed-by: Marian-Cornel Chereji <marian.chereji@freescale.com> Reviewed-by: Jose Rivera <German.Rivera@freescale.com>
-rw-r--r--drivers/staging/fsl_dpa_offload/dpa_ipsec.c59
-rw-r--r--drivers/staging/fsl_dpa_offload/dpa_ipsec_ioctl.h8
-rw-r--r--drivers/staging/fsl_dpa_offload/wrp_dpa_ipsec.c31
-rw-r--r--include/linux/fsl_dpa_ipsec.h6
4 files changed, 104 insertions, 0 deletions
diff --git a/drivers/staging/fsl_dpa_offload/dpa_ipsec.c b/drivers/staging/fsl_dpa_offload/dpa_ipsec.c
index a257526..7b64293 100644
--- a/drivers/staging/fsl_dpa_offload/dpa_ipsec.c
+++ b/drivers/staging/fsl_dpa_offload/dpa_ipsec.c
@@ -5689,3 +5689,62 @@ out:
return 0;
}
EXPORT_SYMBOL(dpa_ipsec_sa_get_seq_number);
+
+int dpa_ipsec_sa_get_out_path(int sa_id, uint32_t *fqid)
+{
+ struct dpa_ipsec *dpa_ipsec;
+ struct dpa_ipsec_sa *sa;
+ int ret;
+
+ if (!fqid) {
+ log_err("Invalid fqid handle\n");
+ return -EINVAL;
+ }
+
+ if (!valid_sa_id(sa_id))
+ return -EINVAL;
+
+ dpa_ipsec = get_instance(sa_id_to_instance_id(sa_id));
+ ret = check_instance(dpa_ipsec);
+ if (unlikely(ret < 0))
+ return ret;
+
+ sa = get_sa_from_sa_id(dpa_ipsec, sa_id);
+ if (!sa) {
+ log_err("Invalid SA handle for SA %d\n", sa_id);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = mutex_trylock(&sa->lock);
+ if (ret == 0) {
+ log_err("SA %d is being used\n", sa_id);
+ ret = -EBUSY;
+ goto out;
+ }
+
+ if (!sa_in_use(sa)) {
+ log_err("SA %d is not in use\n", sa_id);
+ mutex_unlock(&sa->lock);
+ ret = -ENODEV;
+ goto out;
+ }
+
+ if (sa_is_inbound(sa)) {
+ log_err("Illegal to acquire the to SEC frame queue ID for inbound SA %d.\n",
+ sa_id);
+ mutex_unlock(&sa->lock);
+ ret = -EPERM;
+ goto out;
+ }
+
+ *fqid = qman_fq_fqid(sa->to_sec_fq);
+
+ mutex_unlock(&sa->lock);
+ ret = 0;
+out:
+ put_instance(dpa_ipsec);
+
+ return ret;
+}
+EXPORT_SYMBOL(dpa_ipsec_sa_get_out_path);
diff --git a/drivers/staging/fsl_dpa_offload/dpa_ipsec_ioctl.h b/drivers/staging/fsl_dpa_offload/dpa_ipsec_ioctl.h
index 9bf64f3..9d1da46 100644
--- a/drivers/staging/fsl_dpa_offload/dpa_ipsec_ioctl.h
+++ b/drivers/staging/fsl_dpa_offload/dpa_ipsec_ioctl.h
@@ -239,6 +239,11 @@ struct ioc_compat_dpa_ipsec_sa_modify_prm {
};
#endif
+struct ioc_dpa_ipsec_sa_get_out_path {
+ int sa_id; /* security association id */
+ uint32_t fqid; /* where to write the frame queue id number */
+};
+
#define DPA_IPSEC_IOC_MAGIC 0xee
#define DPA_IPSEC_IOC_INIT \
@@ -320,4 +325,7 @@ struct ioc_compat_dpa_ipsec_sa_modify_prm {
#define DPA_IPSEC_IOC_SA_GET_SEQ_NUMBER \
_IOWR(DPA_IPSEC_IOC_MAGIC, 15, struct ioc_dpa_ipsec_sa_get_seq_num)
+#define DPA_IPSEC_IOC_SA_GET_OUT_PATH \
+ _IOWR(DPA_IPSEC_IOC_MAGIC, 16, struct ioc_dpa_ipsec_sa_get_out_path)
+
#endif /* __DPA_IPSEC_IOCTL_H */
diff --git a/drivers/staging/fsl_dpa_offload/wrp_dpa_ipsec.c b/drivers/staging/fsl_dpa_offload/wrp_dpa_ipsec.c
index 4cc8ce4..f4b081f 100644
--- a/drivers/staging/fsl_dpa_offload/wrp_dpa_ipsec.c
+++ b/drivers/staging/fsl_dpa_offload/wrp_dpa_ipsec.c
@@ -1408,6 +1408,37 @@ free:
break;
}
+ case DPA_IPSEC_IOC_SA_GET_OUT_PATH: {
+ struct ioc_dpa_ipsec_sa_get_out_path prm;
+
+ if (copy_from_user(&prm,
+ (struct ioc_dpa_ipsec_sa_get_out_path *)args,
+ sizeof(prm))) {
+ log_err("Could not copy from user out_path params\n");
+ return -EINVAL;
+ }
+
+ if (prm.sa_id < 0) {
+ log_err("Invalid input SA id\n");
+ return -EINVAL;
+ }
+
+ ret = dpa_ipsec_sa_get_out_path(prm.sa_id, &prm.fqid);
+ if (ret < 0) {
+ log_err("Get out path for SA %d failed\n", prm.sa_id);
+ break;
+ }
+
+ if (copy_to_user((struct ioc_dpa_ipsec_sa_get_out_path *)args,
+ &prm, sizeof(prm))) {
+ log_err("Could not copy out_path to user for SA %d\n",
+ prm.sa_id);
+ return -EINVAL;
+ }
+
+ break;
+ }
+
default:
log_err("Invalid DPA IPsec ioctl (0x%x)\n", cmd);
ret = -EINVAL;
diff --git a/include/linux/fsl_dpa_ipsec.h b/include/linux/fsl_dpa_ipsec.h
index df3364d..6516078 100644
--- a/include/linux/fsl_dpa_ipsec.h
+++ b/include/linux/fsl_dpa_ipsec.h
@@ -614,4 +614,10 @@ enum dpa_ipsec_sa_operation_code {
DPA_IPSEC_SA_GET_SEQ_NUM_DONE
};
+/*
+ * Get frame queue id to IPSec for a specified SA in order to bypass outbound
+ * policy lookup and directly apply IPSec processing.
+ */
+int dpa_ipsec_sa_get_out_path(int sa_id, uint32_t *fqid);
+
#endif /* __FSL_DPA_IPSEC_H */