+ /* compile time checks */
+ RTE_BUILD_BUG_ON(RTE_SCHED_PORT_N_GRINDERS == 0);
+ RTE_BUILD_BUG_ON(RTE_SCHED_PORT_N_GRINDERS &
+ (RTE_SCHED_PORT_N_GRINDERS - 1));
+
+ /* User parameters */
+ s->n_pipes_per_subport_enabled = params->n_pipes_per_subport_enabled;
+ memcpy(s->qsize, params->qsize, sizeof(params->qsize));
+ s->n_pipe_profiles = params->n_pipe_profiles;
+ s->n_max_pipe_profiles = params->n_max_pipe_profiles;
+
+#ifdef RTE_SCHED_RED
+ for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) {
+ uint32_t j;
+
+ for (j = 0; j < RTE_COLORS; j++) {
+ /* if min/max are both zero, then RED is disabled */
+ if ((params->red_params[i][j].min_th |
+ params->red_params[i][j].max_th) == 0) {
+ continue;
+ }
+
+ if (rte_red_config_init(&s->red_config[i][j],
+ params->red_params[i][j].wq_log2,
+ params->red_params[i][j].min_th,
+ params->red_params[i][j].max_th,
+ params->red_params[i][j].maxp_inv) != 0) {
+ rte_sched_free_memory(port, n_subports);
+
+ RTE_LOG(NOTICE, SCHED,
+ "%s: RED configuration init fails\n", __func__);
+ return -EINVAL;
+ }
+ }
+ }
+#endif
+
+ /* Scheduling loop detection */
+ s->pipe_loop = RTE_SCHED_PIPE_INVALID;
+ s->pipe_exhaustion = 0;
+
+ /* Grinders */
+ s->busy_grinders = 0;
+
+ /* Queue base calculation */
+ rte_sched_subport_config_qsize(s);
+
+ /* Large data structures */
+ s->pipe = (struct rte_sched_pipe *)
+ (s->memory + rte_sched_subport_get_array_base(params,
+ e_RTE_SCHED_SUBPORT_ARRAY_PIPE));
+ s->queue = (struct rte_sched_queue *)
+ (s->memory + rte_sched_subport_get_array_base(params,
+ e_RTE_SCHED_SUBPORT_ARRAY_QUEUE));
+ s->queue_extra = (struct rte_sched_queue_extra *)
+ (s->memory + rte_sched_subport_get_array_base(params,
+ e_RTE_SCHED_SUBPORT_ARRAY_QUEUE_EXTRA));
+ s->pipe_profiles = (struct rte_sched_pipe_profile *)
+ (s->memory + rte_sched_subport_get_array_base(params,
+ e_RTE_SCHED_SUBPORT_ARRAY_PIPE_PROFILES));
+ s->bmp_array = s->memory + rte_sched_subport_get_array_base(params,
+ e_RTE_SCHED_SUBPORT_ARRAY_BMP_ARRAY);
+ s->queue_array = (struct rte_mbuf **)
+ (s->memory + rte_sched_subport_get_array_base(params,
+ e_RTE_SCHED_SUBPORT_ARRAY_QUEUE_ARRAY));
+
+ /* Bitmap */
+ n_subport_pipe_queues = rte_sched_subport_pipe_queues(s);
+ bmp_mem_size = rte_bitmap_get_memory_footprint(n_subport_pipe_queues);
+ s->bmp = rte_bitmap_init(n_subport_pipe_queues, s->bmp_array,
+ bmp_mem_size);
+ if (s->bmp == NULL) {
+ RTE_LOG(ERR, SCHED,
+ "%s: Subport bitmap init error\n", __func__);
+
+ rte_sched_free_memory(port, n_subports);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < RTE_SCHED_PORT_N_GRINDERS; i++)
+ s->grinder_base_bmp_pos[i] = RTE_SCHED_PIPE_INVALID;
+
+#ifdef RTE_SCHED_SUBPORT_TC_OV