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