+ case RTE_FLOW_ACTION_TYPE_RSS:
+ rss = (const struct rte_flow_action_rss *)act->conf;
+
+ vnic_id = attr->group;
+ if (!vnic_id) {
+ PMD_DRV_LOG(ERR, "Group id cannot be 0\n");
+ rte_flow_error_set(error,
+ EINVAL,
+ RTE_FLOW_ERROR_TYPE_ATTR,
+ NULL,
+ "Group id cannot be 0");
+ rc = -rte_errno;
+ goto ret;
+ }
+
+ vnic = &bp->vnic_info[vnic_id];
+ if (vnic == NULL) {
+ rte_flow_error_set(error,
+ EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION,
+ act,
+ "No matching VNIC for RSS group.");
+ rc = -rte_errno;
+ goto ret;
+ }
+ PMD_DRV_LOG(DEBUG, "VNIC found\n");
+
+ /* Check if requested RSS config matches RSS config of VNIC
+ * only if it is not a fresh VNIC configuration.
+ * Otherwise the existing VNIC configuration can be used.
+ */
+ if (vnic->rx_queue_cnt) {
+ rc = match_vnic_rss_cfg(bp, vnic, rss);
+ if (rc) {
+ PMD_DRV_LOG(ERR,
+ "VNIC and RSS config mismatch\n");
+ rte_flow_error_set(error,
+ EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION,
+ act,
+ "VNIC and RSS cfg mismatch");
+ rc = -rte_errno;
+ goto ret;
+ }
+ goto vnic_found;
+ }
+
+ for (i = 0; i < rss->queue_num; i++) {
+ PMD_DRV_LOG(DEBUG, "RSS action Queue %d\n",
+ rss->queue[i]);
+
+ if (!rss->queue[i] ||
+ rss->queue[i] >= bp->rx_nr_rings ||
+ !bp->rx_queues[rss->queue[i]]) {
+ rte_flow_error_set(error,
+ EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION,
+ act,
+ "Invalid queue ID for RSS");
+ rc = -rte_errno;
+ goto ret;
+ }
+ rxq = bp->rx_queues[rss->queue[i]];
+
+ if (bp->vnic_info[0].fw_grp_ids[rss->queue[i]] !=
+ INVALID_HW_RING_ID) {
+ PMD_DRV_LOG(ERR,
+ "queue active with other VNIC\n");
+ rte_flow_error_set(error,
+ EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION,
+ act,
+ "Invalid queue ID for RSS");
+ rc = -rte_errno;
+ goto ret;
+ }
+
+ rxq->vnic = vnic;
+ rxq->rx_started = 1;
+ vnic->rx_queue_cnt++;
+ }
+
+ vnic->start_grp_id = rss->queue[0];
+ vnic->end_grp_id = rss->queue[rss->queue_num - 1];
+ vnic->func_default = 0; //This is not a default VNIC.
+
+ rc = bnxt_vnic_prep(bp, vnic);
+ if (rc) {
+ rte_flow_error_set(error,
+ EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION,
+ act,
+ "VNIC prep fail");
+ rc = -rte_errno;
+ goto ret;
+ }