@@ -489,4 +489,10 @@ int iavf_ipsec_crypto_request(struct iavf_adapter *adapter,
extern const struct rte_tm_ops iavf_tm_ops;
int iavf_get_ptp_cap(struct iavf_adapter *adapter);
int iavf_get_phc_time(struct iavf_rx_queue *rxq);
+int iavf_flow_sub(struct iavf_adapter *adapter,
+ struct iavf_fsub_conf *filter);
+int iavf_flow_unsub(struct iavf_adapter *adapter,
+ struct iavf_fsub_conf *filter);
+int iavf_flow_sub_check(struct iavf_adapter *adapter,
+ struct iavf_fsub_conf *filter);
#endif /* _IAVF_ETHDEV_H_ */
@@ -69,29 +69,80 @@ iavf_pattern_match_item iavf_fsub_pattern_list[] = {
};
static int
-iavf_fsub_create(__rte_unused struct iavf_adapter *ad,
- __rte_unused struct rte_flow *flow,
- __rte_unused void *meta,
- __rte_unused struct rte_flow_error *error)
+iavf_fsub_create(struct iavf_adapter *ad, struct rte_flow *flow,
+ void *meta, struct rte_flow_error *error)
{
+ struct iavf_fsub_conf *filter = meta;
+ struct iavf_fsub_conf *rule;
+ int ret;
+
+ rule = rte_zmalloc("fsub_entry", sizeof(*rule), 0);
+ if (!rule) {
+ rte_flow_error_set(error, ENOMEM,
+ RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+ "Failed to allocate memory for fsub rule");
+ return -rte_errno;
+ }
+
+ ret = iavf_flow_sub(ad, filter);
+ if (ret) {
+ rte_flow_error_set(error, -ret,
+ RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+ "Failed to subscribe flow rule.");
+ goto free_entry;
+ }
+
+ rte_memcpy(rule, filter, sizeof(*rule));
+ flow->rule = rule;
+
+ return ret;
+
+free_entry:
+ rte_free(rule);
return -rte_errno;
}
static int
-iavf_fsub_destroy(__rte_unused struct iavf_adapter *ad,
- __rte_unused struct rte_flow *flow,
- __rte_unused struct rte_flow_error *error)
+iavf_fsub_destroy(struct iavf_adapter *ad, struct rte_flow *flow,
+ struct rte_flow_error *error)
{
- return -rte_errno;
+ struct iavf_fsub_conf *filter;
+ int ret;
+
+ filter = (struct iavf_fsub_conf *)flow->rule;
+
+ ret = iavf_flow_unsub(ad, filter);
+ if (ret) {
+ rte_flow_error_set(error, -ret,
+ RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+ "Failed to unsubscribe flow rule.");
+ return -rte_errno;
+ }
+
+ flow->rule = NULL;
+ rte_free(filter);
+
+ return ret;
}
static int
-iavf_fsub_validation(__rte_unused struct iavf_adapter *ad,
+iavf_fsub_validation(struct iavf_adapter *ad,
__rte_unused struct rte_flow *flow,
- __rte_unused void *meta,
- __rte_unused struct rte_flow_error *error)
+ void *meta,
+ struct rte_flow_error *error)
{
- return -rte_errno;
+ struct iavf_fsub_conf *filter = meta;
+ int ret;
+
+ ret = iavf_flow_sub_check(ad, filter);
+ if (ret) {
+ rte_flow_error_set(error, -ret,
+ RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+ "Failed to validate filter rule.");
+ return -rte_errno;
+ }
+
+ return ret;
};
static int
@@ -1534,6 +1534,138 @@ iavf_fdir_check(struct iavf_adapter *adapter,
return 0;
}
+int
+iavf_flow_sub(struct iavf_adapter *adapter, struct iavf_fsub_conf *filter)
+{
+ struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
+ struct virtchnl_flow_sub *fsub_cfg;
+ struct iavf_cmd_info args;
+ int err;
+
+ filter->sub_fltr.vsi_id = vf->vsi_res->vsi_id;
+ filter->sub_fltr.validate_only = 0;
+
+ memset(&args, 0, sizeof(args));
+ args.ops = VIRTCHNL_OP_FLOW_SUBSCRIBE;
+ args.in_args = (uint8_t *)(&filter->sub_fltr);
+ args.in_args_size = sizeof(*(&filter->sub_fltr));
+ args.out_buffer = vf->aq_resp;
+ args.out_size = IAVF_AQ_BUF_SZ;
+
+ err = iavf_execute_vf_cmd(adapter, &args, 0);
+ if (err)
+ PMD_DRV_LOG(ERR, "Failed to execute command of "
+ "OP_FLOW_SUBSCRIBE");
+
+ fsub_cfg = (struct virtchnl_flow_sub *)args.out_buffer;
+ filter->flow_id = fsub_cfg->flow_id;
+
+ if (fsub_cfg->status == VIRTCHNL_FSUB_SUCCESS) {
+ PMD_DRV_LOG(INFO, "Succeed in adding rule request by PF");
+ } else if (fsub_cfg->status == VIRTCHNL_FSUB_FAILURE_RULE_NORESOURCE) {
+ PMD_DRV_LOG(ERR, "Failed to add rule request due to no hw "
+ "resource");
+ err = -1;
+ } else if (fsub_cfg->status == VIRTCHNL_FSUB_FAILURE_RULE_EXIST) {
+ PMD_DRV_LOG(ERR, "Failed to add rule request due to the rule "
+ "is already existed");
+ err = -1;
+ } else if (fsub_cfg->status == VIRTCHNL_FSUB_FAILURE_RULE_INVALID) {
+ PMD_DRV_LOG(ERR, "Failed to add rule request due to the hw "
+ "doesn't support");
+ err = -1;
+ } else {
+ PMD_DRV_LOG(ERR, "Failed to add rule request due to other "
+ "reasons");
+ err = -1;
+ }
+
+ return err;
+}
+
+int
+iavf_flow_unsub(struct iavf_adapter *adapter, struct iavf_fsub_conf *filter)
+{
+ struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
+ struct virtchnl_flow_unsub *unsub_cfg;
+ struct iavf_cmd_info args;
+ int err;
+
+ filter->unsub_fltr.vsi_id = vf->vsi_res->vsi_id;
+ filter->unsub_fltr.flow_id = filter->flow_id;
+
+ memset(&args, 0, sizeof(args));
+ args.ops = VIRTCHNL_OP_FLOW_UNSUBSCRIBE;
+ args.in_args = (uint8_t *)(&filter->unsub_fltr);
+ args.in_args_size = sizeof(filter->unsub_fltr);
+ args.out_buffer = vf->aq_resp;
+ args.out_size = IAVF_AQ_BUF_SZ;
+
+ err = iavf_execute_vf_cmd(adapter, &args, 0);
+ if (err)
+ PMD_DRV_LOG(ERR, "Failed to execute command of "
+ "OP_FLOW_UNSUBSCRIBE");
+
+ unsub_cfg = (struct virtchnl_flow_unsub *)args.out_buffer;
+
+ if (unsub_cfg->status == VIRTCHNL_FSUB_SUCCESS) {
+ PMD_DRV_LOG(INFO, "Succeed in deleting rule request by PF");
+ } else if (unsub_cfg->status == VIRTCHNL_FSUB_FAILURE_RULE_NONEXIST) {
+ PMD_DRV_LOG(ERR, "Failed to delete rule request due to this "
+ "rule doesn't exist");
+ err = -1;
+ } else {
+ PMD_DRV_LOG(ERR, "Failed to delete rule request due to other "
+ "reasons");
+ err = -1;
+ }
+
+ return err;
+}
+
+int
+iavf_flow_sub_check(struct iavf_adapter *adapter,
+ struct iavf_fsub_conf *filter)
+{
+ struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
+ struct virtchnl_flow_sub *fsub_cfg;
+
+ struct iavf_cmd_info args;
+ int err;
+
+ filter->sub_fltr.vsi_id = vf->vsi_res->vsi_id;
+ filter->sub_fltr.validate_only = 1;
+
+ args.ops = VIRTCHNL_OP_FLOW_SUBSCRIBE;
+ args.in_args = (uint8_t *)(&filter->sub_fltr);
+ args.in_args_size = sizeof(*(&filter->sub_fltr));
+ args.out_buffer = vf->aq_resp;
+ args.out_size = IAVF_AQ_BUF_SZ;
+
+ err = iavf_execute_vf_cmd(adapter, &args, 0);
+ if (err) {
+ PMD_DRV_LOG(ERR, "fail to check flow director rule");
+ return err;
+ }
+
+ fsub_cfg = (struct virtchnl_flow_sub *)args.out_buffer;
+
+ if (fsub_cfg->status == VIRTCHNL_FSUB_SUCCESS) {
+ PMD_DRV_LOG(INFO, "Succeed in checking rule request by PF");
+ } else if (fsub_cfg->status == VIRTCHNL_FSUB_FAILURE_RULE_INVALID) {
+ PMD_DRV_LOG(ERR, "Failed to check rule request due to "
+ "parameters validation or HW doesn't "
+ "support");
+ err = -1;
+ } else {
+ PMD_DRV_LOG(ERR, "Failed to check rule request due to other "
+ "reasons");
+ err = -1;
+ }
+
+ return err;
+}
+
int
iavf_add_del_rss_cfg(struct iavf_adapter *adapter,
struct virtchnl_rss_cfg *rss_cfg, bool add)