/* * Copyright (c) 2017 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* define message IDs */ #include #include #include static void vl_api_sw_interface_set_dpdk_hqos_pipe_t_handler (vl_api_sw_interface_set_dpdk_hqos_pipe_t * mp) { vl_api_sw_interface_set_dpdk_hqos_pipe_reply_t *rmp; int rv = 0; dpdk_main_t *dm = &dpdk_main; dpdk_device_t *xd; u32 sw_if_index = ntohl (mp->sw_if_index); u32 subport = ntohl (mp->subport); u32 pipe = ntohl (mp->pipe); u32 profile = ntohl (mp->profile); vnet_hw_interface_t *hw; VALIDATE_SW_IF_INDEX (mp); /* hw_if & dpdk device */ hw = vnet_get_sup_hw_interface (dm->vnet_main, sw_if_index); xd = vec_elt_at_index (dm->devices, hw->dev_instance); rv = rte_sched_pipe_config (xd->hqos_ht->hqos, subport, pipe, profile); BAD_SW_IF_INDEX_LABEL; REPLY_MACRO (VL_API_SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY); } static void *vl_api_sw_interface_set_dpdk_hqos_pipe_t_print (vl_api_sw_interface_set_dpdk_hqos_pipe_t * mp, void *handle) { u8 *s; s = format (0, "SCRIPT: sw_interface_set_dpdk_hqos_pipe "); s = format (s, "sw_if_index %u ", ntohl (mp->sw_if_index)); s = format (s, "subport %u pipe %u profile %u ", ntohl (mp->subport), ntohl (mp->pipe), ntohl (mp->profile)); FINISH; } static void vl_api_sw_interface_set_dpdk_hqos_subport_t_handler (vl_api_sw_interface_set_dpdk_hqos_subport_t * mp) { vl_api_sw_interface_set_dpdk_hqos_subport_reply_t *rmp; int rv = 0; dpdk_main_t *dm = &dpdk_main; dpdk_device_t *xd; struct rte_sched_subport_params p; u32 sw_if_index = ntohl (mp->sw_if_index); u32 subport = ntohl (mp->subport); p.tb_rate = ntohl (mp->tb_rate); p.tb_size = ntohl (mp->tb_size); p.tc_rate[0] = ntohl (mp->tc_rate[0]); p.tc_rate[1] = ntohl (mp->tc_rate[1]); p.tc_rate[2] = ntohl (mp->tc_rate[2]); p.tc_rate[3] = ntohl (mp->tc_rate[3]); p.tc_period = ntohl (mp->tc_period); vnet_hw_interface_t *hw; VALIDATE_SW_IF_INDEX (mp); /* hw_if & dpdk device */ hw = vnet_get_sup_hw_interface (dm->vnet_main, sw_if_index); xd = vec_elt_at_index (dm->devices, hw->dev_instance); rv = rte_sched_subport_config (xd->hqos_ht->hqos, subport, &p); BAD_SW_IF_INDEX_LABEL; REPLY_MACRO (VL_API_SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY); } static void *vl_api_sw_interface_set_dpdk_hqos_subport_t_print (vl_api_sw_interface_set_dpdk_hqos_subport_t * mp, void *handle) { u8 *s; s = format (0, "SCRIPT: sw_interface_set_dpdk_hqos_subport "); s = format (s, "sw_if_index %u ", ntohl (mp->sw_if_index)); s = format (s, "subport %u rate %u bkt_size %u tc0 %u tc1 %u tc2 %u tc3 %u period %u", ntohl (mp->subport), ntohl (mp->tb_rate), ntohl (mp->tb_size), ntohl (mp->tc_rate[0]), ntohl (mp->tc_rate[1]), ntohl (mp->tc_rate[2]), ntohl (mp->tc_rate[3]), ntohl (mp->tc_period)); FINISH; } static void vl_api_sw_interface_set_dpdk_hqos_tctbl_t_handler (vl_api_sw_interface_set_dpdk_hqos_tctbl_t * mp) { vl_api_sw_interface_set_dpdk_hqos_tctbl_reply_t *rmp; int rv = 0; dpdk_main_t *dm = &dpdk_main; vlib_thread_main_t *tm = vlib_get_thread_main (); dpdk_device_t *xd; u32 sw_if_index = ntohl (mp->sw_if_index); u32 entry = ntohl (mp->entry); u32 tc = ntohl (mp->tc); u32 queue = ntohl (mp->queue); u32 val, i; vnet_hw_interface_t *hw; VALIDATE_SW_IF_INDEX (mp); /* hw_if & dpdk device */ hw = vnet_get_sup_hw_interface (dm->vnet_main, sw_if_index); xd = vec_elt_at_index (dm->devices, hw->dev_instance); if (tc >= RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE) { clib_warning ("invalid traffic class !!"); rv = VNET_API_ERROR_INVALID_VALUE; goto done; } if (queue >= RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS) { clib_warning ("invalid queue !!"); rv = VNET_API_ERROR_INVALID_VALUE; goto done; } /* Detect the set of worker threads */ uword *p = hash_get_mem (tm->thread_registrations_by_name, "workers"); if (p == 0) { clib_warning ("worker thread registration AWOL !!"); rv = VNET_API_ERROR_INVALID_VALUE_2; goto done; } vlib_thread_registration_t *tr = (vlib_thread_registration_t *) p[0]; int worker_thread_first = tr->first_index; int worker_thread_count = tr->count; val = tc * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + queue; for (i = 0; i < worker_thread_count; i++) xd->hqos_wt[worker_thread_first + i].hqos_tc_table[entry] = val; BAD_SW_IF_INDEX_LABEL; done: REPLY_MACRO (VL_API_SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY); } static void *vl_api_sw_interface_set_dpdk_hqos_tctbl_t_print (vl_api_sw_interface_set_dpdk_hqos_tctbl_t * mp, void *handle) { u8 *s; s = format (0, "SCRIPT: sw_interface_set_dpdk_hqos_tctbl "); s = format (s, "sw_if_index %u ", ntohl (mp->sw_if_index)); s = format (s, "entry %u tc %u queue %u", ntohl (mp->entry), ntohl (mp->tc), ntohl (mp->queue)); FINISH; } #include static clib_error_t * dpdk_api_init (vlib_main_t * vm) { dpdk_main_t *dm = &dpdk_main; /* Ask for a correctly-sized block of API message decode slots */ dm->msg_id_base = setup_message_id_table (); return 0; } /* *INDENT-OFF* */ VLIB_INIT_FUNCTION (dpdk_api_init) = { .runs_after = VLIB_INITS ("dpdk_init"), /* *INDENT-OFF* */ /* * fd.io coding-style-patch-verification: ON * * Local Variables: * eval: (c-set-style "gnu") * End: */