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