+static void
+remove_unsupported_param_size (u32 **param_sizes, u32 param_size_min,
+ u32 param_size_max, u32 increment)
+{
+ u32 i = 0;
+ u32 cap_param_size;
+
+ while (i < vec_len (*param_sizes))
+ {
+ u32 found_param = 0;
+ for (cap_param_size = param_size_min; cap_param_size <= param_size_max;
+ cap_param_size += increment)
+ {
+ if ((*param_sizes)[i] == cap_param_size)
+ {
+ found_param = 1;
+ break;
+ }
+ if (increment == 0)
+ break;
+ }
+ if (!found_param)
+ /* no such param_size in cap so delete this size in temp_cap params */
+ vec_delete (*param_sizes, 1, i);
+ else
+ i++;
+ }
+}
+
+static void
+cryptodev_delete_cap (cryptodev_capability_t **temp_caps, u32 temp_cap_id)
+{
+ cryptodev_capability_t temp_cap = (*temp_caps)[temp_cap_id];
+
+ switch (temp_cap.xform_type)
+ {
+ case RTE_CRYPTO_SYM_XFORM_AUTH:
+ vec_free (temp_cap.auth.digest_sizes);
+ break;
+ case RTE_CRYPTO_SYM_XFORM_CIPHER:
+ vec_free (temp_cap.cipher.key_sizes);
+ break;
+ case RTE_CRYPTO_SYM_XFORM_AEAD:
+ vec_free (temp_cap.aead.key_sizes);
+ vec_free (temp_cap.aead.aad_sizes);
+ vec_free (temp_cap.aead.digest_sizes);
+ break;
+ default:
+ break;
+ }
+ vec_delete (*temp_caps, 1, temp_cap_id);
+}
+
+static u32
+cryptodev_remove_unsupported_param_sizes (
+ cryptodev_capability_t *temp_cap,
+ const struct rte_cryptodev_capabilities *dev_caps)
+{
+ u32 cap_found = 0;
+ const struct rte_cryptodev_capabilities *cap = &dev_caps[0];
+
+ while (cap->op != RTE_CRYPTO_OP_TYPE_UNDEFINED)
+ {
+ if (cap->sym.xform_type == temp_cap->xform_type)
+ switch (cap->sym.xform_type)
+ {
+ case RTE_CRYPTO_SYM_XFORM_CIPHER:
+ if (cap->sym.cipher.algo == temp_cap->cipher.algo)
+ {
+ remove_unsupported_param_size (
+ &temp_cap->cipher.key_sizes, cap->sym.cipher.key_size.min,
+ cap->sym.cipher.key_size.max,
+ cap->sym.cipher.key_size.increment);
+ if (vec_len (temp_cap->cipher.key_sizes) > 0)
+ cap_found = 1;
+ }
+ break;
+ case RTE_CRYPTO_SYM_XFORM_AUTH:
+ if (cap->sym.auth.algo == temp_cap->auth.algo)
+ {
+ remove_unsupported_param_size (
+ &temp_cap->auth.digest_sizes, cap->sym.auth.digest_size.min,
+ cap->sym.auth.digest_size.max,
+ cap->sym.auth.digest_size.increment);
+ if (vec_len (temp_cap->auth.digest_sizes) > 0)
+ cap_found = 1;
+ }
+ break;
+ case RTE_CRYPTO_SYM_XFORM_AEAD:
+ if (cap->sym.aead.algo == temp_cap->aead.algo)
+ {
+ remove_unsupported_param_size (
+ &temp_cap->aead.key_sizes, cap->sym.aead.key_size.min,
+ cap->sym.aead.key_size.max,
+ cap->sym.aead.key_size.increment);
+ remove_unsupported_param_size (
+ &temp_cap->aead.aad_sizes, cap->sym.aead.aad_size.min,
+ cap->sym.aead.aad_size.max,
+ cap->sym.aead.aad_size.increment);
+ remove_unsupported_param_size (
+ &temp_cap->aead.digest_sizes, cap->sym.aead.digest_size.min,
+ cap->sym.aead.digest_size.max,
+ cap->sym.aead.digest_size.increment);
+ if (vec_len (temp_cap->aead.key_sizes) > 0 &&
+ vec_len (temp_cap->aead.aad_sizes) > 0 &&
+ vec_len (temp_cap->aead.digest_sizes) > 0)
+ cap_found = 1;
+ }
+ break;
+ default:
+ break;
+ }
+ if (cap_found)
+ break;
+ cap++;
+ }
+
+ return cap_found;
+}
+
+static void
+cryptodev_get_common_capabilities ()
+{
+ cryptodev_main_t *cmt = &cryptodev_main;
+ cryptodev_inst_t *dev_inst;
+ struct rte_cryptodev_info dev_info;
+ u32 previous_dev_id, dev_id;
+ u32 cap_id = 0;
+ u32 param;
+ cryptodev_capability_t tmp_cap;
+ const struct rte_cryptodev_capabilities *cap;
+ const struct rte_cryptodev_capabilities *dev_caps;
+
+ if (vec_len (cmt->cryptodev_inst) == 0)
+ return;
+ dev_inst = vec_elt_at_index (cmt->cryptodev_inst, 0);
+ rte_cryptodev_info_get (dev_inst->dev_id, &dev_info);
+ cap = &dev_info.capabilities[0];
+
+ /*init capabilities vector*/
+ while (cap->op != RTE_CRYPTO_OP_TYPE_UNDEFINED)
+ {
+ ASSERT (cap->op == RTE_CRYPTO_OP_TYPE_SYMMETRIC);
+ tmp_cap.xform_type = cap->sym.xform_type;
+ switch (cap->sym.xform_type)
+ {
+ case RTE_CRYPTO_SYM_XFORM_CIPHER:
+ tmp_cap.cipher.key_sizes = 0;
+ tmp_cap.cipher.algo = cap->sym.cipher.algo;
+ for (param = cap->sym.cipher.key_size.min;
+ param <= cap->sym.cipher.key_size.max;
+ param += cap->sym.cipher.key_size.increment)
+ {
+ vec_add1 (tmp_cap.cipher.key_sizes, param);
+ if (cap->sym.cipher.key_size.increment == 0)
+ break;
+ }
+ break;
+ case RTE_CRYPTO_SYM_XFORM_AUTH:
+ tmp_cap.auth.algo = cap->sym.auth.algo;
+ tmp_cap.auth.digest_sizes = 0;
+ for (param = cap->sym.auth.digest_size.min;
+ param <= cap->sym.auth.digest_size.max;
+ param += cap->sym.auth.digest_size.increment)
+ {
+ vec_add1 (tmp_cap.auth.digest_sizes, param);
+ if (cap->sym.auth.digest_size.increment == 0)
+ break;
+ }
+ break;
+ case RTE_CRYPTO_SYM_XFORM_AEAD:
+ tmp_cap.aead.key_sizes = 0;
+ tmp_cap.aead.aad_sizes = 0;
+ tmp_cap.aead.digest_sizes = 0;
+ tmp_cap.aead.algo = cap->sym.aead.algo;
+ for (param = cap->sym.aead.key_size.min;
+ param <= cap->sym.aead.key_size.max;
+ param += cap->sym.aead.key_size.increment)
+ {
+ vec_add1 (tmp_cap.aead.key_sizes, param);
+ if (cap->sym.aead.key_size.increment == 0)
+ break;
+ }
+ for (param = cap->sym.aead.aad_size.min;
+ param <= cap->sym.aead.aad_size.max;
+ param += cap->sym.aead.aad_size.increment)
+ {
+ vec_add1 (tmp_cap.aead.aad_sizes, param);
+ if (cap->sym.aead.aad_size.increment == 0)
+ break;
+ }
+ for (param = cap->sym.aead.digest_size.min;
+ param <= cap->sym.aead.digest_size.max;
+ param += cap->sym.aead.digest_size.increment)
+ {
+ vec_add1 (tmp_cap.aead.digest_sizes, param);
+ if (cap->sym.aead.digest_size.increment == 0)
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
+ vec_add1 (cmt->supported_caps, tmp_cap);
+ cap++;
+ }
+
+ while (cap_id < vec_len (cmt->supported_caps))
+ {
+ u32 cap_is_supported = 1;
+ previous_dev_id = cmt->cryptodev_inst->dev_id;
+
+ vec_foreach (dev_inst, cmt->cryptodev_inst)
+ {
+ dev_id = dev_inst->dev_id;
+ if (previous_dev_id != dev_id)
+ {
+ previous_dev_id = dev_id;
+ rte_cryptodev_info_get (dev_id, &dev_info);
+ dev_caps = &dev_info.capabilities[0];
+ cap_is_supported = cryptodev_remove_unsupported_param_sizes (
+ &cmt->supported_caps[cap_id], dev_caps);
+ if (!cap_is_supported)
+ {
+ cryptodev_delete_cap (&cmt->supported_caps, cap_id);
+ /*no need to check other devices as this one doesn't support
+ * this temp_cap*/
+ break;
+ }
+ }
+ }
+ if (cap_is_supported)
+ cap_id++;
+ }
+}
+