diff options
author | Bogdan Constantin Popescu <bogdan.c.popescu@freescale.com> | 2014-03-28 09:17:46 (GMT) |
---|---|---|
committer | Jose Rivera <German.Rivera@freescale.com> | 2014-03-28 16:17:28 (GMT) |
commit | 0506e775d04d8f303f3ca3abfd18096f3c4f0df5 (patch) | |
tree | 987a1db5525e8fd55d9c0ed8ff409ddde07be966 | |
parent | 14bc1055d1415408999b4ac1660a261daddd3b55 (diff) | |
download | linux-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.c | 59 | ||||
-rw-r--r-- | drivers/staging/fsl_dpa_offload/dpa_ipsec_ioctl.h | 8 | ||||
-rw-r--r-- | drivers/staging/fsl_dpa_offload/wrp_dpa_ipsec.c | 31 | ||||
-rw-r--r-- | include/linux/fsl_dpa_ipsec.h | 6 |
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 */ |