blob: 8b22c650c82b8728d5c2fe05179a48a90ee860a8 [file] [log] [blame]
Damjan Marionc9037932017-04-27 21:12:17 +02001/*
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:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
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.
14 */
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>
20
21#include <vnet/ethernet/ethernet.h>
22#include <dpdk/device/dpdk.h>
Damjan Marionc9037932017-04-27 21:12:17 +020023#include <vlib/pci/pci.h>
24
25#include <stdio.h>
26#include <stdlib.h>
27#include <unistd.h>
28#include <sys/stat.h>
29#include <sys/mount.h>
30#include <string.h>
31#include <fcntl.h>
32
33#include <dpdk/device/dpdk_priv.h>
34
35#include <vlibapi/api.h>
36#include <vlibmemory/api.h>
37
38/* define message IDs */
Ole Troan025166d2019-10-02 17:17:58 +020039#include <dpdk/api/dpdk.api_enum.h>
40#include <dpdk/api/dpdk.api_types.h>
Damjan Marionc9037932017-04-27 21:12:17 +020041
42#include <vlibapi/api_helper_macros.h>
43
44static void
45 vl_api_sw_interface_set_dpdk_hqos_pipe_t_handler
46 (vl_api_sw_interface_set_dpdk_hqos_pipe_t * mp)
47{
48 vl_api_sw_interface_set_dpdk_hqos_pipe_reply_t *rmp;
49 int rv = 0;
50
51 dpdk_main_t *dm = &dpdk_main;
52 dpdk_device_t *xd;
53
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;
59
60 VALIDATE_SW_IF_INDEX (mp);
61
62 /* hw_if & dpdk device */
63 hw = vnet_get_sup_hw_interface (dm->vnet_main, sw_if_index);
64
65 xd = vec_elt_at_index (dm->devices, hw->dev_instance);
66
67 rv = rte_sched_pipe_config (xd->hqos_ht->hqos, subport, pipe, profile);
68
69 BAD_SW_IF_INDEX_LABEL;
70
71 REPLY_MACRO (VL_API_SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY);
72}
73
74static void *vl_api_sw_interface_set_dpdk_hqos_pipe_t_print
75 (vl_api_sw_interface_set_dpdk_hqos_pipe_t * mp, void *handle)
76{
77 u8 *s;
78
79 s = format (0, "SCRIPT: sw_interface_set_dpdk_hqos_pipe ");
80
81 s = format (s, "sw_if_index %u ", ntohl (mp->sw_if_index));
82
83 s = format (s, "subport %u pipe %u profile %u ",
84 ntohl (mp->subport), ntohl (mp->pipe), ntohl (mp->profile));
85
86 FINISH;
87}
88
89static void
90 vl_api_sw_interface_set_dpdk_hqos_subport_t_handler
91 (vl_api_sw_interface_set_dpdk_hqos_subport_t * mp)
92{
93 vl_api_sw_interface_set_dpdk_hqos_subport_reply_t *rmp;
94 int rv = 0;
95
96 dpdk_main_t *dm = &dpdk_main;
97 dpdk_device_t *xd;
98 struct rte_sched_subport_params p;
99
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);
109
110 vnet_hw_interface_t *hw;
111
112 VALIDATE_SW_IF_INDEX (mp);
113
114 /* hw_if & dpdk device */
115 hw = vnet_get_sup_hw_interface (dm->vnet_main, sw_if_index);
116
117 xd = vec_elt_at_index (dm->devices, hw->dev_instance);
118
119 rv = rte_sched_subport_config (xd->hqos_ht->hqos, subport, &p);
120
121 BAD_SW_IF_INDEX_LABEL;
122
123 REPLY_MACRO (VL_API_SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY);
124}
125
126static void *vl_api_sw_interface_set_dpdk_hqos_subport_t_print
127 (vl_api_sw_interface_set_dpdk_hqos_subport_t * mp, void *handle)
128{
129 u8 *s;
130
131 s = format (0, "SCRIPT: sw_interface_set_dpdk_hqos_subport ");
132
133 s = format (s, "sw_if_index %u ", ntohl (mp->sw_if_index));
134
135 s =
136 format (s,
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));
142
143 FINISH;
144}
145
146static void
147 vl_api_sw_interface_set_dpdk_hqos_tctbl_t_handler
148 (vl_api_sw_interface_set_dpdk_hqos_tctbl_t * mp)
149{
150 vl_api_sw_interface_set_dpdk_hqos_tctbl_reply_t *rmp;
151 int rv = 0;
152
153 dpdk_main_t *dm = &dpdk_main;
154 vlib_thread_main_t *tm = vlib_get_thread_main ();
155 dpdk_device_t *xd;
156
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);
161 u32 val, i;
162
163 vnet_hw_interface_t *hw;
164
165 VALIDATE_SW_IF_INDEX (mp);
166
167 /* hw_if & dpdk device */
168 hw = vnet_get_sup_hw_interface (dm->vnet_main, sw_if_index);
169
170 xd = vec_elt_at_index (dm->devices, hw->dev_instance);
171
172 if (tc >= RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE)
173 {
174 clib_warning ("invalid traffic class !!");
175 rv = VNET_API_ERROR_INVALID_VALUE;
176 goto done;
177 }
178 if (queue >= RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS)
179 {
180 clib_warning ("invalid queue !!");
181 rv = VNET_API_ERROR_INVALID_VALUE;
182 goto done;
183 }
184
185 /* Detect the set of worker threads */
186 uword *p = hash_get_mem (tm->thread_registrations_by_name, "workers");
187
188 if (p == 0)
189 {
190 clib_warning ("worker thread registration AWOL !!");
191 rv = VNET_API_ERROR_INVALID_VALUE_2;
192 goto done;
193 }
194
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;
198
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;
202
203 BAD_SW_IF_INDEX_LABEL;
204done:
205
206 REPLY_MACRO (VL_API_SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY);
207}
208
209static void *vl_api_sw_interface_set_dpdk_hqos_tctbl_t_print
210 (vl_api_sw_interface_set_dpdk_hqos_tctbl_t * mp, void *handle)
211{
212 u8 *s;
213
214 s = format (0, "SCRIPT: sw_interface_set_dpdk_hqos_tctbl ");
215
216 s = format (s, "sw_if_index %u ", ntohl (mp->sw_if_index));
217
218 s = format (s, "entry %u tc %u queue %u",
219 ntohl (mp->entry), ntohl (mp->tc), ntohl (mp->queue));
220
221 FINISH;
222}
223
Ole Troan025166d2019-10-02 17:17:58 +0200224#include <dpdk/api/dpdk.api.c>
Damjan Marionc9037932017-04-27 21:12:17 +0200225static clib_error_t *
226dpdk_api_init (vlib_main_t * vm)
227{
228 dpdk_main_t *dm = &dpdk_main;
Damjan Marionc9037932017-04-27 21:12:17 +0200229
230 /* Ask for a correctly-sized block of API message decode slots */
Ole Troan025166d2019-10-02 17:17:58 +0200231 dm->msg_id_base = setup_message_id_table ();
Damjan Marionc9037932017-04-27 21:12:17 +0200232
Ole Troan025166d2019-10-02 17:17:58 +0200233 return 0;
Damjan Marionc9037932017-04-27 21:12:17 +0200234}
235
Dave Barachf8d50682019-05-14 18:01:44 -0400236/* *INDENT-OFF* */
237VLIB_INIT_FUNCTION (dpdk_api_init) =
238{
239 .runs_after = VLIB_INITS ("dpdk_init"),
240/* *INDENT-OFF* */
Damjan Marionc9037932017-04-27 21:12:17 +0200241
242/*
243 * fd.io coding-style-patch-verification: ON
244 *
245 * Local Variables:
246 * eval: (c-set-style "gnu")
247 * End:
248 */