+static int
+rte_sched_subport_check_params(struct rte_sched_subport_params *params,
+ uint32_t n_max_pipes_per_subport,
+ uint64_t rate)
+{
+ uint32_t i;
+
+ /* Check user parameters */
+ if (params == NULL) {
+ RTE_LOG(ERR, SCHED,
+ "%s: Incorrect value for parameter params\n", __func__);
+ return -EINVAL;
+ }
+
+ if (params->tb_rate == 0 || params->tb_rate > rate) {
+ RTE_LOG(ERR, SCHED,
+ "%s: Incorrect value for tb rate\n", __func__);
+ return -EINVAL;
+ }
+
+ if (params->tb_size == 0) {
+ RTE_LOG(ERR, SCHED,
+ "%s: Incorrect value for tb size\n", __func__);
+ return -EINVAL;
+ }
+
+ /* qsize: if non-zero, power of 2,
+ * no bigger than 32K (due to 16-bit read/write pointers)
+ */
+ for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) {
+ uint16_t qsize = params->qsize[i];
+
+ if (qsize != 0 && !rte_is_power_of_2(qsize)) {
+ RTE_LOG(ERR, SCHED,
+ "%s: Incorrect value for qsize\n", __func__);
+ return -EINVAL;
+ }
+ }
+
+ 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;
+}
+