+
+ for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) {
+ uint64_t tc_rate = params->tc_rate[i];
+ uint16_t qsize = params->qsize[i];
+
+ if ((qsize == 0 && tc_rate != 0) ||
+ (qsize != 0 && tc_rate == 0) ||
+ (tc_rate > params->tb_rate)) {
+ RTE_LOG(ERR, SCHED,
+ "%s: Incorrect value for tc rate\n", __func__);
+ return -EINVAL;
+ }
+ }
+
+ if (params->qsize[RTE_SCHED_TRAFFIC_CLASS_BE] == 0 ||
+ params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE] == 0) {
+ RTE_LOG(ERR, SCHED,
+ "%s: Incorrect qsize or tc rate(best effort)\n", __func__);
+ return -EINVAL;
+ }
+
+ if (params->tc_period == 0) {
+ RTE_LOG(ERR, SCHED,
+ "%s: Incorrect value for tc period\n", __func__);
+ return -EINVAL;
+ }
+
+ /* n_pipes_per_subport: non-zero, power of 2 */
+ if (params->n_pipes_per_subport_enabled == 0 ||
+ params->n_pipes_per_subport_enabled > n_max_pipes_per_subport ||
+ !rte_is_power_of_2(params->n_pipes_per_subport_enabled)) {
+ RTE_LOG(ERR, SCHED,
+ "%s: Incorrect value for pipes number\n", __func__);
+ return -EINVAL;
+ }
+
+ /* pipe_profiles and n_pipe_profiles */
+ if (params->pipe_profiles == NULL ||
+ params->n_pipe_profiles == 0 ||
+ params->n_max_pipe_profiles == 0 ||
+ params->n_pipe_profiles > params->n_max_pipe_profiles) {
+ RTE_LOG(ERR, SCHED,
+ "%s: Incorrect value for pipe profiles\n", __func__);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < params->n_pipe_profiles; i++) {
+ struct rte_sched_pipe_params *p = params->pipe_profiles + i;
+ int status;
+
+ status = pipe_profile_check(p, rate, ¶ms->qsize[0]);
+ if (status != 0) {
+ RTE_LOG(ERR, SCHED,
+ "%s: Pipe profile check failed(%d)\n", __func__, status);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+uint32_t
+rte_sched_port_get_memory_footprint(struct rte_sched_port_params *port_params,
+ struct rte_sched_subport_params **subport_params)
+{
+ uint32_t size0 = 0, size1 = 0, i;
+ int status;
+
+ status = rte_sched_port_check_params(port_params);
+ if (status != 0) {
+ RTE_LOG(ERR, SCHED,
+ "%s: Port scheduler port params check failed (%d)\n",
+ __func__, status);
+
+ return 0;
+ }
+
+ for (i = 0; i < port_params->n_subports_per_port; i++) {
+ struct rte_sched_subport_params *sp = subport_params[i];
+
+ status = rte_sched_subport_check_params(sp,
+ port_params->n_pipes_per_subport,
+ port_params->rate);
+ if (status != 0) {
+ RTE_LOG(ERR, SCHED,
+ "%s: Port scheduler subport params check failed (%d)\n",
+ __func__, status);
+
+ return 0;
+ }
+ }
+
+ size0 = sizeof(struct rte_sched_port);
+
+ for (i = 0; i < port_params->n_subports_per_port; i++) {
+ struct rte_sched_subport_params *sp = subport_params[i];
+
+ size1 += rte_sched_subport_get_array_base(sp,
+ e_RTE_SCHED_SUBPORT_ARRAY_TOTAL);
+ }
+
+ return size0 + size1;
+}
+
+struct rte_sched_port *
+rte_sched_port_config(struct rte_sched_port_params *params)
+{
+ struct rte_sched_port *port = NULL;
+ uint32_t size0, size1;
+ uint32_t cycles_per_byte;
+ uint32_t i, j;
+ int status;
+
+ status = rte_sched_port_check_params(params);
+ if (status != 0) {
+ RTE_LOG(ERR, SCHED,
+ "%s: Port scheduler params check failed (%d)\n",
+ __func__, status);
+ return NULL;
+ }
+
+ size0 = sizeof(struct rte_sched_port);
+ size1 = params->n_subports_per_port * sizeof(struct rte_sched_subport *);
+
+ /* Allocate memory to store the data structures */
+ port = rte_zmalloc_socket("qos_params", size0 + size1, RTE_CACHE_LINE_SIZE,
+ params->socket);
+ if (port == NULL) {
+ RTE_LOG(ERR, SCHED, "%s: Memory allocation fails\n", __func__);
+
+ return NULL;
+ }
+
+ /* User parameters */
+ port->n_subports_per_port = params->n_subports_per_port;
+ port->n_pipes_per_subport = params->n_pipes_per_subport;
+ port->n_pipes_per_subport_log2 =
+ __builtin_ctz(params->n_pipes_per_subport);
+ port->socket = params->socket;
+
+ for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++)
+ port->pipe_queue[i] = i;
+
+ for (i = 0, j = 0; i < RTE_SCHED_QUEUES_PER_PIPE; i++) {
+ port->pipe_tc[i] = j;
+
+ if (j < RTE_SCHED_TRAFFIC_CLASS_BE)
+ j++;
+ }
+
+ for (i = 0, j = 0; i < RTE_SCHED_QUEUES_PER_PIPE; i++) {
+ port->tc_queue[i] = j;
+
+ if (i >= RTE_SCHED_TRAFFIC_CLASS_BE)
+ j++;
+ }
+ port->rate = params->rate;
+ port->mtu = params->mtu + params->frame_overhead;
+ port->frame_overhead = params->frame_overhead;