2 * Copyright (c) 2017 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
15 #include <vnet/vnet.h>
16 #include <vppinfra/vec.h>
17 #include <vppinfra/error.h>
18 #include <vppinfra/format.h>
19 #include <vppinfra/bitmap.h>
21 #include <vnet/ethernet/ethernet.h>
22 #include <dpdk/device/dpdk.h>
23 #include <vlib/pci/pci.h>
29 #include <sys/mount.h>
33 #include <dpdk/device/dpdk_priv.h>
35 #include <vlibapi/api.h>
36 #include <vlibmemory/api.h>
38 /* define message IDs */
39 #include <dpdk/api/dpdk.api_enum.h>
40 #include <dpdk/api/dpdk.api_types.h>
42 #include <vlibapi/api_helper_macros.h>
45 vl_api_sw_interface_set_dpdk_hqos_pipe_t_handler
46 (vl_api_sw_interface_set_dpdk_hqos_pipe_t * mp)
48 vl_api_sw_interface_set_dpdk_hqos_pipe_reply_t *rmp;
51 dpdk_main_t *dm = &dpdk_main;
54 u32 sw_if_index = ntohl (mp->sw_if_index);
55 u32 subport = ntohl (mp->subport);
56 u32 pipe = ntohl (mp->pipe);
57 u32 profile = ntohl (mp->profile);
58 vnet_hw_interface_t *hw;
60 VALIDATE_SW_IF_INDEX (mp);
62 /* hw_if & dpdk device */
63 hw = vnet_get_sup_hw_interface (dm->vnet_main, sw_if_index);
65 xd = vec_elt_at_index (dm->devices, hw->dev_instance);
67 rv = rte_sched_pipe_config (xd->hqos_ht->hqos, subport, pipe, profile);
69 BAD_SW_IF_INDEX_LABEL;
71 REPLY_MACRO (VL_API_SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY);
74 static void *vl_api_sw_interface_set_dpdk_hqos_pipe_t_print
75 (vl_api_sw_interface_set_dpdk_hqos_pipe_t * mp, void *handle)
79 s = format (0, "SCRIPT: sw_interface_set_dpdk_hqos_pipe ");
81 s = format (s, "sw_if_index %u ", ntohl (mp->sw_if_index));
83 s = format (s, "subport %u pipe %u profile %u ",
84 ntohl (mp->subport), ntohl (mp->pipe), ntohl (mp->profile));
90 vl_api_sw_interface_set_dpdk_hqos_subport_t_handler
91 (vl_api_sw_interface_set_dpdk_hqos_subport_t * mp)
93 vl_api_sw_interface_set_dpdk_hqos_subport_reply_t *rmp;
96 dpdk_main_t *dm = &dpdk_main;
98 struct rte_sched_subport_params p;
100 u32 sw_if_index = ntohl (mp->sw_if_index);
101 u32 subport = ntohl (mp->subport);
102 p.tb_rate = ntohl (mp->tb_rate);
103 p.tb_size = ntohl (mp->tb_size);
104 p.tc_rate[0] = ntohl (mp->tc_rate[0]);
105 p.tc_rate[1] = ntohl (mp->tc_rate[1]);
106 p.tc_rate[2] = ntohl (mp->tc_rate[2]);
107 p.tc_rate[3] = ntohl (mp->tc_rate[3]);
108 p.tc_period = ntohl (mp->tc_period);
110 vnet_hw_interface_t *hw;
112 VALIDATE_SW_IF_INDEX (mp);
114 /* hw_if & dpdk device */
115 hw = vnet_get_sup_hw_interface (dm->vnet_main, sw_if_index);
117 xd = vec_elt_at_index (dm->devices, hw->dev_instance);
119 rv = rte_sched_subport_config (xd->hqos_ht->hqos, subport, &p);
121 BAD_SW_IF_INDEX_LABEL;
123 REPLY_MACRO (VL_API_SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY);
126 static void *vl_api_sw_interface_set_dpdk_hqos_subport_t_print
127 (vl_api_sw_interface_set_dpdk_hqos_subport_t * mp, void *handle)
131 s = format (0, "SCRIPT: sw_interface_set_dpdk_hqos_subport ");
133 s = format (s, "sw_if_index %u ", ntohl (mp->sw_if_index));
137 "subport %u rate %u bkt_size %u tc0 %u tc1 %u tc2 %u tc3 %u period %u",
138 ntohl (mp->subport), ntohl (mp->tb_rate), ntohl (mp->tb_size),
139 ntohl (mp->tc_rate[0]), ntohl (mp->tc_rate[1]),
140 ntohl (mp->tc_rate[2]), ntohl (mp->tc_rate[3]),
141 ntohl (mp->tc_period));
147 vl_api_sw_interface_set_dpdk_hqos_tctbl_t_handler
148 (vl_api_sw_interface_set_dpdk_hqos_tctbl_t * mp)
150 vl_api_sw_interface_set_dpdk_hqos_tctbl_reply_t *rmp;
153 dpdk_main_t *dm = &dpdk_main;
154 vlib_thread_main_t *tm = vlib_get_thread_main ();
157 u32 sw_if_index = ntohl (mp->sw_if_index);
158 u32 entry = ntohl (mp->entry);
159 u32 tc = ntohl (mp->tc);
160 u32 queue = ntohl (mp->queue);
163 vnet_hw_interface_t *hw;
165 VALIDATE_SW_IF_INDEX (mp);
167 /* hw_if & dpdk device */
168 hw = vnet_get_sup_hw_interface (dm->vnet_main, sw_if_index);
170 xd = vec_elt_at_index (dm->devices, hw->dev_instance);
172 if (tc >= RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE)
174 clib_warning ("invalid traffic class !!");
175 rv = VNET_API_ERROR_INVALID_VALUE;
178 if (queue >= RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS)
180 clib_warning ("invalid queue !!");
181 rv = VNET_API_ERROR_INVALID_VALUE;
185 /* Detect the set of worker threads */
186 uword *p = hash_get_mem (tm->thread_registrations_by_name, "workers");
190 clib_warning ("worker thread registration AWOL !!");
191 rv = VNET_API_ERROR_INVALID_VALUE_2;
195 vlib_thread_registration_t *tr = (vlib_thread_registration_t *) p[0];
196 int worker_thread_first = tr->first_index;
197 int worker_thread_count = tr->count;
199 val = tc * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + queue;
200 for (i = 0; i < worker_thread_count; i++)
201 xd->hqos_wt[worker_thread_first + i].hqos_tc_table[entry] = val;
203 BAD_SW_IF_INDEX_LABEL;
206 REPLY_MACRO (VL_API_SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY);
209 static void *vl_api_sw_interface_set_dpdk_hqos_tctbl_t_print
210 (vl_api_sw_interface_set_dpdk_hqos_tctbl_t * mp, void *handle)
214 s = format (0, "SCRIPT: sw_interface_set_dpdk_hqos_tctbl ");
216 s = format (s, "sw_if_index %u ", ntohl (mp->sw_if_index));
218 s = format (s, "entry %u tc %u queue %u",
219 ntohl (mp->entry), ntohl (mp->tc), ntohl (mp->queue));
224 #include <dpdk/api/dpdk.api.c>
225 static clib_error_t *
226 dpdk_api_init (vlib_main_t * vm)
228 dpdk_main_t *dm = &dpdk_main;
230 /* Ask for a correctly-sized block of API message decode slots */
231 dm->msg_id_base = setup_message_id_table ();
237 VLIB_INIT_FUNCTION (dpdk_api_init) =
239 .runs_after = VLIB_INITS ("dpdk_init"),
243 * fd.io coding-style-patch-verification: ON
246 * eval: (c-set-style "gnu")