+int dpaa2_eth_eventq_attach(const struct rte_eth_dev *dev,
+ int eth_rx_queue_id,
+ struct dpaa2_dpcon_dev *dpcon,
+ const struct rte_event_eth_rx_adapter_queue_conf *queue_conf)
+{
+ struct dpaa2_dev_priv *eth_priv = dev->data->dev_private;
+ struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private;
+ struct dpaa2_queue *dpaa2_ethq = eth_priv->rx_vq[eth_rx_queue_id];
+ uint8_t flow_id = dpaa2_ethq->flow_id;
+ struct dpni_queue cfg;
+ uint8_t options, priority;
+ int ret;
+
+ if (queue_conf->ev.sched_type == RTE_SCHED_TYPE_PARALLEL)
+ dpaa2_ethq->cb = dpaa2_dev_process_parallel_event;
+ else if (queue_conf->ev.sched_type == RTE_SCHED_TYPE_ATOMIC)
+ dpaa2_ethq->cb = dpaa2_dev_process_atomic_event;
+ else if (queue_conf->ev.sched_type == RTE_SCHED_TYPE_ORDERED)
+ dpaa2_ethq->cb = dpaa2_dev_process_ordered_event;
+ else
+ return -EINVAL;
+
+ priority = (RTE_EVENT_DEV_PRIORITY_LOWEST / queue_conf->ev.priority) *
+ (dpcon->num_priorities - 1);
+
+ memset(&cfg, 0, sizeof(struct dpni_queue));
+ options = DPNI_QUEUE_OPT_DEST;
+ cfg.destination.type = DPNI_DEST_DPCON;
+ cfg.destination.id = dpcon->dpcon_id;
+ cfg.destination.priority = priority;
+
+ if (queue_conf->ev.sched_type == RTE_SCHED_TYPE_ATOMIC) {
+ options |= DPNI_QUEUE_OPT_HOLD_ACTIVE;
+ cfg.destination.hold_active = 1;
+ }
+
+ if (queue_conf->ev.sched_type == RTE_SCHED_TYPE_ORDERED &&
+ !eth_priv->en_ordered) {
+ struct opr_cfg ocfg;
+
+ /* Restoration window size = 256 frames */
+ ocfg.oprrws = 3;
+ /* Restoration window size = 512 frames for LX2 */
+ if (dpaa2_svr_family == SVR_LX2160A)
+ ocfg.oprrws = 4;
+ /* Auto advance NESN window enabled */
+ ocfg.oa = 1;
+ /* Late arrival window size disabled */
+ ocfg.olws = 0;
+ /* ORL resource exhaustaion advance NESN disabled */
+ ocfg.oeane = 0;
+ /* Loose ordering enabled */
+ ocfg.oloe = 1;
+ eth_priv->en_loose_ordered = 1;
+ /* Strict ordering enabled if explicitly set */
+ if (getenv("DPAA2_STRICT_ORDERING_ENABLE")) {
+ ocfg.oloe = 0;
+ eth_priv->en_loose_ordered = 0;
+ }
+
+ ret = dpni_set_opr(dpni, CMD_PRI_LOW, eth_priv->token,
+ dpaa2_ethq->tc_index, flow_id,
+ OPR_OPT_CREATE, &ocfg);
+ if (ret) {
+ DPAA2_PMD_ERR("Error setting opr: ret: %d\n", ret);
+ return ret;
+ }
+
+ eth_priv->en_ordered = 1;
+ }
+
+ options |= DPNI_QUEUE_OPT_USER_CTX;
+ cfg.user_context = (size_t)(dpaa2_ethq);
+
+ ret = dpni_set_queue(dpni, CMD_PRI_LOW, eth_priv->token, DPNI_QUEUE_RX,
+ dpaa2_ethq->tc_index, flow_id, options, &cfg);
+ if (ret) {
+ DPAA2_PMD_ERR("Error in dpni_set_queue: ret: %d", ret);
+ return ret;
+ }
+
+ memcpy(&dpaa2_ethq->ev, &queue_conf->ev, sizeof(struct rte_event));
+
+ return 0;
+}
+
+int dpaa2_eth_eventq_detach(const struct rte_eth_dev *dev,
+ int eth_rx_queue_id)
+{
+ struct dpaa2_dev_priv *eth_priv = dev->data->dev_private;
+ struct fsl_mc_io *dpni = (struct fsl_mc_io *)dev->process_private;
+ struct dpaa2_queue *dpaa2_ethq = eth_priv->rx_vq[eth_rx_queue_id];
+ uint8_t flow_id = dpaa2_ethq->flow_id;
+ struct dpni_queue cfg;
+ uint8_t options;
+ int ret;
+
+ memset(&cfg, 0, sizeof(struct dpni_queue));
+ options = DPNI_QUEUE_OPT_DEST;
+ cfg.destination.type = DPNI_DEST_NONE;
+
+ ret = dpni_set_queue(dpni, CMD_PRI_LOW, eth_priv->token, DPNI_QUEUE_RX,
+ dpaa2_ethq->tc_index, flow_id, options, &cfg);
+ if (ret)
+ DPAA2_PMD_ERR("Error in dpni_set_queue: ret: %d", ret);
+
+ return ret;
+}
+
+static inline int
+dpaa2_dev_verify_filter_ops(enum rte_filter_op filter_op)
+{
+ unsigned int i;
+
+ for (i = 0; i < RTE_DIM(dpaa2_supported_filter_ops); i++) {
+ if (dpaa2_supported_filter_ops[i] == filter_op)
+ return 0;
+ }
+ return -ENOTSUP;
+}
+
+static int
+dpaa2_dev_flow_ctrl(struct rte_eth_dev *dev,
+ enum rte_filter_type filter_type,
+ enum rte_filter_op filter_op,
+ void *arg)
+{
+ int ret = 0;
+
+ if (!dev)
+ return -ENODEV;
+
+ switch (filter_type) {
+ case RTE_ETH_FILTER_GENERIC:
+ if (dpaa2_dev_verify_filter_ops(filter_op) < 0) {
+ ret = -ENOTSUP;
+ break;
+ }
+ *(const void **)arg = &dpaa2_flow_ops;
+ dpaa2_filter_type |= filter_type;
+ break;
+ default:
+ RTE_LOG(ERR, PMD, "Filter type (%d) not supported",
+ filter_type);
+ ret = -ENOTSUP;
+ break;
+ }
+ return ret;
+}
+