Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2017 Huawei Technologies Co., Ltd
3 : : */
4 : :
5 : : #include "hinic_compat.h"
6 : : #include "hinic_pmd_hwdev.h"
7 : : #include "hinic_pmd_hwif.h"
8 : : #include "hinic_pmd_eqs.h"
9 : : #include "hinic_pmd_wq.h"
10 : : #include "hinic_pmd_mgmt.h"
11 : : #include "hinic_pmd_cmdq.h"
12 : : #include "hinic_pmd_niccfg.h"
13 : : #include "hinic_pmd_mbox.h"
14 : :
15 : : #define l2nic_msg_to_mgmt_sync(hwdev, cmd, buf_in, \
16 : : in_size, buf_out, out_size) \
17 : : hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_L2NIC, cmd, \
18 : : buf_in, in_size, \
19 : : buf_out, out_size, 0)
20 : :
21 : : /**
22 : : * hinic_init_function_table - Initialize function table.
23 : : *
24 : : * @param hwdev
25 : : * The hardware interface of a nic device.
26 : : * @param rx_buf_sz
27 : : * Receive buffer size.
28 : : *
29 : : * @return
30 : : * 0 on success.
31 : : * negative error value otherwise.
32 : : */
33 : 0 : int hinic_init_function_table(void *hwdev, u16 rx_buf_sz)
34 : : {
35 : : struct hinic_function_table function_table;
36 : 0 : u16 out_size = sizeof(function_table);
37 : : int err;
38 : :
39 [ # # ]: 0 : if (!hwdev) {
40 : 0 : PMD_DRV_LOG(ERR, "Hwdev is NULL");
41 : 0 : return -EINVAL;
42 : : }
43 : :
44 : : memset(&function_table, 0, sizeof(function_table));
45 : 0 : function_table.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
46 : 0 : function_table.func_id = hinic_global_func_id(hwdev);
47 : 0 : function_table.mtu = 0x3FFF; /* default, max mtu */
48 : 0 : function_table.rx_wqe_buf_size = rx_buf_sz;
49 : :
50 : 0 : err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_L2NIC,
51 : : HINIC_PORT_CMD_INIT_FUNC,
52 : : &function_table, sizeof(function_table),
53 : : &function_table, &out_size, 0);
54 [ # # # # : 0 : if (err || function_table.mgmt_msg_head.status || !out_size) {
# # ]
55 : 0 : PMD_DRV_LOG(ERR,
56 : : "Failed to init func table, err: %d, status: 0x%x, out size: 0x%x",
57 : : err, function_table.mgmt_msg_head.status, out_size);
58 : 0 : return -EIO;
59 : : }
60 : :
61 : : return 0;
62 : : }
63 : :
64 : : /**
65 : : * hinic_get_base_qpn - Get global queue number.
66 : : *
67 : : * @param hwdev
68 : : * The hardware interface of a nic device.
69 : : * @param global_qpn
70 : : * Global queue number.
71 : : *
72 : : * @return
73 : : * 0 on success.
74 : : * negative error value otherwise.
75 : : */
76 : 0 : int hinic_get_base_qpn(void *hwdev, u16 *global_qpn)
77 : : {
78 : : struct hinic_cmd_qpn cmd_qpn;
79 : 0 : u16 out_size = sizeof(cmd_qpn);
80 : : int err;
81 : :
82 [ # # ]: 0 : if (!hwdev || !global_qpn) {
83 : 0 : PMD_DRV_LOG(ERR, "Hwdev or global_qpn is NULL");
84 : 0 : return -EINVAL;
85 : : }
86 : :
87 : : memset(&cmd_qpn, 0, sizeof(cmd_qpn));
88 : 0 : cmd_qpn.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
89 : 0 : cmd_qpn.func_id = hinic_global_func_id(hwdev);
90 : :
91 : 0 : err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_L2NIC,
92 : : HINIC_PORT_CMD_GET_GLOBAL_QPN,
93 : : &cmd_qpn, sizeof(cmd_qpn), &cmd_qpn,
94 : : &out_size, 0);
95 [ # # # # : 0 : if (err || !out_size || cmd_qpn.mgmt_msg_head.status) {
# # ]
96 : 0 : PMD_DRV_LOG(ERR,
97 : : "Failed to get base qpn, err: %d, status: 0x%x, out size: 0x%x",
98 : : err, cmd_qpn.mgmt_msg_head.status, out_size);
99 : 0 : return -EIO;
100 : : }
101 : :
102 : 0 : *global_qpn = cmd_qpn.base_qpn;
103 : :
104 : 0 : return 0;
105 : : }
106 : :
107 : : /**
108 : : * hinic_set_mac - Init mac_vlan table in NIC.
109 : : *
110 : : * @param hwdev
111 : : * The hardware interface of a nic device.
112 : : * @param mac_addr
113 : : * MAC address.
114 : : * @param vlan_id
115 : : * Set 0 for mac_vlan table initialization.
116 : : * @param func_id
117 : : * Global function id of NIC.
118 : : *
119 : : * @return
120 : : * 0 on success.
121 : : * negative error value otherwise.
122 : : */
123 : 0 : int hinic_set_mac(void *hwdev, u8 *mac_addr, u16 vlan_id, u16 func_id)
124 : : {
125 : : struct hinic_port_mac_set mac_info;
126 : 0 : u16 out_size = sizeof(mac_info);
127 : : int err;
128 : :
129 [ # # ]: 0 : if (!hwdev || !mac_addr) {
130 : 0 : PMD_DRV_LOG(ERR, "Hwdev or mac_addr is NULL");
131 : 0 : return -EINVAL;
132 : : }
133 : :
134 : : memset(&mac_info, 0, sizeof(mac_info));
135 : 0 : mac_info.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
136 : 0 : mac_info.func_id = func_id;
137 : 0 : mac_info.vlan_id = vlan_id;
138 : : memmove(mac_info.mac, mac_addr, ETH_ALEN);
139 : :
140 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_MAC, &mac_info,
141 : : sizeof(mac_info), &mac_info, &out_size);
142 [ # # # # : 0 : if (err || !out_size || (mac_info.mgmt_msg_head.status &&
# # ]
143 : : mac_info.mgmt_msg_head.status != HINIC_PF_SET_VF_ALREADY)) {
144 : 0 : PMD_DRV_LOG(ERR, "Failed to set MAC, err: %d, status: 0x%x, out size: 0x%x",
145 : : err, mac_info.mgmt_msg_head.status, out_size);
146 : 0 : return -EIO;
147 : : }
148 : :
149 [ # # ]: 0 : if (mac_info.mgmt_msg_head.status == HINIC_PF_SET_VF_ALREADY) {
150 : 0 : PMD_DRV_LOG(WARNING, "PF has already set vf mac, Ignore set operation.");
151 : 0 : return HINIC_PF_SET_VF_ALREADY;
152 : : }
153 : :
154 : : return 0;
155 : : }
156 : :
157 : : /**
158 : : * hinic_del_mac - Uninit mac_vlan table in NIC.
159 : : *
160 : : * @param hwdev
161 : : * The hardware interface of a nic device.
162 : : * @param mac_addr
163 : : * MAC address.
164 : : * @param vlan_id
165 : : * Set 0 for mac_vlan table initialization.
166 : : * @param func_id
167 : : * Global function id of NIC.
168 : : *
169 : : * @return
170 : : * 0 on success.
171 : : * negative error value otherwise.
172 : : */
173 : 0 : int hinic_del_mac(void *hwdev, u8 *mac_addr, u16 vlan_id, u16 func_id)
174 : : {
175 : : struct hinic_port_mac_set mac_info;
176 : 0 : u16 out_size = sizeof(mac_info);
177 : : int err;
178 : :
179 [ # # ]: 0 : if (!hwdev || !mac_addr) {
180 : 0 : PMD_DRV_LOG(ERR, "Hwdev or mac_addr is NULL");
181 : 0 : return -EINVAL;
182 : : }
183 : :
184 [ # # ]: 0 : if (vlan_id >= VLAN_N_VID) {
185 : 0 : PMD_DRV_LOG(ERR, "Invalid VLAN number");
186 : 0 : return -EINVAL;
187 : : }
188 : :
189 : : memset(&mac_info, 0, sizeof(mac_info));
190 : 0 : mac_info.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
191 : 0 : mac_info.func_id = func_id;
192 : 0 : mac_info.vlan_id = vlan_id;
193 : : memmove(mac_info.mac, mac_addr, ETH_ALEN);
194 : :
195 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_DEL_MAC, &mac_info,
196 : : sizeof(mac_info), &mac_info, &out_size);
197 [ # # # # : 0 : if (err || !out_size || (mac_info.mgmt_msg_head.status &&
# # ]
198 : : mac_info.mgmt_msg_head.status != HINIC_PF_SET_VF_ALREADY)) {
199 : 0 : PMD_DRV_LOG(ERR, "Failed to delete MAC, err: %d, status: 0x%x, out size: 0x%x",
200 : : err, mac_info.mgmt_msg_head.status, out_size);
201 : 0 : return -EIO;
202 : : }
203 [ # # ]: 0 : if (mac_info.mgmt_msg_head.status == HINIC_PF_SET_VF_ALREADY) {
204 : 0 : PMD_DRV_LOG(WARNING, "PF has already set vf mac, Ignore delete operation.");
205 : 0 : return HINIC_PF_SET_VF_ALREADY;
206 : : }
207 : :
208 : : return 0;
209 : : }
210 : :
211 : : /**
212 : : * hinic_get_default_mac - Get default mac address from hardware.
213 : : *
214 : : * @param hwdev
215 : : * The hardware interface of a nic device.
216 : : * @param mac_addr
217 : : * MAC address.
218 : : *
219 : : * @return
220 : : * 0 on success.
221 : : * negative error value otherwise.
222 : : */
223 : 0 : int hinic_get_default_mac(void *hwdev, u8 *mac_addr)
224 : : {
225 : : struct hinic_port_mac_set mac_info;
226 : 0 : u16 out_size = sizeof(mac_info);
227 : : int err;
228 : :
229 [ # # ]: 0 : if (!hwdev || !mac_addr) {
230 : 0 : PMD_DRV_LOG(ERR, "Hwdev or mac_addr is NULL");
231 : 0 : return -EINVAL;
232 : : }
233 : :
234 : : memset(&mac_info, 0, sizeof(mac_info));
235 : 0 : mac_info.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
236 : 0 : mac_info.func_id = hinic_global_func_id(hwdev);
237 : :
238 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_GET_MAC,
239 : : &mac_info, sizeof(mac_info),
240 : : &mac_info, &out_size);
241 [ # # # # : 0 : if (err || !out_size || mac_info.mgmt_msg_head.status) {
# # ]
242 : 0 : PMD_DRV_LOG(ERR, "Failed to get mac, err: %d, status: 0x%x, out size: 0x%x",
243 : : err, mac_info.mgmt_msg_head.status, out_size);
244 : 0 : return -EIO;
245 : : }
246 : :
247 : : memmove(mac_addr, mac_info.mac, ETH_ALEN);
248 : :
249 : 0 : return 0;
250 : : }
251 : :
252 : : /**
253 : : * hinic_update_mac - Update mac address to hardware.
254 : : *
255 : : * @param hwdev
256 : : * The hardware interface of a nic device.
257 : : * @param old_mac
258 : : * Old mac address.
259 : : * @param new_mac
260 : : * New mac address.
261 : : * @param vlan_id
262 : : * Set 0 for mac_vlan table initialization.
263 : : * @param func_id
264 : : * Global function id of NIC.
265 : : *
266 : : * @return
267 : : * 0 on success.
268 : : * negative error value otherwise.
269 : : */
270 : 0 : int hinic_update_mac(void *hwdev, u8 *old_mac, u8 *new_mac, u16 vlan_id,
271 : : u16 func_id)
272 : : {
273 : : struct hinic_port_mac_update mac_info;
274 : 0 : u16 out_size = sizeof(mac_info);
275 : : int err;
276 : :
277 [ # # # # ]: 0 : if (!hwdev || !old_mac || !new_mac) {
278 : 0 : PMD_DRV_LOG(ERR, "Hwdev, old_mac or new_mac is NULL");
279 : 0 : return -EINVAL;
280 : : }
281 : :
282 : : memset(&mac_info, 0, sizeof(mac_info));
283 : 0 : mac_info.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
284 : 0 : mac_info.func_id = func_id;
285 : 0 : mac_info.vlan_id = vlan_id;
286 : : memcpy(mac_info.old_mac, old_mac, ETH_ALEN);
287 : : memcpy(mac_info.new_mac, new_mac, ETH_ALEN);
288 : :
289 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_UPDATE_MAC,
290 : : &mac_info, sizeof(mac_info),
291 : : &mac_info, &out_size);
292 [ # # # # ]: 0 : if (err || !out_size ||
293 [ # # ]: 0 : (mac_info.mgmt_msg_head.status &&
294 : : mac_info.mgmt_msg_head.status != HINIC_PF_SET_VF_ALREADY)) {
295 : 0 : PMD_DRV_LOG(ERR, "Failed to update MAC, err: %d, status: 0x%x, out size: 0x%x",
296 : : err, mac_info.mgmt_msg_head.status, out_size);
297 : 0 : return -EIO;
298 : : }
299 [ # # ]: 0 : if (mac_info.mgmt_msg_head.status == HINIC_PF_SET_VF_ALREADY) {
300 : 0 : PMD_DRV_LOG(WARNING, "PF has already set vf mac, Ignore update operation");
301 : 0 : return HINIC_PF_SET_VF_ALREADY;
302 : : }
303 : :
304 : : return 0;
305 : : }
306 : :
307 : : /**
308 : : * hinic_set_port_mtu - Set MTU to port.
309 : : *
310 : : * @param hwdev
311 : : * The hardware interface of a nic device.
312 : : * @param new_mtu
313 : : * MTU size.
314 : : *
315 : : * @return
316 : : * 0 on success.
317 : : * negative error value otherwise.
318 : : */
319 : 0 : int hinic_set_port_mtu(void *hwdev, u32 new_mtu)
320 : : {
321 : : struct hinic_mtu mtu_info;
322 : 0 : u16 out_size = sizeof(mtu_info);
323 : : int err;
324 : :
325 [ # # ]: 0 : if (!hwdev) {
326 : 0 : PMD_DRV_LOG(ERR, "Hwdev is NULL");
327 : 0 : return -EINVAL;
328 : : }
329 : :
330 : : memset(&mtu_info, 0, sizeof(mtu_info));
331 : 0 : mtu_info.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
332 : 0 : mtu_info.func_id = hinic_global_func_id(hwdev);
333 : 0 : mtu_info.mtu = new_mtu;
334 : :
335 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_CHANGE_MTU,
336 : : &mtu_info, sizeof(mtu_info),
337 : : &mtu_info, &out_size);
338 [ # # # # : 0 : if (err || !out_size || mtu_info.mgmt_msg_head.status) {
# # ]
339 : 0 : PMD_DRV_LOG(ERR, "Failed to set mtu, err: %d, status: 0x%x, out size: 0x%x",
340 : : err, mtu_info.mgmt_msg_head.status, out_size);
341 : 0 : return -EIO;
342 : : }
343 : :
344 : : return 0;
345 : : }
346 : :
347 : : /**
348 : : * hinic_add_remove_vlan - Add or remove vlan id to vlan elb table.
349 : : *
350 : : * @param hwdev
351 : : * The hardware interface of a nic device.
352 : : * @param vlan_id
353 : : * Vlan id.
354 : : * @param func_id
355 : : * Global function id of NIC.
356 : : * @param add
357 : : * Add or remove operation.
358 : : *
359 : : * @return
360 : : * 0 on success.
361 : : * negative error value otherwise.
362 : : */
363 : 0 : int hinic_add_remove_vlan(void *hwdev, u16 vlan_id, u16 func_id, bool add)
364 : : {
365 : : struct hinic_vlan_config vlan_info;
366 : 0 : u16 out_size = sizeof(vlan_info);
367 : : u8 cmd;
368 : : int err;
369 : :
370 [ # # ]: 0 : if (!hwdev) {
371 : 0 : PMD_DRV_LOG(ERR, "Hwdev is NULL");
372 : 0 : return -EINVAL;
373 : : }
374 : :
375 [ # # ]: 0 : cmd = add ? HINIC_PORT_CMD_ADD_VLAN : HINIC_PORT_CMD_DEL_VLAN;
376 : :
377 : : memset(&vlan_info, 0, sizeof(vlan_info));
378 : 0 : vlan_info.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
379 : 0 : vlan_info.func_id = func_id;
380 : 0 : vlan_info.vlan_id = vlan_id;
381 : :
382 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, cmd, &vlan_info, sizeof(vlan_info),
383 : : &vlan_info, &out_size);
384 [ # # # # : 0 : if (err || !out_size || vlan_info.mgmt_msg_head.status) {
# # ]
385 [ # # ]: 0 : PMD_DRV_LOG(ERR,
386 : : "Failed to %s vlan, err: %d, status: 0x%x, out size: 0x%x",
387 : : add ? "add" : "remove", err,
388 : : vlan_info.mgmt_msg_head.status, out_size);
389 : 0 : return -EIO;
390 : : }
391 : :
392 : : return 0;
393 : : }
394 : :
395 : : /**
396 : : * hinic_config_vlan_filter - Enable or Disable vlan filter.
397 : : *
398 : : * @param hwdev
399 : : * The hardware interface of a nic device.
400 : : * @param vlan_filter_ctrl
401 : : * Enable or Disable.
402 : : *
403 : : * @return
404 : : * 0 on success.
405 : : * negative error value otherwise.
406 : : */
407 : 0 : int hinic_config_vlan_filter(void *hwdev, u32 vlan_filter_ctrl)
408 : : {
409 : : struct hinic_hwdev *nic_hwdev = (struct hinic_hwdev *)hwdev;
410 : : struct hinic_vlan_filter vlan_filter;
411 : 0 : u16 out_size = sizeof(vlan_filter);
412 : : int err;
413 : :
414 [ # # ]: 0 : if (!hwdev)
415 : : return -EINVAL;
416 : :
417 : : memset(&vlan_filter, 0, sizeof(vlan_filter));
418 : 0 : vlan_filter.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
419 : 0 : vlan_filter.func_id = hinic_global_func_id(nic_hwdev);
420 : 0 : vlan_filter.vlan_filter_ctrl = vlan_filter_ctrl;
421 : :
422 : 0 : err = l2nic_msg_to_mgmt_sync(nic_hwdev, HINIC_PORT_CMD_SET_VLAN_FILTER,
423 : : &vlan_filter, sizeof(vlan_filter),
424 : : &vlan_filter, &out_size);
425 [ # # ]: 0 : if (vlan_filter.mgmt_msg_head.status == HINIC_MGMT_CMD_UNSUPPORTED) {
426 : : err = HINIC_MGMT_CMD_UNSUPPORTED;
427 [ # # ]: 0 : } else if ((err == HINIC_MBOX_VF_CMD_ERROR) &&
428 [ # # ]: 0 : (HINIC_IS_VF(nic_hwdev))) {
429 : : err = HINIC_MGMT_CMD_UNSUPPORTED;
430 [ # # # # : 0 : } else if (err || !out_size || vlan_filter.mgmt_msg_head.status) {
# # ]
431 : 0 : PMD_DRV_LOG(ERR,
432 : : "Failed to config vlan filter, vlan_filter_ctrl: 0x%x, err: %d, status: 0x%x, out size: 0x%x",
433 : : vlan_filter_ctrl, err,
434 : : vlan_filter.mgmt_msg_head.status, out_size);
435 : : err = -EIO;
436 : : }
437 : :
438 : : return err;
439 : : }
440 : :
441 : : /**
442 : : * hinic_set_rx_vlan_offload - Enable or Disable vlan offload.
443 : : *
444 : : * @param hwdev
445 : : * The hardware interface of a nic device.
446 : : * @param en
447 : : * Enable or Disable.
448 : : *
449 : : * @return
450 : : * 0 on success.
451 : : * negative error value otherwise.
452 : : */
453 : 0 : int hinic_set_rx_vlan_offload(void *hwdev, u8 en)
454 : : {
455 : : struct hinic_vlan_offload vlan_cfg;
456 : 0 : u16 out_size = sizeof(vlan_cfg);
457 : : int err;
458 : :
459 [ # # ]: 0 : if (!hwdev) {
460 : 0 : PMD_DRV_LOG(ERR, "Hwdev is NULL");
461 : 0 : return -EINVAL;
462 : : }
463 : :
464 : : memset(&vlan_cfg, 0, sizeof(vlan_cfg));
465 : 0 : vlan_cfg.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
466 : 0 : vlan_cfg.func_id = hinic_global_func_id(hwdev);
467 : 0 : vlan_cfg.vlan_rx_offload = en;
468 : :
469 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_RX_VLAN_OFFLOAD,
470 : : &vlan_cfg, sizeof(vlan_cfg),
471 : : &vlan_cfg, &out_size);
472 [ # # # # : 0 : if (err || !out_size || vlan_cfg.mgmt_msg_head.status) {
# # ]
473 : 0 : PMD_DRV_LOG(ERR,
474 : : "Failed to set rx vlan offload, err: %d, status: 0x%x, out size: 0x%x",
475 : : err, vlan_cfg.mgmt_msg_head.status, out_size);
476 : 0 : return -EIO;
477 : : }
478 : :
479 : : return 0;
480 : : }
481 : :
482 : : /**
483 : : * hinic_get_link_status - Get link status from hardware.
484 : : *
485 : : * @param hwdev
486 : : * The hardware interface of a nic device.
487 : : * @param link_state
488 : : * Link status.
489 : : *
490 : : * @return
491 : : * 0 on success.
492 : : * negative error value otherwise.
493 : : */
494 : 0 : int hinic_get_link_status(void *hwdev, u8 *link_state)
495 : : {
496 : : struct hinic_get_link get_link;
497 : 0 : u16 out_size = sizeof(get_link);
498 : : int err;
499 : :
500 [ # # ]: 0 : if (!hwdev || !link_state) {
501 : 0 : PMD_DRV_LOG(ERR, "Hwdev or link_state is NULL");
502 : 0 : return -EINVAL;
503 : : }
504 : :
505 : : memset(&get_link, 0, sizeof(get_link));
506 : 0 : get_link.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
507 : 0 : get_link.func_id = hinic_global_func_id(hwdev);
508 : :
509 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_GET_LINK_STATE,
510 : : &get_link, sizeof(get_link),
511 : : &get_link, &out_size);
512 [ # # # # : 0 : if (err || !out_size || get_link.mgmt_msg_head.status) {
# # ]
513 : 0 : PMD_DRV_LOG(ERR, "Failed to get link state, err: %d, status: 0x%x, out size: 0x%x",
514 : : err, get_link.mgmt_msg_head.status, out_size);
515 : 0 : return -EIO;
516 : : }
517 : :
518 : 0 : *link_state = get_link.link_status;
519 : :
520 : 0 : return 0;
521 : : }
522 : :
523 : : /**
524 : : * hinic_set_vport_enable - Notify firmware that driver is ready or not.
525 : : *
526 : : * @param hwdev
527 : : * The hardware interface of a nic device.
528 : : * @param enable
529 : : * 1: driver is ready; 0: driver is not ok.
530 : : *
531 : : * @return
532 : : * 0 on success.
533 : : * negative error value otherwise.
534 : : */
535 : 0 : int hinic_set_vport_enable(void *hwdev, bool enable)
536 : : {
537 : : struct hinic_vport_state en_state;
538 : 0 : u16 out_size = sizeof(en_state);
539 : : int err;
540 : :
541 [ # # ]: 0 : if (!hwdev) {
542 : 0 : PMD_DRV_LOG(ERR, "Hwdev is NULL");
543 : 0 : return -EINVAL;
544 : : }
545 : :
546 : : memset(&en_state, 0, sizeof(en_state));
547 : 0 : en_state.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
548 : 0 : en_state.func_id = hinic_global_func_id(hwdev);
549 : 0 : en_state.state = (enable ? 1 : 0);
550 : :
551 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_VPORT_ENABLE,
552 : : &en_state, sizeof(en_state),
553 : : &en_state, &out_size);
554 [ # # # # : 0 : if (err || !out_size || en_state.mgmt_msg_head.status) {
# # ]
555 : 0 : PMD_DRV_LOG(ERR, "Failed to set vport state, err: %d, status: 0x%x, out size: 0x%x",
556 : : err, en_state.mgmt_msg_head.status, out_size);
557 : 0 : return -EIO;
558 : : }
559 : :
560 : : return 0;
561 : : }
562 : :
563 : : /**
564 : : * hinic_set_port_enable - Open MAG to receive packets.
565 : : *
566 : : * @param hwdev
567 : : * The hardware interface of a nic device.
568 : : * @param enable
569 : : * 1: open MAG; 0: close MAG.
570 : : *
571 : : * @return
572 : : * 0 on success.
573 : : * negative error value otherwise.
574 : : */
575 : 0 : int hinic_set_port_enable(void *hwdev, bool enable)
576 : : {
577 : : struct hinic_port_state en_state;
578 : 0 : u16 out_size = sizeof(en_state);
579 : : int err;
580 : :
581 [ # # ]: 0 : if (!hwdev) {
582 : 0 : PMD_DRV_LOG(ERR, "Hwdev is NULL");
583 : 0 : return -EINVAL;
584 : : }
585 : :
586 [ # # ]: 0 : if (HINIC_IS_VF((struct hinic_hwdev *)hwdev))
587 : : return 0;
588 : :
589 : : memset(&en_state, 0, sizeof(en_state));
590 : 0 : en_state.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
591 [ # # ]: 0 : en_state.state = (enable ? HINIC_PORT_ENABLE : HINIC_PORT_DISABLE);
592 : :
593 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_PORT_ENABLE,
594 : : &en_state, sizeof(en_state),
595 : : &en_state, &out_size);
596 [ # # # # : 0 : if (err || !out_size || en_state.mgmt_msg_head.status) {
# # ]
597 : 0 : PMD_DRV_LOG(ERR, "Failed to set phy port state, err: %d, status: 0x%x, out size: 0x%x",
598 : : err, en_state.mgmt_msg_head.status, out_size);
599 : 0 : return -EIO;
600 : : }
601 : :
602 : : return 0;
603 : : }
604 : :
605 : 0 : int hinic_get_port_info(void *hwdev, struct nic_port_info *port_info)
606 : : {
607 : : struct hinic_port_info port_msg;
608 : 0 : u16 out_size = sizeof(port_msg);
609 : : int err;
610 : :
611 [ # # ]: 0 : if (!hwdev || !port_info) {
612 : 0 : PMD_DRV_LOG(ERR, "Hwdev or port_info is NULL");
613 : 0 : return -EINVAL;
614 : : }
615 : :
616 : : memset(&port_msg, 0, sizeof(port_msg));
617 : 0 : port_msg.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
618 : 0 : port_msg.func_id = hinic_global_func_id(hwdev);
619 : :
620 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_GET_PORT_INFO,
621 : : &port_msg, sizeof(port_msg),
622 : : &port_msg, &out_size);
623 [ # # # # : 0 : if (err || !out_size || port_msg.mgmt_msg_head.status) {
# # ]
624 : 0 : PMD_DRV_LOG(ERR,
625 : : "Failed to get port info, err: %d, status: 0x%x, out size: 0x%x",
626 : : err, port_msg.mgmt_msg_head.status, out_size);
627 : 0 : return -EIO;
628 : : }
629 : :
630 : 0 : port_info->autoneg_cap = port_msg.autoneg_cap;
631 : 0 : port_info->autoneg_state = port_msg.autoneg_state;
632 : 0 : port_info->duplex = port_msg.duplex;
633 : 0 : port_info->port_type = port_msg.port_type;
634 : 0 : port_info->speed = port_msg.speed;
635 : :
636 : 0 : return 0;
637 : : }
638 : :
639 : 0 : int hinic_set_pause_config(void *hwdev, struct nic_pause_config nic_pause)
640 : : {
641 : : struct hinic_pause_config pause_info;
642 : 0 : u16 out_size = sizeof(pause_info);
643 : : int err;
644 : :
645 [ # # ]: 0 : if (!hwdev) {
646 : 0 : PMD_DRV_LOG(ERR, "Hwdev is NULL");
647 : 0 : return -EINVAL;
648 : : }
649 : :
650 : : memset(&pause_info, 0, sizeof(pause_info));
651 : 0 : pause_info.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
652 : 0 : pause_info.func_id = hinic_global_func_id(hwdev);
653 : 0 : pause_info.auto_neg = nic_pause.auto_neg;
654 : 0 : pause_info.rx_pause = nic_pause.rx_pause;
655 : 0 : pause_info.tx_pause = nic_pause.tx_pause;
656 : :
657 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_PAUSE_INFO,
658 : : &pause_info, sizeof(pause_info),
659 : : &pause_info, &out_size);
660 [ # # # # : 0 : if (err || !out_size || pause_info.mgmt_msg_head.status) {
# # ]
661 : 0 : PMD_DRV_LOG(ERR, "Failed to set pause info, err: %d, status: 0x%x, out size: 0x%x",
662 : : err, pause_info.mgmt_msg_head.status, out_size);
663 : 0 : return -EIO;
664 : : }
665 : :
666 : : return 0;
667 : : }
668 : :
669 : 0 : int hinic_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause)
670 : : {
671 : : struct hinic_pause_config pause_info;
672 : 0 : u16 out_size = sizeof(pause_info);
673 : : int err;
674 : :
675 [ # # ]: 0 : if (!hwdev || !nic_pause)
676 : : return -EINVAL;
677 : :
678 : : memset(&pause_info, 0, sizeof(pause_info));
679 : 0 : pause_info.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
680 : 0 : pause_info.func_id = hinic_global_func_id(hwdev);
681 : :
682 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_GET_PAUSE_INFO,
683 : : &pause_info, sizeof(pause_info),
684 : : &pause_info, &out_size);
685 [ # # # # : 0 : if (err || !out_size || pause_info.mgmt_msg_head.status) {
# # ]
686 : 0 : PMD_DRV_LOG(ERR, "Failed to get pause info, err: %d, status: 0x%x, out size: 0x%x\n",
687 : : err, pause_info.mgmt_msg_head.status, out_size);
688 : 0 : return -EIO;
689 : : }
690 : :
691 : 0 : nic_pause->auto_neg = pause_info.auto_neg;
692 : 0 : nic_pause->rx_pause = pause_info.rx_pause;
693 : 0 : nic_pause->tx_pause = pause_info.tx_pause;
694 : :
695 : 0 : return 0;
696 : : }
697 : :
698 : 0 : int hinic_dcb_set_ets(void *hwdev, u8 *up_tc, u8 *pg_bw,
699 : : u8 *pgid, u8 *up_bw, u8 *prio)
700 : : {
701 : : struct hinic_up_ets_cfg ets;
702 : 0 : u16 out_size = sizeof(ets);
703 : : u16 up_bw_t = 0;
704 : : u8 pg_bw_t = 0;
705 : : int i, err;
706 : :
707 [ # # # # : 0 : if (!hwdev || !up_tc || !pg_bw || !pgid || !up_bw || !prio) {
# # ]
708 : 0 : PMD_DRV_LOG(ERR, "Hwdev, up_tc, pg_bw, pgid, up_bw or prio is NULL");
709 : 0 : return -EINVAL;
710 : : }
711 : :
712 [ # # ]: 0 : for (i = 0; i < HINIC_DCB_TC_MAX; i++) {
713 : 0 : up_bw_t += *(up_bw + i);
714 : 0 : pg_bw_t += *(pg_bw + i);
715 : :
716 [ # # ]: 0 : if (*(up_tc + i) > HINIC_DCB_TC_MAX) {
717 : 0 : PMD_DRV_LOG(ERR, "Invalid up %d mapping tc: %d", i,
718 : : *(up_tc + i));
719 : 0 : return -EINVAL;
720 : : }
721 : : }
722 : :
723 [ # # # # ]: 0 : if (pg_bw_t != 100 || (up_bw_t % 100) != 0) {
724 : 0 : PMD_DRV_LOG(ERR,
725 : : "Invalid pg_bw: %d or up_bw: %d", pg_bw_t, up_bw_t);
726 : 0 : return -EINVAL;
727 : : }
728 : :
729 : : memset(&ets, 0, sizeof(ets));
730 : 0 : ets.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
731 : : ets.port_id = 0; /* reserved */
732 : : memcpy(ets.up_tc, up_tc, HINIC_DCB_TC_MAX);
733 : : memcpy(ets.pg_bw, pg_bw, HINIC_DCB_UP_MAX);
734 : : memcpy(ets.pgid, pgid, HINIC_DCB_UP_MAX);
735 : : memcpy(ets.up_bw, up_bw, HINIC_DCB_UP_MAX);
736 : : memcpy(ets.prio, prio, HINIC_DCB_UP_MAX);
737 : :
738 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_ETS,
739 : : &ets, sizeof(ets), &ets, &out_size);
740 [ # # # # : 0 : if (err || ets.mgmt_msg_head.status || !out_size) {
# # ]
741 : 0 : PMD_DRV_LOG(ERR,
742 : : "Failed to set ets, err: %d, status: 0x%x, out size: 0x%x",
743 : : err, ets.mgmt_msg_head.status, out_size);
744 : 0 : return -EIO;
745 : : }
746 : :
747 : : return 0;
748 : : }
749 : :
750 : 0 : int hinic_get_vport_stats(void *hwdev, struct hinic_vport_stats *stats)
751 : : {
752 : : struct hinic_port_stats_info vport_stats_cmd;
753 : : struct hinic_cmd_vport_stats vport_stats_rsp;
754 : 0 : u16 out_size = sizeof(vport_stats_rsp);
755 : : int err;
756 : :
757 [ # # ]: 0 : if (!hwdev || !stats) {
758 : 0 : PMD_DRV_LOG(ERR, "Hwdev or stats is NULL");
759 : 0 : return -EINVAL;
760 : : }
761 : :
762 : : memset(&vport_stats_rsp, 0, sizeof(vport_stats_rsp));
763 : : memset(&vport_stats_cmd, 0, sizeof(vport_stats_cmd));
764 : 0 : vport_stats_cmd.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
765 : : vport_stats_cmd.stats_version = HINIC_PORT_STATS_VERSION;
766 : 0 : vport_stats_cmd.func_id = hinic_global_func_id(hwdev);
767 : 0 : vport_stats_cmd.stats_size = sizeof(vport_stats_rsp);
768 : :
769 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_GET_VPORT_STAT,
770 : : &vport_stats_cmd, sizeof(vport_stats_cmd),
771 : : &vport_stats_rsp, &out_size);
772 [ # # # # : 0 : if (err || !out_size || vport_stats_rsp.mgmt_msg_head.status) {
# # ]
773 : 0 : PMD_DRV_LOG(ERR,
774 : : "Get vport stats from fw failed, err: %d, status: 0x%x, out size: 0x%x",
775 : : err, vport_stats_rsp.mgmt_msg_head.status, out_size);
776 : 0 : return -EIO;
777 : : }
778 : :
779 : : memcpy(stats, &vport_stats_rsp.stats, sizeof(*stats));
780 : :
781 : 0 : return 0;
782 : : }
783 : :
784 : 0 : int hinic_get_phy_port_stats(void *hwdev, struct hinic_phy_port_stats *stats)
785 : : {
786 : : struct hinic_port_stats_info port_stats_cmd;
787 : : struct hinic_port_stats port_stats_rsp;
788 : 0 : u16 out_size = sizeof(port_stats_rsp);
789 : : int err;
790 : :
791 [ # # ]: 0 : if (!hwdev || !stats) {
792 : 0 : PMD_DRV_LOG(ERR, "Hwdev or stats is NULL");
793 : 0 : return -EINVAL;
794 : : }
795 : :
796 : : memset(&port_stats_rsp, 0, sizeof(port_stats_rsp));
797 : : memset(&port_stats_cmd, 0, sizeof(port_stats_cmd));
798 : 0 : port_stats_cmd.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
799 : : port_stats_cmd.stats_version = HINIC_PORT_STATS_VERSION;
800 : 0 : port_stats_cmd.stats_size = sizeof(port_stats_rsp);
801 : :
802 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_GET_PORT_STATISTICS,
803 : : &port_stats_cmd, sizeof(port_stats_cmd),
804 : : &port_stats_rsp, &out_size);
805 [ # # # # : 0 : if (err || !out_size || port_stats_rsp.mgmt_msg_head.status) {
# # ]
806 : 0 : PMD_DRV_LOG(ERR,
807 : : "Failed to get port statistics, err: %d, status: 0x%x, out size: 0x%x",
808 : : err, port_stats_rsp.mgmt_msg_head.status, out_size);
809 : 0 : return -EIO;
810 : : }
811 : :
812 : : memcpy(stats, &port_stats_rsp.stats, sizeof(*stats));
813 : :
814 : 0 : return 0;
815 : : }
816 : :
817 : 0 : int hinic_set_rss_type(void *hwdev, u32 tmpl_idx, struct nic_rss_type rss_type)
818 : : {
819 : : struct nic_rss_context_tbl *ctx_tbl;
820 : : struct hinic_cmd_buf *cmd_buf;
821 : : u32 ctx = 0;
822 : : u64 out_param;
823 : : int err;
824 : :
825 [ # # ]: 0 : if (!hwdev) {
826 : 0 : PMD_DRV_LOG(ERR, "Hwdev is NULL");
827 : 0 : return -EINVAL;
828 : : }
829 : :
830 : 0 : cmd_buf = hinic_alloc_cmd_buf(hwdev);
831 [ # # ]: 0 : if (!cmd_buf) {
832 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate cmd buf");
833 : 0 : return -ENOMEM;
834 : : }
835 : :
836 : 0 : ctx |= HINIC_RSS_TYPE_SET(1, VALID) |
837 : 0 : HINIC_RSS_TYPE_SET(rss_type.ipv4, IPV4) |
838 : 0 : HINIC_RSS_TYPE_SET(rss_type.ipv6, IPV6) |
839 : 0 : HINIC_RSS_TYPE_SET(rss_type.ipv6_ext, IPV6_EXT) |
840 : 0 : HINIC_RSS_TYPE_SET(rss_type.tcp_ipv4, TCP_IPV4) |
841 : 0 : HINIC_RSS_TYPE_SET(rss_type.tcp_ipv6, TCP_IPV6) |
842 : 0 : HINIC_RSS_TYPE_SET(rss_type.tcp_ipv6_ext, TCP_IPV6_EXT) |
843 : 0 : HINIC_RSS_TYPE_SET(rss_type.udp_ipv4, UDP_IPV4) |
844 : 0 : HINIC_RSS_TYPE_SET(rss_type.udp_ipv6, UDP_IPV6);
845 : :
846 : 0 : cmd_buf->size = sizeof(struct nic_rss_context_tbl);
847 : :
848 : 0 : ctx_tbl = (struct nic_rss_context_tbl *)cmd_buf->buf;
849 [ # # ]: 0 : ctx_tbl->group_index = cpu_to_be32(tmpl_idx);
850 : 0 : ctx_tbl->offset = 0;
851 : : ctx_tbl->size = sizeof(u32);
852 : 0 : ctx_tbl->size = cpu_to_be32(ctx_tbl->size);
853 : 0 : ctx_tbl->rsvd = 0;
854 [ # # ]: 0 : ctx_tbl->ctx = cpu_to_be32(ctx);
855 : :
856 : : /* cfg the rss context table by command queue */
857 : 0 : err = hinic_cmdq_direct_resp(hwdev, HINIC_ACK_TYPE_CMDQ,
858 : : HINIC_MOD_L2NIC,
859 : : HINIC_UCODE_CMD_SET_RSS_CONTEXT_TABLE,
860 : : cmd_buf, &out_param, 0);
861 : :
862 : 0 : hinic_free_cmd_buf(hwdev, cmd_buf);
863 : :
864 [ # # # # ]: 0 : if (err || out_param != 0) {
865 : 0 : PMD_DRV_LOG(ERR, "Failed to set rss context table");
866 : 0 : return -EIO;
867 : : }
868 : :
869 : : return 0;
870 : : }
871 : :
872 : 0 : int hinic_get_rss_type(void *hwdev, u32 tmpl_idx, struct nic_rss_type *rss_type)
873 : : {
874 : : struct hinic_rss_context_table ctx_tbl;
875 : 0 : u16 out_size = sizeof(ctx_tbl);
876 : : int err;
877 : :
878 [ # # ]: 0 : if (!hwdev || !rss_type) {
879 : 0 : PMD_DRV_LOG(ERR, "Hwdev or rss_type is NULL");
880 : 0 : return -EINVAL;
881 : : }
882 : :
883 : 0 : ctx_tbl.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
884 : 0 : ctx_tbl.func_id = hinic_global_func_id(hwdev);
885 : 0 : ctx_tbl.template_id = (u8)tmpl_idx;
886 : :
887 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_GET_RSS_CTX_TBL,
888 : : &ctx_tbl, sizeof(ctx_tbl),
889 : : &ctx_tbl, &out_size);
890 [ # # # # : 0 : if (err || !out_size || ctx_tbl.mgmt_msg_head.status) {
# # ]
891 : 0 : PMD_DRV_LOG(ERR,
892 : : "Failed to get hash type, err: %d, status: 0x%x, out size: 0x%x",
893 : : err, ctx_tbl.mgmt_msg_head.status, out_size);
894 : 0 : return -EIO;
895 : : }
896 : :
897 : 0 : rss_type->ipv4 = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV4);
898 : 0 : rss_type->ipv6 = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV6);
899 : 0 : rss_type->ipv6_ext = HINIC_RSS_TYPE_GET(ctx_tbl.context, IPV6_EXT);
900 : 0 : rss_type->tcp_ipv4 = HINIC_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV4);
901 : 0 : rss_type->tcp_ipv6 = HINIC_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV6);
902 : 0 : rss_type->tcp_ipv6_ext =
903 : 0 : HINIC_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV6_EXT);
904 : 0 : rss_type->udp_ipv4 = HINIC_RSS_TYPE_GET(ctx_tbl.context, UDP_IPV4);
905 : 0 : rss_type->udp_ipv6 = HINIC_RSS_TYPE_GET(ctx_tbl.context, UDP_IPV6);
906 : :
907 : 0 : return 0;
908 : : }
909 : :
910 : 0 : int hinic_rss_set_template_tbl(void *hwdev, u32 tmpl_idx, u8 *temp)
911 : : {
912 : : struct hinic_rss_template_key temp_key;
913 : 0 : u16 out_size = sizeof(temp_key);
914 : : int err;
915 : :
916 [ # # ]: 0 : if (!hwdev || !temp) {
917 : 0 : PMD_DRV_LOG(ERR, "Hwdev or temp is NULL");
918 : 0 : return -EINVAL;
919 : : }
920 : :
921 : : memset(&temp_key, 0, sizeof(temp_key));
922 : 0 : temp_key.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
923 : 0 : temp_key.func_id = hinic_global_func_id(hwdev);
924 : 0 : temp_key.template_id = (u8)tmpl_idx;
925 : : memcpy(temp_key.key, temp, HINIC_RSS_KEY_SIZE);
926 : :
927 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_RSS_TEMPLATE_TBL,
928 : : &temp_key, sizeof(temp_key),
929 : : &temp_key, &out_size);
930 [ # # # # : 0 : if (err || !out_size || temp_key.mgmt_msg_head.status) {
# # ]
931 : 0 : PMD_DRV_LOG(ERR,
932 : : "Failed to set hash key, err: %d, status: 0x%x, out size: 0x%x",
933 : : err, temp_key.mgmt_msg_head.status, out_size);
934 : 0 : return -EIO;
935 : : }
936 : :
937 : : return 0;
938 : : }
939 : :
940 : 0 : int hinic_rss_get_template_tbl(void *hwdev, u32 tmpl_idx, u8 *temp)
941 : : {
942 : : struct hinic_rss_template_key temp_key;
943 : 0 : u16 out_size = sizeof(temp_key);
944 : : int err;
945 : :
946 [ # # ]: 0 : if (!hwdev || !temp) {
947 : 0 : PMD_DRV_LOG(ERR, "Hwdev or temp is NULL");
948 : 0 : return -EINVAL;
949 : : }
950 : :
951 : : memset(&temp_key, 0, sizeof(temp_key));
952 : 0 : temp_key.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
953 : 0 : temp_key.func_id = hinic_global_func_id(hwdev);
954 : 0 : temp_key.template_id = (u8)tmpl_idx;
955 : :
956 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_GET_RSS_TEMPLATE_TBL,
957 : : &temp_key, sizeof(temp_key),
958 : : &temp_key, &out_size);
959 [ # # # # : 0 : if (err || !out_size || temp_key.mgmt_msg_head.status) {
# # ]
960 : 0 : PMD_DRV_LOG(ERR, "Failed to get hash key, err: %d, status: 0x%x, out size: 0x%x",
961 : : err, temp_key.mgmt_msg_head.status, out_size);
962 : 0 : return -EIO;
963 : : }
964 : :
965 : : memcpy(temp, temp_key.key, HINIC_RSS_KEY_SIZE);
966 : :
967 : 0 : return 0;
968 : : }
969 : :
970 : : /**
971 : : * hinic_rss_set_hash_engine - Init rss hash function.
972 : : *
973 : : * @param hwdev
974 : : * The hardware interface of a nic device.
975 : : * @param tmpl_idx
976 : : * Index of rss template from NIC.
977 : : * @param type
978 : : * Hash function, such as Toeplitz or XOR.
979 : : *
980 : : * @return
981 : : * 0 on success.
982 : : * negative error value otherwise.
983 : : */
984 : 0 : int hinic_rss_set_hash_engine(void *hwdev, u8 tmpl_idx, u8 type)
985 : : {
986 : : struct hinic_rss_engine_type hash_type;
987 : 0 : u16 out_size = sizeof(hash_type);
988 : : int err;
989 : :
990 [ # # ]: 0 : if (!hwdev) {
991 : 0 : PMD_DRV_LOG(ERR, "Hwdev is NULL");
992 : 0 : return -EINVAL;
993 : : }
994 : :
995 : : memset(&hash_type, 0, sizeof(hash_type));
996 : 0 : hash_type.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
997 : 0 : hash_type.func_id = hinic_global_func_id(hwdev);
998 : 0 : hash_type.hash_engine = type;
999 : 0 : hash_type.template_id = tmpl_idx;
1000 : :
1001 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_RSS_HASH_ENGINE,
1002 : : &hash_type, sizeof(hash_type),
1003 : : &hash_type, &out_size);
1004 [ # # # # : 0 : if (err || !out_size || hash_type.mgmt_msg_head.status) {
# # ]
1005 : 0 : PMD_DRV_LOG(ERR, "Failed to get hash engine, err: %d, status: 0x%x, out size: 0x%x",
1006 : : err, hash_type.mgmt_msg_head.status, out_size);
1007 : 0 : return -EIO;
1008 : : }
1009 : :
1010 : : return 0;
1011 : : }
1012 : :
1013 : 0 : int hinic_rss_set_indir_tbl(void *hwdev, u32 tmpl_idx, u32 *indir_table)
1014 : : {
1015 : : struct nic_rss_indirect_tbl *indir_tbl;
1016 : : struct hinic_cmd_buf *cmd_buf;
1017 : : int i;
1018 : : u32 *temp;
1019 : : u32 indir_size;
1020 : : u64 out_param;
1021 : : int err;
1022 : :
1023 [ # # ]: 0 : if (!hwdev || !indir_table) {
1024 : 0 : PMD_DRV_LOG(ERR, "Hwdev or indir_table is NULL");
1025 : 0 : return -EINVAL;
1026 : : }
1027 : :
1028 : 0 : cmd_buf = hinic_alloc_cmd_buf(hwdev);
1029 [ # # ]: 0 : if (!cmd_buf) {
1030 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate cmd buf");
1031 : 0 : return -ENOMEM;
1032 : : }
1033 : :
1034 : 0 : cmd_buf->size = sizeof(struct nic_rss_indirect_tbl);
1035 : 0 : indir_tbl = cmd_buf->buf;
1036 [ # # ]: 0 : indir_tbl->group_index = cpu_to_be32(tmpl_idx);
1037 : :
1038 [ # # ]: 0 : for (i = 0; i < HINIC_RSS_INDIR_SIZE; i++) {
1039 : 0 : indir_tbl->entry[i] = (u8)(*(indir_table + i));
1040 : :
1041 [ # # ]: 0 : if (0x3 == (i & 0x3)) {
1042 : 0 : temp = (u32 *)&indir_tbl->entry[i - 3];
1043 [ # # ]: 0 : *temp = cpu_to_be32(*temp);
1044 : : }
1045 : : }
1046 : :
1047 : : /* configure the rss indirect table by command queue */
1048 : : indir_size = HINIC_RSS_INDIR_SIZE / 2;
1049 : 0 : indir_tbl->offset = 0;
1050 : 0 : indir_tbl->size = cpu_to_be32(indir_size);
1051 : :
1052 : 0 : err = hinic_cmdq_direct_resp(hwdev, HINIC_ACK_TYPE_CMDQ,
1053 : : HINIC_MOD_L2NIC,
1054 : : HINIC_UCODE_CMD_SET_RSS_INDIR_TABLE,
1055 : : cmd_buf, &out_param, 0);
1056 [ # # # # ]: 0 : if (err || out_param != 0) {
1057 : 0 : PMD_DRV_LOG(ERR, "Failed to set rss indir table");
1058 : : err = -EIO;
1059 : 0 : goto free_buf;
1060 : : }
1061 : :
1062 : 0 : indir_tbl->offset = cpu_to_be32(indir_size);
1063 : 0 : indir_tbl->size = cpu_to_be32(indir_size);
1064 : 0 : memcpy(indir_tbl->entry, &indir_tbl->entry[indir_size], indir_size);
1065 : :
1066 : 0 : err = hinic_cmdq_direct_resp(hwdev, HINIC_ACK_TYPE_CMDQ,
1067 : : HINIC_MOD_L2NIC,
1068 : : HINIC_UCODE_CMD_SET_RSS_INDIR_TABLE,
1069 : : cmd_buf, &out_param, 0);
1070 [ # # # # ]: 0 : if (err || out_param != 0) {
1071 : 0 : PMD_DRV_LOG(ERR, "Failed to set rss indir table");
1072 : : err = -EIO;
1073 : : }
1074 : :
1075 : 0 : free_buf:
1076 : 0 : hinic_free_cmd_buf(hwdev, cmd_buf);
1077 : :
1078 : 0 : return err;
1079 : : }
1080 : :
1081 : 0 : int hinic_rss_get_indir_tbl(void *hwdev, u32 tmpl_idx, u32 *indir_table)
1082 : : {
1083 : : struct hinic_rss_indir_table rss_cfg;
1084 : 0 : u16 out_size = sizeof(rss_cfg);
1085 : : int err = 0, i;
1086 : :
1087 [ # # ]: 0 : if (!hwdev || !indir_table) {
1088 : 0 : PMD_DRV_LOG(ERR, "Hwdev or indir_table is NULL");
1089 : 0 : return -EINVAL;
1090 : : }
1091 : :
1092 : : memset(&rss_cfg, 0, sizeof(rss_cfg));
1093 : 0 : rss_cfg.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1094 : 0 : rss_cfg.func_id = hinic_global_func_id(hwdev);
1095 : 0 : rss_cfg.template_id = (u8)tmpl_idx;
1096 : :
1097 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev,
1098 : : HINIC_PORT_CMD_GET_RSS_TEMPLATE_INDIR_TBL,
1099 : : &rss_cfg, sizeof(rss_cfg), &rss_cfg,
1100 : : &out_size);
1101 [ # # # # : 0 : if (err || !out_size || rss_cfg.mgmt_msg_head.status) {
# # ]
1102 : 0 : PMD_DRV_LOG(ERR, "Failed to get indir table, err: %d, status: 0x%x, out size: 0x%x",
1103 : : err, rss_cfg.mgmt_msg_head.status, out_size);
1104 : 0 : return -EIO;
1105 : : }
1106 : :
1107 : 0 : hinic_be32_to_cpu(rss_cfg.indir, HINIC_RSS_INDIR_SIZE);
1108 [ # # ]: 0 : for (i = 0; i < HINIC_RSS_INDIR_SIZE; i++)
1109 : 0 : indir_table[i] = rss_cfg.indir[i];
1110 : :
1111 : : return 0;
1112 : : }
1113 : :
1114 : 0 : int hinic_rss_cfg(void *hwdev, u8 rss_en, u8 tmpl_idx, u8 tc_num, u8 *prio_tc)
1115 : : {
1116 : : struct hinic_rss_config rss_cfg;
1117 : 0 : u16 out_size = sizeof(rss_cfg);
1118 : : int err;
1119 : :
1120 : : /* micro code required: number of TC should be power of 2 */
1121 [ # # # # ]: 0 : if (!hwdev || !prio_tc || (tc_num & (tc_num - 1))) {
1122 : 0 : PMD_DRV_LOG(ERR, "Hwdev or prio_tc is NULL, or tc_num: %u Not power of 2",
1123 : : tc_num);
1124 : 0 : return -EINVAL;
1125 : : }
1126 : :
1127 : : memset(&rss_cfg, 0, sizeof(rss_cfg));
1128 : 0 : rss_cfg.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1129 : 0 : rss_cfg.func_id = hinic_global_func_id(hwdev);
1130 : 0 : rss_cfg.rss_en = rss_en;
1131 : 0 : rss_cfg.template_id = tmpl_idx;
1132 [ # # ]: 0 : rss_cfg.rq_priority_number = tc_num ? (u8)ilog2(tc_num) : 0;
1133 : :
1134 : : memcpy(rss_cfg.prio_tc, prio_tc, HINIC_DCB_UP_MAX);
1135 : :
1136 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_RSS_CFG,
1137 : : &rss_cfg, sizeof(rss_cfg), &rss_cfg,
1138 : : &out_size);
1139 [ # # # # : 0 : if (err || !out_size || rss_cfg.mgmt_msg_head.status) {
# # ]
1140 : 0 : PMD_DRV_LOG(ERR, "Failed to set rss cfg, err: %d, status: 0x%x, out size: 0x%x",
1141 : : err, rss_cfg.mgmt_msg_head.status, out_size);
1142 : 0 : return -EIO;
1143 : : }
1144 : :
1145 : : return 0;
1146 : : }
1147 : :
1148 : : /**
1149 : : * hinic_rss_template_alloc - Get rss template id from the chip,
1150 : : * all functions share 96 templates.
1151 : : *
1152 : : * @param hwdev
1153 : : * The hardware interface of a nic device.
1154 : : * @param tmpl_idx
1155 : : * Index of rss template from chip.
1156 : : *
1157 : : * @return
1158 : : * 0 on success.
1159 : : * negative error value otherwise.
1160 : : */
1161 : 0 : int hinic_rss_template_alloc(void *hwdev, u8 *tmpl_idx)
1162 : : {
1163 : : struct hinic_rss_template_mgmt template_mgmt;
1164 : 0 : u16 out_size = sizeof(template_mgmt);
1165 : : int err;
1166 : :
1167 [ # # ]: 0 : if (!hwdev || !tmpl_idx) {
1168 : 0 : PMD_DRV_LOG(ERR, "Hwdev or tmpl_idx is NULL");
1169 : 0 : return -EINVAL;
1170 : : }
1171 : :
1172 : : memset(&template_mgmt, 0, sizeof(template_mgmt));
1173 : 0 : template_mgmt.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1174 : 0 : template_mgmt.func_id = hinic_global_func_id(hwdev);
1175 : 0 : template_mgmt.cmd = NIC_RSS_CMD_TEMP_ALLOC;
1176 : :
1177 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_RSS_TEMP_MGR,
1178 : : &template_mgmt, sizeof(template_mgmt),
1179 : : &template_mgmt, &out_size);
1180 [ # # # # : 0 : if (err || !out_size || template_mgmt.mgmt_msg_head.status) {
# # ]
1181 : 0 : PMD_DRV_LOG(ERR, "Failed to alloc rss template, err: %d, status: 0x%x, out size: 0x%x",
1182 : : err, template_mgmt.mgmt_msg_head.status, out_size);
1183 : 0 : return -EIO;
1184 : : }
1185 : :
1186 : 0 : *tmpl_idx = template_mgmt.template_id;
1187 : :
1188 : 0 : return 0;
1189 : : }
1190 : :
1191 : : /**
1192 : : * hinic_rss_template_free - Free rss template id to the chip.
1193 : : *
1194 : : * @param hwdev
1195 : : * The hardware interface of a nic device.
1196 : : * @param tmpl_idx
1197 : : * Index of rss template from chip.
1198 : : *
1199 : : * @return
1200 : : * 0 on success.
1201 : : * negative error value otherwise.
1202 : : */
1203 : 0 : int hinic_rss_template_free(void *hwdev, u8 tmpl_idx)
1204 : : {
1205 : : struct hinic_rss_template_mgmt template_mgmt;
1206 : 0 : u16 out_size = sizeof(template_mgmt);
1207 : : int err;
1208 : :
1209 [ # # ]: 0 : if (!hwdev) {
1210 : 0 : PMD_DRV_LOG(ERR, "Hwdev is NULL");
1211 : 0 : return -EINVAL;
1212 : : }
1213 : :
1214 : : memset(&template_mgmt, 0, sizeof(template_mgmt));
1215 : 0 : template_mgmt.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1216 : 0 : template_mgmt.func_id = hinic_global_func_id(hwdev);
1217 : 0 : template_mgmt.template_id = tmpl_idx;
1218 : 0 : template_mgmt.cmd = NIC_RSS_CMD_TEMP_FREE;
1219 : :
1220 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_RSS_TEMP_MGR,
1221 : : &template_mgmt, sizeof(template_mgmt),
1222 : : &template_mgmt, &out_size);
1223 [ # # # # : 0 : if (err || !out_size || template_mgmt.mgmt_msg_head.status) {
# # ]
1224 : 0 : PMD_DRV_LOG(ERR, "Failed to free rss template, err: %d, status: 0x%x, out size: 0x%x",
1225 : : err, template_mgmt.mgmt_msg_head.status, out_size);
1226 : 0 : return -EIO;
1227 : : }
1228 : :
1229 : : return 0;
1230 : : }
1231 : :
1232 : : /**
1233 : : * hinic_set_rx_vhd_mode - Change rx buffer size after initialization.
1234 : : *
1235 : : * @param hwdev
1236 : : * The hardware interface of a nic device.
1237 : : * @param vhd_mode
1238 : : * Not needed.
1239 : : * @param rx_buf_sz
1240 : : * receive buffer size.
1241 : : *
1242 : : * @return
1243 : : * 0 on success.
1244 : : * negative error value otherwise.
1245 : : */
1246 : 0 : int hinic_set_rx_vhd_mode(void *hwdev, u16 vhd_mode, u16 rx_buf_sz)
1247 : : {
1248 : : struct hinic_set_vhd_mode vhd_mode_cfg;
1249 : 0 : u16 out_size = sizeof(vhd_mode_cfg);
1250 : : int err;
1251 : :
1252 [ # # ]: 0 : if (!hwdev) {
1253 : 0 : PMD_DRV_LOG(ERR, "Hwdev is NULL");
1254 : 0 : return -EINVAL;
1255 : : }
1256 : :
1257 : : memset(&vhd_mode_cfg, 0, sizeof(vhd_mode_cfg));
1258 : :
1259 : 0 : vhd_mode_cfg.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1260 : 0 : vhd_mode_cfg.func_id = hinic_global_func_id(hwdev);
1261 : 0 : vhd_mode_cfg.vhd_type = vhd_mode;
1262 : 0 : vhd_mode_cfg.rx_wqe_buffer_size = rx_buf_sz;
1263 : :
1264 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_VHD_CFG,
1265 : : &vhd_mode_cfg, sizeof(vhd_mode_cfg),
1266 : : &vhd_mode_cfg, &out_size);
1267 [ # # # # : 0 : if (err || !out_size || vhd_mode_cfg.mgmt_msg_head.status) {
# # ]
1268 : 0 : PMD_DRV_LOG(ERR,
1269 : : "Failed to set vhd mode, err: %d, status: 0x%x, out size: 0x%x",
1270 : : err, vhd_mode_cfg.mgmt_msg_head.status, out_size);
1271 : 0 : return -EIO;
1272 : : }
1273 : :
1274 : : return 0;
1275 : : }
1276 : :
1277 : 0 : int hinic_set_rx_mode(void *hwdev, u32 enable)
1278 : : {
1279 : : struct hinic_rx_mode_config rx_mode_cfg;
1280 : 0 : u16 out_size = sizeof(rx_mode_cfg);
1281 : : int err;
1282 : :
1283 [ # # ]: 0 : if (!hwdev) {
1284 : 0 : PMD_DRV_LOG(ERR, "Hwdev is NULL");
1285 : 0 : return -EINVAL;
1286 : : }
1287 : :
1288 : : memset(&rx_mode_cfg, 0, sizeof(rx_mode_cfg));
1289 : 0 : rx_mode_cfg.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1290 : 0 : rx_mode_cfg.func_id = hinic_global_func_id(hwdev);
1291 : 0 : rx_mode_cfg.rx_mode = enable;
1292 : :
1293 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_RX_MODE,
1294 : : &rx_mode_cfg, sizeof(rx_mode_cfg),
1295 : : &rx_mode_cfg, &out_size);
1296 [ # # # # : 0 : if (err || !out_size || rx_mode_cfg.mgmt_msg_head.status) {
# # ]
1297 : 0 : PMD_DRV_LOG(ERR, "Failed to set rx mode, err: %d, status: 0x%x, out size: 0x%x",
1298 : : err, rx_mode_cfg.mgmt_msg_head.status, out_size);
1299 : 0 : return -EIO;
1300 : : }
1301 : :
1302 : : return 0;
1303 : : }
1304 : :
1305 : : /**
1306 : : * hinic_get_mgmt_version - Get mgmt module version from chip.
1307 : : *
1308 : : * @param hwdev
1309 : : * The hardware interface of a nic device.
1310 : : * @param fw
1311 : : * Firmware version.
1312 : : *
1313 : : * @return
1314 : : * 0 on success.
1315 : : * negative error value otherwise.
1316 : : */
1317 : 0 : int hinic_get_mgmt_version(void *hwdev, char *fw)
1318 : : {
1319 : : struct hinic_version_info fw_ver;
1320 : 0 : u16 out_size = sizeof(fw_ver);
1321 : : int err;
1322 : :
1323 [ # # ]: 0 : if (!hwdev || !fw) {
1324 : 0 : PMD_DRV_LOG(ERR, "Hwdev or fw is NULL");
1325 : 0 : return -EINVAL;
1326 : : }
1327 : :
1328 : : memset(&fw_ver, 0, sizeof(fw_ver));
1329 : 0 : fw_ver.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1330 : :
1331 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_GET_MGMT_VERSION,
1332 : : &fw_ver, sizeof(fw_ver), &fw_ver,
1333 : : &out_size);
1334 [ # # # # : 0 : if (err || !out_size || fw_ver.mgmt_msg_head.status) {
# # ]
1335 : 0 : PMD_DRV_LOG(ERR, "Failed to get mgmt version, err: %d, status: 0x%x, out size: 0x%x\n",
1336 : : err, fw_ver.mgmt_msg_head.status, out_size);
1337 : 0 : return -EIO;
1338 : : }
1339 : :
1340 : : snprintf(fw, HINIC_MGMT_VERSION_MAX_LEN, "%s", fw_ver.ver);
1341 : :
1342 : 0 : return 0;
1343 : : }
1344 : :
1345 : 0 : int hinic_set_rx_csum_offload(void *hwdev, u32 en)
1346 : : {
1347 : : struct hinic_checksum_offload rx_csum_cfg;
1348 : 0 : u16 out_size = sizeof(rx_csum_cfg);
1349 : : int err;
1350 : :
1351 [ # # ]: 0 : if (!hwdev) {
1352 : 0 : PMD_DRV_LOG(ERR, "Hwdev is NULL");
1353 : 0 : return -EINVAL;
1354 : : }
1355 : :
1356 : : memset(&rx_csum_cfg, 0, sizeof(rx_csum_cfg));
1357 : 0 : rx_csum_cfg.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1358 : 0 : rx_csum_cfg.func_id = hinic_global_func_id(hwdev);
1359 : 0 : rx_csum_cfg.rx_csum_offload = en;
1360 : :
1361 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_RX_CSUM,
1362 : : &rx_csum_cfg, sizeof(rx_csum_cfg),
1363 : : &rx_csum_cfg, &out_size);
1364 [ # # # # : 0 : if (err || !out_size || rx_csum_cfg.mgmt_msg_head.status) {
# # ]
1365 : 0 : PMD_DRV_LOG(ERR,
1366 : : "Failed to set rx csum offload, err: %d, status: 0x%x, out size: 0x%x",
1367 : : err, rx_csum_cfg.mgmt_msg_head.status, out_size);
1368 : 0 : return -EIO;
1369 : : }
1370 : :
1371 : : return 0;
1372 : : }
1373 : :
1374 : 0 : int hinic_set_rx_lro(void *hwdev, u8 ipv4_en, u8 ipv6_en, u8 max_wqe_num)
1375 : : {
1376 : : struct hinic_lro_config lro_cfg;
1377 : 0 : u16 out_size = sizeof(lro_cfg);
1378 : : int err;
1379 : :
1380 [ # # ]: 0 : if (!hwdev) {
1381 : 0 : PMD_DRV_LOG(ERR, "Hwdev is NULL");
1382 : 0 : return -EINVAL;
1383 : : }
1384 : :
1385 : : memset(&lro_cfg, 0, sizeof(lro_cfg));
1386 : 0 : lro_cfg.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1387 : 0 : lro_cfg.func_id = hinic_global_func_id(hwdev);
1388 : 0 : lro_cfg.lro_ipv4_en = ipv4_en;
1389 : 0 : lro_cfg.lro_ipv6_en = ipv6_en;
1390 : 0 : lro_cfg.lro_max_wqe_num = max_wqe_num;
1391 : :
1392 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_LRO,
1393 : : &lro_cfg, sizeof(lro_cfg), &lro_cfg,
1394 : : &out_size);
1395 [ # # # # : 0 : if (err || !out_size || lro_cfg.mgmt_msg_head.status) {
# # ]
1396 : 0 : PMD_DRV_LOG(ERR, "Failed to set lro offload, err: %d, status: 0x%x, out size: 0x%x",
1397 : : err, lro_cfg.mgmt_msg_head.status, out_size);
1398 : 0 : return -EIO;
1399 : : }
1400 : :
1401 : : return 0;
1402 : : }
1403 : :
1404 : 0 : int hinic_set_anti_attack(void *hwdev, bool enable)
1405 : : {
1406 : : struct hinic_port_anti_attack_rate rate;
1407 : 0 : u16 out_size = sizeof(rate);
1408 : : int err;
1409 : :
1410 [ # # ]: 0 : if (!hwdev) {
1411 : 0 : PMD_DRV_LOG(ERR, "Hwdev is NULL");
1412 : 0 : return -EINVAL;
1413 : : }
1414 : :
1415 : : memset(&rate, 0, sizeof(rate));
1416 : 0 : rate.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1417 : 0 : rate.func_id = hinic_global_func_id(hwdev);
1418 : 0 : rate.enable = enable;
1419 : 0 : rate.cir = ANTI_ATTACK_DEFAULT_CIR;
1420 : 0 : rate.xir = ANTI_ATTACK_DEFAULT_XIR;
1421 : 0 : rate.cbs = ANTI_ATTACK_DEFAULT_CBS;
1422 : 0 : rate.xbs = ANTI_ATTACK_DEFAULT_XBS;
1423 : :
1424 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_ANTI_ATTACK_RATE,
1425 : : &rate, sizeof(rate), &rate, &out_size);
1426 [ # # # # : 0 : if (err || !out_size || rate.mgmt_msg_head.status) {
# # ]
1427 [ # # ]: 0 : PMD_DRV_LOG(ERR, "Can't %s port Anti-Attack rate limit, err: %d, status: 0x%x, out size: 0x%x",
1428 : : (enable ? "enable" : "disable"), err,
1429 : : rate.mgmt_msg_head.status, out_size);
1430 : 0 : return -EIO;
1431 : : }
1432 : :
1433 : : return 0;
1434 : : }
1435 : :
1436 : : /* Set autoneg status and restart port link status */
1437 : 0 : int hinic_reset_port_link_cfg(void *hwdev)
1438 : : {
1439 : : struct hinic_reset_link_cfg reset_cfg;
1440 : 0 : u16 out_size = sizeof(reset_cfg);
1441 : : int err;
1442 : :
1443 : : memset(&reset_cfg, 0, sizeof(reset_cfg));
1444 : 0 : reset_cfg.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1445 : 0 : reset_cfg.func_id = hinic_global_func_id(hwdev);
1446 : :
1447 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_RESET_LINK_CFG,
1448 : : &reset_cfg, sizeof(reset_cfg),
1449 : : &reset_cfg, &out_size);
1450 [ # # # # : 0 : if (err || !out_size || reset_cfg.mgmt_msg_head.status) {
# # ]
1451 : 0 : PMD_DRV_LOG(ERR, "Reset port link configure failed, err: %d, status: 0x%x, out size: 0x%x",
1452 : : err, reset_cfg.mgmt_msg_head.status, out_size);
1453 : 0 : return -EIO;
1454 : : }
1455 : :
1456 : : return 0;
1457 : : }
1458 : :
1459 : : /**
1460 : : * hinic_vf_func_init - Register VF to PF.
1461 : : *
1462 : : * @param hwdev
1463 : : * The hardware interface of a nic device.
1464 : : *
1465 : : * @return
1466 : : * 0 on success.
1467 : : * negative error value otherwise.
1468 : : */
1469 : 0 : int hinic_vf_func_init(struct hinic_hwdev *hwdev)
1470 : : {
1471 : 0 : int err, state = 0;
1472 : :
1473 [ # # ]: 0 : if (!HINIC_IS_VF(hwdev))
1474 : : return 0;
1475 : :
1476 : 0 : err = hinic_mbox_to_pf(hwdev, HINIC_MOD_L2NIC,
1477 : : HINIC_PORT_CMD_VF_REGISTER, &state, sizeof(state),
1478 : : NULL, NULL, 0);
1479 [ # # ]: 0 : if (err) {
1480 : 0 : PMD_DRV_LOG(ERR, "Fail to register vf");
1481 : 0 : return err;
1482 : : }
1483 : :
1484 : : return 0;
1485 : : }
1486 : :
1487 : : /**
1488 : : * hinic_vf_func_free - Unregister VF from PF.
1489 : : *
1490 : : * @param hwdev
1491 : : * The hardware interface of a nic device.
1492 : : */
1493 : 0 : void hinic_vf_func_free(struct hinic_hwdev *hwdev)
1494 : : {
1495 : : int err;
1496 : :
1497 [ # # ]: 0 : if (hinic_func_type(hwdev) != TYPE_VF)
1498 : 0 : return;
1499 : :
1500 : 0 : err = hinic_mbox_to_pf(hwdev, HINIC_MOD_L2NIC,
1501 : : HINIC_PORT_CMD_VF_UNREGISTER, &err, sizeof(err),
1502 : : NULL, NULL, 0);
1503 [ # # ]: 0 : if (err)
1504 : 0 : PMD_DRV_LOG(ERR, "Fail to unregister VF, err: %d", err);
1505 : : }
1506 : :
1507 : 0 : int hinic_set_fast_recycle_mode(void *hwdev, u8 mode)
1508 : : {
1509 : : struct hinic_fast_recycled_mode fast_recycled_mode;
1510 : 0 : u16 out_size = sizeof(fast_recycled_mode);
1511 : : int err;
1512 : :
1513 [ # # ]: 0 : if (!hwdev) {
1514 : 0 : PMD_DRV_LOG(ERR, "Hwdev is NULL");
1515 : 0 : return -EINVAL;
1516 : : }
1517 : :
1518 : : memset(&fast_recycled_mode, 0, sizeof(fast_recycled_mode));
1519 : 0 : fast_recycled_mode.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1520 : 0 : fast_recycled_mode.func_id = hinic_global_func_id(hwdev);
1521 : 0 : fast_recycled_mode.fast_recycled_mode = mode;
1522 : :
1523 : 0 : err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM,
1524 : : HINIC_MGMT_CMD_FAST_RECYCLE_MODE_SET,
1525 : : &fast_recycled_mode,
1526 : : sizeof(fast_recycled_mode),
1527 : : &fast_recycled_mode, &out_size, 0);
1528 [ # # # # : 0 : if (err || fast_recycled_mode.mgmt_msg_head.status || !out_size) {
# # ]
1529 : 0 : PMD_DRV_LOG(ERR, "Failed to set recycle mode, err: %d, status: 0x%x, out size: 0x%x",
1530 : : err, fast_recycled_mode.mgmt_msg_head.status, out_size);
1531 : 0 : return -EIO;
1532 : : }
1533 : :
1534 : : return 0;
1535 : : }
1536 : :
1537 : 0 : int hinic_clear_vport_stats(struct hinic_hwdev *hwdev)
1538 : : {
1539 : : struct hinic_clear_vport_stats clear_vport_stats;
1540 : 0 : u16 out_size = sizeof(clear_vport_stats);
1541 : : int err;
1542 : :
1543 [ # # ]: 0 : if (!hwdev) {
1544 : 0 : PMD_DRV_LOG(ERR, "Hwdev is NULL");
1545 : 0 : return -EINVAL;
1546 : : }
1547 : :
1548 : : memset(&clear_vport_stats, 0, sizeof(clear_vport_stats));
1549 : 0 : clear_vport_stats.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1550 : 0 : clear_vport_stats.func_id = hinic_global_func_id(hwdev);
1551 : :
1552 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_CLEAN_VPORT_STAT,
1553 : : &clear_vport_stats,
1554 : : sizeof(clear_vport_stats),
1555 : : &clear_vport_stats, &out_size);
1556 [ # # # # : 0 : if (err || !out_size || clear_vport_stats.mgmt_msg_head.status) {
# # ]
1557 : 0 : PMD_DRV_LOG(ERR, "Failed to clear vport statistics, err: %d, status: 0x%x, out size: 0x%x",
1558 : : err, clear_vport_stats.mgmt_msg_head.status, out_size);
1559 : 0 : return -EIO;
1560 : : }
1561 : :
1562 : : return 0;
1563 : : }
1564 : :
1565 : 0 : int hinic_clear_phy_port_stats(struct hinic_hwdev *hwdev)
1566 : : {
1567 : : struct hinic_clear_port_stats clear_phy_port_stats;
1568 : 0 : u16 out_size = sizeof(clear_phy_port_stats);
1569 : : int err;
1570 : :
1571 [ # # ]: 0 : if (!hwdev) {
1572 : 0 : PMD_DRV_LOG(ERR, "Hwdev is NULL");
1573 : 0 : return -EINVAL;
1574 : : }
1575 : :
1576 : : memset(&clear_phy_port_stats, 0, sizeof(clear_phy_port_stats));
1577 : 0 : clear_phy_port_stats.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1578 : 0 : clear_phy_port_stats.func_id = hinic_global_func_id(hwdev);
1579 : :
1580 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev,
1581 : : HINIC_PORT_CMD_CLEAR_PORT_STATISTICS,
1582 : : &clear_phy_port_stats,
1583 : : sizeof(clear_phy_port_stats),
1584 : : &clear_phy_port_stats, &out_size);
1585 [ # # # # : 0 : if (err || !out_size || clear_phy_port_stats.mgmt_msg_head.status) {
# # ]
1586 : 0 : PMD_DRV_LOG(ERR, "Failed to clear phy port statistics, err: %d, status: 0x%x, out size: 0x%x",
1587 : : err, clear_phy_port_stats.mgmt_msg_head.status,
1588 : : out_size);
1589 : 0 : return -EIO;
1590 : : }
1591 : :
1592 : : return 0;
1593 : : }
1594 : :
1595 : 0 : int hinic_set_link_status_follow(void *hwdev,
1596 : : enum hinic_link_follow_status status)
1597 : : {
1598 : : struct hinic_set_link_follow follow;
1599 : 0 : u16 out_size = sizeof(follow);
1600 : : int err;
1601 : :
1602 [ # # ]: 0 : if (!hwdev)
1603 : : return -EINVAL;
1604 : :
1605 [ # # ]: 0 : if (HINIC_IS_VF((struct hinic_hwdev *)hwdev))
1606 : : return 0;
1607 : :
1608 [ # # ]: 0 : if (status >= HINIC_LINK_FOLLOW_STATUS_MAX) {
1609 : 0 : PMD_DRV_LOG(ERR, "Invalid link follow status: %d", status);
1610 : 0 : return -EINVAL;
1611 : : }
1612 : :
1613 : : memset(&follow, 0, sizeof(follow));
1614 : 0 : follow.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1615 : 0 : follow.func_id = hinic_global_func_id(hwdev);
1616 : 0 : follow.follow_status = status;
1617 : :
1618 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_LINK_FOLLOW,
1619 : : &follow, sizeof(follow),
1620 : : &follow, &out_size);
1621 [ # # ]: 0 : if ((follow.mgmt_msg_head.status != HINIC_MGMT_CMD_UNSUPPORTED &&
1622 [ # # # # ]: 0 : follow.mgmt_msg_head.status) || err || !out_size) {
1623 : 0 : PMD_DRV_LOG(ERR,
1624 : : "Failed to set link status follow phy port status, err: %d, status: 0x%x, out size: 0x%x",
1625 : : err, follow.mgmt_msg_head.status, out_size);
1626 : 0 : return -EIO;
1627 : : }
1628 : :
1629 : 0 : return follow.mgmt_msg_head.status;
1630 : : }
1631 : :
1632 : 0 : int hinic_get_link_mode(void *hwdev, u32 *supported, u32 *advertised)
1633 : : {
1634 : : struct hinic_link_mode_cmd link_mode;
1635 : 0 : u16 out_size = sizeof(link_mode);
1636 : : int err;
1637 : :
1638 [ # # # # ]: 0 : if (!hwdev || !supported || !advertised)
1639 : : return -EINVAL;
1640 : :
1641 : : memset(&link_mode, 0, sizeof(link_mode));
1642 : 0 : link_mode.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1643 : 0 : link_mode.func_id = hinic_global_func_id(hwdev);
1644 : :
1645 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_GET_LINK_MODE,
1646 : : &link_mode, sizeof(link_mode),
1647 : : &link_mode, &out_size);
1648 [ # # # # : 0 : if (err || !out_size || link_mode.mgmt_msg_head.status) {
# # ]
1649 : 0 : PMD_DRV_LOG(ERR,
1650 : : "Failed to get link mode, err: %d, status: 0x%x, out size: 0x%x",
1651 : : err, link_mode.mgmt_msg_head.status, out_size);
1652 : 0 : return -EIO;
1653 : : }
1654 : :
1655 : 0 : *supported = link_mode.supported;
1656 : 0 : *advertised = link_mode.advertised;
1657 : :
1658 : 0 : return 0;
1659 : : }
1660 : :
1661 : : /**
1662 : : * hinic_flush_qp_res - Flush tx && rx chip resources in case of set vport
1663 : : * fake failed when device start.
1664 : : *
1665 : : * @param hwdev
1666 : : * The hardware interface of a nic device.
1667 : : *
1668 : : * @return
1669 : : * 0 on success.
1670 : : * negative error value otherwise.
1671 : : */
1672 : 0 : int hinic_flush_qp_res(void *hwdev)
1673 : : {
1674 : : struct hinic_clear_qp_resource qp_res;
1675 : 0 : u16 out_size = sizeof(qp_res);
1676 : : int err;
1677 : :
1678 : : memset(&qp_res, 0, sizeof(qp_res));
1679 : 0 : qp_res.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1680 : 0 : qp_res.func_id = hinic_global_func_id(hwdev);
1681 : :
1682 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_CLEAR_QP_RES,
1683 : : &qp_res, sizeof(qp_res), &qp_res,
1684 : : &out_size);
1685 [ # # # # : 0 : if (err || !out_size || qp_res.mgmt_msg_head.status) {
# # ]
1686 : 0 : PMD_DRV_LOG(ERR, "Failed to clear sq resources, err: %d, status: 0x%x, out size: 0x%x",
1687 : : err, qp_res.mgmt_msg_head.status, out_size);
1688 : 0 : return -EIO;
1689 : : }
1690 : :
1691 : : return 0;
1692 : : }
1693 : :
1694 : : /**
1695 : : * hinic_vf_get_default_cos - Get default cos of VF.
1696 : : *
1697 : : * @param hwdev
1698 : : * The hardware interface of a nic device.
1699 : : * @param cos_id
1700 : : * Cos value.
1701 : : *
1702 : : * @return
1703 : : * 0 on success.
1704 : : * negative error value otherwise.
1705 : : */
1706 : 0 : int hinic_vf_get_default_cos(struct hinic_hwdev *hwdev, u8 *cos_id)
1707 : : {
1708 : : struct hinic_vf_default_cos vf_cos;
1709 : 0 : u16 out_size = sizeof(vf_cos);
1710 : : int err;
1711 : :
1712 : : memset(&vf_cos, 0, sizeof(vf_cos));
1713 : 0 : vf_cos.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1714 : :
1715 : 0 : err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_L2NIC,
1716 : : HINIC_PORT_CMD_GET_VF_COS, &vf_cos,
1717 : : sizeof(vf_cos), &vf_cos, &out_size, 0);
1718 [ # # # # : 0 : if (err || !out_size || vf_cos.mgmt_msg_head.status) {
# # ]
1719 : 0 : PMD_DRV_LOG(ERR, "Get VF default cos failed, err: %d, status: 0x%x, out size: 0x%x",
1720 : : err, vf_cos.mgmt_msg_head.status, out_size);
1721 : 0 : return -EIO;
1722 : : }
1723 : 0 : *cos_id = vf_cos.state.default_cos;
1724 : :
1725 : 0 : return 0;
1726 : : }
1727 : :
1728 : : /**
1729 : : * hinic_set_fdir_filter - Set fdir filter for control path
1730 : : * packet to notify firmware.
1731 : : *
1732 : : * @param hwdev
1733 : : * The hardware interface of a nic device.
1734 : : * @param filter_type
1735 : : * Packet type to filter.
1736 : : * @param qid
1737 : : * Rx qid to filter.
1738 : : * @param type_enable
1739 : : * The status of pkt type filter.
1740 : : * @param enable
1741 : : * Fdir function Enable or Disable.
1742 : : * @return
1743 : : * 0 on success,
1744 : : * negative error value otherwise.
1745 : : */
1746 : 0 : int hinic_set_fdir_filter(void *hwdev, u8 filter_type, u8 qid, u8 type_enable,
1747 : : bool enable)
1748 : : {
1749 : : struct hinic_port_qfilter_info port_filer_cmd;
1750 : 0 : u16 out_size = sizeof(port_filer_cmd);
1751 : : int err;
1752 : :
1753 [ # # ]: 0 : if (!hwdev)
1754 : : return -EINVAL;
1755 : :
1756 : : memset(&port_filer_cmd, 0, sizeof(port_filer_cmd));
1757 : 0 : port_filer_cmd.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1758 : 0 : port_filer_cmd.func_id = hinic_global_func_id(hwdev);
1759 : 0 : port_filer_cmd.filter_enable = (u8)enable;
1760 : 0 : port_filer_cmd.filter_type = filter_type;
1761 : 0 : port_filer_cmd.qid = qid;
1762 : 0 : port_filer_cmd.filter_type_enable = type_enable;
1763 : 0 : port_filer_cmd.fdir_flag = 0;
1764 : :
1765 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_Q_FILTER,
1766 : : &port_filer_cmd, sizeof(port_filer_cmd),
1767 : : &port_filer_cmd, &out_size);
1768 [ # # # # : 0 : if (err || !out_size || port_filer_cmd.mgmt_msg_head.status) {
# # ]
1769 : 0 : PMD_DRV_LOG(ERR, "Set port Q filter failed, err: %d, status: 0x%x, out size: 0x%x, type: 0x%x,"
1770 : : " enable: 0x%x, qid: 0x%x, filter_type_enable: 0x%x\n",
1771 : : err, port_filer_cmd.mgmt_msg_head.status, out_size,
1772 : : filter_type, enable, qid, type_enable);
1773 : 0 : return -EIO;
1774 : : }
1775 : :
1776 : : return 0;
1777 : : }
1778 : :
1779 : : /**
1780 : : * hinic_set_normal_filter - Set fdir filter for IO path packet.
1781 : : *
1782 : : * @param hwdev
1783 : : * The hardware interface of a nic device.
1784 : : * @param qid
1785 : : * Rx qid to filter.
1786 : : * @param normal_type_enable
1787 : : * IO path packet function Enable or Disable
1788 : : * @param key
1789 : : * IO path packet filter key value, such as DIP from pkt.
1790 : : * @param enable
1791 : : * Fdir function Enable or Disable.
1792 : : * @param flag
1793 : : * Filter flag, such as dip or others.
1794 : : * @return
1795 : : * 0 on success,
1796 : : * negative error value otherwise.
1797 : : */
1798 : 0 : int hinic_set_normal_filter(void *hwdev, u8 qid, u8 normal_type_enable,
1799 : : u32 key, bool enable, u8 flag)
1800 : : {
1801 : : struct hinic_port_qfilter_info port_filer_cmd;
1802 : 0 : u16 out_size = sizeof(port_filer_cmd);
1803 : : int err;
1804 : :
1805 [ # # ]: 0 : if (!hwdev)
1806 : : return -EINVAL;
1807 : :
1808 : : memset(&port_filer_cmd, 0, sizeof(port_filer_cmd));
1809 : 0 : port_filer_cmd.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1810 : 0 : port_filer_cmd.func_id = hinic_global_func_id(hwdev);
1811 : 0 : port_filer_cmd.filter_enable = (u8)enable;
1812 : 0 : port_filer_cmd.qid = qid;
1813 : 0 : port_filer_cmd.normal_type_enable = normal_type_enable;
1814 : 0 : port_filer_cmd.fdir_flag = flag; /* fdir flag: support dip */
1815 : 0 : port_filer_cmd.key = key;
1816 : :
1817 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_Q_FILTER,
1818 : : &port_filer_cmd, sizeof(port_filer_cmd),
1819 : : &port_filer_cmd, &out_size);
1820 [ # # # # : 0 : if (err || !out_size || port_filer_cmd.mgmt_msg_head.status) {
# # ]
1821 : 0 : PMD_DRV_LOG(ERR, "Set normal filter failed, err: %d, status: 0x%x, out size: 0x%x, fdir_flag: 0x%x,"
1822 : : " enable: 0x%x, qid: 0x%x, normal_type_enable: 0x%x, key:0x%x\n",
1823 : : err, port_filer_cmd.mgmt_msg_head.status, out_size,
1824 : : flag, enable, qid, normal_type_enable, key);
1825 : 0 : return -EIO;
1826 : : }
1827 : :
1828 : : return 0;
1829 : : }
1830 : :
1831 : : /**
1832 : : * hinic_set_fdir_tcam - Set fdir filter for control packet
1833 : : * by tcam table to notify hardware.
1834 : : *
1835 : : * @param hwdev
1836 : : * The hardware interface of a nic device.
1837 : : * @param type_mask
1838 : : * Index of TCAM.
1839 : : * @param filter_rule
1840 : : * TCAM rule for control packet, such as lacp or bgp.
1841 : : * @param filter_action
1842 : : * TCAM action for control packet, such as accept or drop.
1843 : : * @return
1844 : : * 0 on success,
1845 : : * negative error value otherwise.
1846 : : */
1847 : 0 : int hinic_set_fdir_tcam(void *hwdev, u16 type_mask,
1848 : : struct tag_pa_rule *filter_rule,
1849 : : struct tag_pa_action *filter_action)
1850 : : {
1851 : : struct hinic_fdir_tcam_info port_tcam_cmd;
1852 : 0 : u16 out_size = sizeof(port_tcam_cmd);
1853 : : int err;
1854 : :
1855 [ # # ]: 0 : if (!hwdev)
1856 : : return -EINVAL;
1857 : :
1858 : : memset(&port_tcam_cmd, 0, sizeof(port_tcam_cmd));
1859 : 0 : port_tcam_cmd.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1860 : 0 : port_tcam_cmd.tcam_index = type_mask;
1861 : 0 : port_tcam_cmd.flag = TCAM_SET;
1862 : : memcpy((void *)&port_tcam_cmd.filter_rule,
1863 : : (void *)filter_rule, sizeof(struct tag_pa_rule));
1864 : : memcpy((void *)&port_tcam_cmd.filter_action,
1865 : : (void *)filter_action, sizeof(struct tag_pa_action));
1866 : :
1867 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_TCAM_FILTER,
1868 : : &port_tcam_cmd, sizeof(port_tcam_cmd),
1869 : : &port_tcam_cmd, &out_size);
1870 [ # # # # : 0 : if (err || !out_size || port_tcam_cmd.mgmt_msg_head.status) {
# # ]
1871 : 0 : PMD_DRV_LOG(ERR, "Set tcam table failed, err: %d, status: 0x%x, out size: 0x%x",
1872 : : err, port_tcam_cmd.mgmt_msg_head.status, out_size);
1873 : 0 : return -EIO;
1874 : : }
1875 : :
1876 : : return 0;
1877 : : }
1878 : :
1879 : : /**
1880 : : * hinic_clear_fdir_tcam - Clear fdir filter TCAM table for control packet.
1881 : : *
1882 : : * @param hwdev
1883 : : * The hardware interface of a nic device.
1884 : : * @param type_mask
1885 : : * Index of TCAM.
1886 : : * @return
1887 : : * 0 on success,
1888 : : * negative error value otherwise.
1889 : : */
1890 : 0 : int hinic_clear_fdir_tcam(void *hwdev, u16 type_mask)
1891 : : {
1892 : : struct hinic_fdir_tcam_info port_tcam_cmd;
1893 : 0 : u16 out_size = sizeof(port_tcam_cmd);
1894 : : int err;
1895 : :
1896 [ # # ]: 0 : if (!hwdev)
1897 : : return -EINVAL;
1898 : :
1899 : : memset(&port_tcam_cmd, 0, sizeof(port_tcam_cmd));
1900 : 0 : port_tcam_cmd.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1901 : 0 : port_tcam_cmd.tcam_index = type_mask;
1902 : 0 : port_tcam_cmd.flag = TCAM_CLEAR;
1903 : :
1904 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_TCAM_FILTER,
1905 : : &port_tcam_cmd, sizeof(port_tcam_cmd),
1906 : : &port_tcam_cmd, &out_size);
1907 [ # # # # : 0 : if (err || !out_size || port_tcam_cmd.mgmt_msg_head.status) {
# # ]
1908 : 0 : PMD_DRV_LOG(ERR, "Clear tcam table failed, err: %d, status: 0x%x, out size: 0x%x",
1909 : : err, port_tcam_cmd.mgmt_msg_head.status, out_size);
1910 : 0 : return -EIO;
1911 : : }
1912 : :
1913 : : return 0;
1914 : : }
1915 : :
1916 : 0 : int hinic_add_tcam_rule(void *hwdev, struct tag_tcam_cfg_rule *tcam_rule)
1917 : : {
1918 : 0 : u16 out_size = sizeof(struct tag_fdir_add_rule_cmd);
1919 : : struct tag_fdir_add_rule_cmd tcam_cmd;
1920 : : int err;
1921 : :
1922 [ # # ]: 0 : if (!hwdev) {
1923 : 0 : PMD_DRV_LOG(ERR, "Hwdev is NULL");
1924 : 0 : return -EINVAL;
1925 : : }
1926 : :
1927 [ # # ]: 0 : if (tcam_rule->index >= HINIC_MAX_TCAM_RULES_NUM) {
1928 : 0 : PMD_DRV_LOG(ERR, "Tcam rules num to add is invalid");
1929 : 0 : return -EINVAL;
1930 : : }
1931 : :
1932 : : memset(&tcam_cmd, 0, sizeof(struct tag_fdir_add_rule_cmd));
1933 : 0 : tcam_cmd.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1934 : : memcpy((void *)&tcam_cmd.rule, (void *)tcam_rule,
1935 : : sizeof(struct tag_tcam_cfg_rule));
1936 : :
1937 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_UP_TC_ADD_FLOW,
1938 : : &tcam_cmd, sizeof(tcam_cmd),
1939 : : &tcam_cmd, &out_size);
1940 [ # # # # : 0 : if (err || tcam_cmd.mgmt_msg_head.status || !out_size) {
# # ]
1941 : 0 : PMD_DRV_LOG(ERR,
1942 : : "Add tcam rule failed, err: %d, status: 0x%x, out size: 0x%x",
1943 : : err, tcam_cmd.mgmt_msg_head.status, out_size);
1944 : 0 : return -EIO;
1945 : : }
1946 : :
1947 : : return 0;
1948 : : }
1949 : :
1950 : 0 : int hinic_del_tcam_rule(void *hwdev, u32 index)
1951 : : {
1952 : 0 : u16 out_size = sizeof(struct tag_fdir_del_rule_cmd);
1953 : : struct tag_fdir_del_rule_cmd tcam_cmd;
1954 : : int err;
1955 : :
1956 [ # # ]: 0 : if (!hwdev) {
1957 : 0 : PMD_DRV_LOG(ERR, "Hwdev is NULL");
1958 : 0 : return -EINVAL;
1959 : : }
1960 : :
1961 [ # # ]: 0 : if (index >= HINIC_MAX_TCAM_RULES_NUM) {
1962 : 0 : PMD_DRV_LOG(ERR, "Tcam rules num to del is invalid");
1963 : 0 : return -EINVAL;
1964 : : }
1965 : :
1966 : : memset(&tcam_cmd, 0, sizeof(struct tag_fdir_del_rule_cmd));
1967 : 0 : tcam_cmd.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1968 : 0 : tcam_cmd.index_start = index;
1969 : 0 : tcam_cmd.index_num = 1;
1970 : :
1971 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_UP_TC_DEL_FLOW,
1972 : : &tcam_cmd, sizeof(tcam_cmd),
1973 : : &tcam_cmd, &out_size);
1974 [ # # # # : 0 : if (err || tcam_cmd.mgmt_msg_head.status || !out_size) {
# # ]
1975 : 0 : PMD_DRV_LOG(ERR,
1976 : : "Del tcam rule failed, err: %d, status: 0x%x, out size: 0x%x",
1977 : : err, tcam_cmd.mgmt_msg_head.status, out_size);
1978 : 0 : return -EIO;
1979 : : }
1980 : :
1981 : : return 0;
1982 : : }
1983 : :
1984 : 0 : static int hinic_mgmt_tcam_block(void *hwdev, u8 alloc_en,
1985 : : u8 block_type, u16 *index)
1986 : : {
1987 : : struct hinic_cmd_ctrl_tcam_block tcam_block_info;
1988 : 0 : u16 out_size = sizeof(struct hinic_cmd_ctrl_tcam_block);
1989 : : struct hinic_hwdev *nic_hwdev = (struct hinic_hwdev *)hwdev;
1990 : : int err;
1991 : :
1992 [ # # ]: 0 : if (!hwdev) {
1993 : 0 : PMD_DRV_LOG(ERR, "Hwdev is NULL");
1994 : 0 : return -EINVAL;
1995 : : }
1996 : :
1997 : : memset(&tcam_block_info, 0, sizeof(struct hinic_cmd_ctrl_tcam_block));
1998 : 0 : tcam_block_info.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1999 : 0 : tcam_block_info.func_id = hinic_global_func_id(hwdev);
2000 : 0 : tcam_block_info.alloc_en = alloc_en;
2001 : 0 : tcam_block_info.tcam_type = block_type;
2002 : 0 : tcam_block_info.tcam_block_index = *index;
2003 : :
2004 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev,
2005 : : HINIC_PORT_CMD_UP_TC_CTRL_TCAM_BLOCK,
2006 : : &tcam_block_info, sizeof(tcam_block_info),
2007 : : &tcam_block_info, &out_size);
2008 [ # # ]: 0 : if (tcam_block_info.mgmt_msg_head.status ==
2009 : : HINIC_MGMT_CMD_UNSUPPORTED) {
2010 : : err = HINIC_MGMT_CMD_UNSUPPORTED;
2011 : 0 : PMD_DRV_LOG(INFO, "Firmware/uP doesn't support alloc or del tcam block");
2012 : 0 : return err;
2013 [ # # ]: 0 : } else if ((err == HINIC_MBOX_VF_CMD_ERROR) &&
2014 [ # # ]: 0 : (HINIC_IS_VF(nic_hwdev))) {
2015 : : err = HINIC_MGMT_CMD_UNSUPPORTED;
2016 : 0 : PMD_DRV_LOG(INFO, "VF doesn't support alloc and del tcam block.");
2017 : 0 : return err;
2018 [ # # # # : 0 : } else if (err || (!out_size) || tcam_block_info.mgmt_msg_head.status) {
# # ]
2019 : 0 : PMD_DRV_LOG(ERR,
2020 : : "Set tcam block failed, err: %d, status: 0x%x, out size: 0x%x",
2021 : : err, tcam_block_info.mgmt_msg_head.status, out_size);
2022 : 0 : return -EIO;
2023 : : }
2024 : :
2025 [ # # ]: 0 : if (alloc_en)
2026 : 0 : *index = tcam_block_info.tcam_block_index;
2027 : :
2028 : : return 0;
2029 : : }
2030 : :
2031 : 0 : int hinic_alloc_tcam_block(void *hwdev, u8 block_type, u16 *index)
2032 : : {
2033 : 0 : return hinic_mgmt_tcam_block(hwdev, HINIC_TCAM_BLOCK_ENABLE,
2034 : : block_type, index);
2035 : : }
2036 : :
2037 : 0 : int hinic_free_tcam_block(void *hwdev, u8 block_type, u16 *index)
2038 : : {
2039 : 0 : return hinic_mgmt_tcam_block(hwdev, HINIC_TCAM_BLOCK_DISABLE,
2040 : : block_type, index);
2041 : : }
2042 : :
2043 : 0 : int hinic_flush_tcam_rule(void *hwdev)
2044 : : {
2045 : : struct hinic_cmd_flush_tcam_rules tcam_flush;
2046 : 0 : u16 out_size = sizeof(struct hinic_cmd_flush_tcam_rules);
2047 : : struct hinic_hwdev *nic_hwdev = (struct hinic_hwdev *)hwdev;
2048 : : int err;
2049 : :
2050 [ # # ]: 0 : if (!hwdev) {
2051 : 0 : PMD_DRV_LOG(ERR, "Hwdev is NULL");
2052 : 0 : return -EINVAL;
2053 : : }
2054 : :
2055 : : memset(&tcam_flush, 0, sizeof(struct hinic_cmd_flush_tcam_rules));
2056 : 0 : tcam_flush.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
2057 : 0 : tcam_flush.func_id = hinic_global_func_id(hwdev);
2058 : :
2059 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_UP_TC_FLUSH_TCAM,
2060 : : &tcam_flush, sizeof(struct hinic_cmd_flush_tcam_rules),
2061 : : &tcam_flush, &out_size);
2062 [ # # ]: 0 : if (tcam_flush.mgmt_msg_head.status == HINIC_MGMT_CMD_UNSUPPORTED) {
2063 : : err = HINIC_MGMT_CMD_UNSUPPORTED;
2064 : 0 : PMD_DRV_LOG(INFO, "Firmware/uP doesn't support flush tcam fdir");
2065 [ # # ]: 0 : } else if ((err == HINIC_MBOX_VF_CMD_ERROR) &&
2066 [ # # ]: 0 : (HINIC_IS_VF(nic_hwdev))) {
2067 : : err = HINIC_MGMT_CMD_UNSUPPORTED;
2068 : 0 : PMD_DRV_LOG(INFO, "VF doesn't support flush tcam fdir");
2069 [ # # # # : 0 : } else if (err || (!out_size) || tcam_flush.mgmt_msg_head.status) {
# # ]
2070 : 0 : PMD_DRV_LOG(ERR,
2071 : : "Flush tcam fdir rules failed, err: %d, status: 0x%x, out size: 0x%x",
2072 : : err, tcam_flush.mgmt_msg_head.status, out_size);
2073 : : err = -EIO;
2074 : : }
2075 : :
2076 : : return err;
2077 : : }
2078 : :
2079 : 0 : int hinic_set_fdir_tcam_rule_filter(void *hwdev, bool enable)
2080 : : {
2081 : : struct hinic_port_tcam_info port_tcam_cmd;
2082 : 0 : u16 out_size = sizeof(port_tcam_cmd);
2083 : : int err;
2084 : :
2085 [ # # ]: 0 : if (!hwdev)
2086 : : return -EINVAL;
2087 : :
2088 : : memset(&port_tcam_cmd, 0, sizeof(port_tcam_cmd));
2089 : 0 : port_tcam_cmd.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
2090 : 0 : port_tcam_cmd.func_id = hinic_global_func_id(hwdev);
2091 : 0 : port_tcam_cmd.tcam_enable = (u8)enable;
2092 : :
2093 : 0 : err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_UP_TC_ENABLE,
2094 : : &port_tcam_cmd, sizeof(port_tcam_cmd),
2095 : : &port_tcam_cmd, &out_size);
2096 [ # # ]: 0 : if ((port_tcam_cmd.mgmt_msg_head.status != HINIC_MGMT_CMD_UNSUPPORTED &&
2097 [ # # # # ]: 0 : port_tcam_cmd.mgmt_msg_head.status) || err || !out_size) {
2098 [ # # ]: 0 : if (err == HINIC_MBOX_VF_CMD_ERROR &&
2099 [ # # ]: 0 : HINIC_IS_VF((struct hinic_hwdev *)hwdev)) {
2100 : : err = HINIC_MGMT_CMD_UNSUPPORTED;
2101 : 0 : PMD_DRV_LOG(WARNING, "VF doesn't support setting fdir tcam filter");
2102 : 0 : return err;
2103 : : }
2104 : 0 : PMD_DRV_LOG(ERR, "Set fdir tcam filter failed, err: %d, "
2105 : : "status: 0x%x, out size: 0x%x, enable: 0x%x",
2106 : : err, port_tcam_cmd.mgmt_msg_head.status, out_size,
2107 : : enable);
2108 : 0 : return -EIO;
2109 : : }
2110 : :
2111 [ # # ]: 0 : if (port_tcam_cmd.mgmt_msg_head.status == HINIC_MGMT_CMD_UNSUPPORTED) {
2112 : : err = HINIC_MGMT_CMD_UNSUPPORTED;
2113 : 0 : PMD_DRV_LOG(WARNING, "Fw doesn't support setting fdir tcam filter");
2114 : : }
2115 : :
2116 : : return err;
2117 : : }
2118 : :
2119 : :
|