1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2017 Huawei Technologies Co., Ltd
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"
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, \
23 #define TCAM_CLEAR 0x2
25 struct hinic_port_qfilter_info {
26 struct hinic_mgmt_msg_head mgmt_msg_head;
29 u8 normal_type_enable;
30 u8 filter_type_enable;
39 * hinic_init_function_table - Initialize function table.
42 * The hardware interface of a nic device.
44 * Receive buffer size.
48 * negative error value otherwise.
50 int hinic_init_function_table(void *hwdev, u16 rx_buf_sz)
52 struct hinic_function_table function_table;
53 u16 out_size = sizeof(function_table);
57 PMD_DRV_LOG(ERR, "Hwdev is NULL");
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;
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) {
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);
82 * hinic_get_base_qpn - Get global queue number.
85 * The hardware interface of a nic device.
87 * Global queue number.
91 * negative error value otherwise.
93 int hinic_get_base_qpn(void *hwdev, u16 *global_qpn)
95 struct hinic_cmd_qpn cmd_qpn;
96 u16 out_size = sizeof(cmd_qpn);
99 if (!hwdev || !global_qpn) {
100 PMD_DRV_LOG(ERR, "Hwdev or global_qpn is NULL");
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);
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,
112 if (err || !out_size || cmd_qpn.mgmt_msg_head.status) {
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);
119 *global_qpn = cmd_qpn.base_qpn;
125 * hinic_set_mac - Init mac_vlan table in NIC.
128 * The hardware interface of a nic device.
132 * Set 0 for mac_vlan table initialization.
134 * Global function id of NIC.
138 * negative error value otherwise.
140 int hinic_set_mac(void *hwdev, u8 *mac_addr, u16 vlan_id, u16 func_id)
142 struct hinic_port_mac_set mac_info;
143 u16 out_size = sizeof(mac_info);
146 if (!hwdev || !mac_addr) {
147 PMD_DRV_LOG(ERR, "Hwdev or mac_addr is NULL");
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);
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);
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;
175 * hinic_del_mac - Uninit mac_vlan table in NIC.
178 * The hardware interface of a nic device.
182 * Set 0 for mac_vlan table initialization.
184 * Global function id of NIC.
188 * negative error value otherwise.
190 int hinic_del_mac(void *hwdev, u8 *mac_addr, u16 vlan_id, u16 func_id)
192 struct hinic_port_mac_set mac_info;
193 u16 out_size = sizeof(mac_info);
196 if (!hwdev || !mac_addr) {
197 PMD_DRV_LOG(ERR, "Hwdev or mac_addr is NULL");
201 if (vlan_id >= VLAN_N_VID) {
202 PMD_DRV_LOG(ERR, "Invalid VLAN number");
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);
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);
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;
229 * hinic_get_default_mac - Get default mac address from hardware.
232 * The hardware interface of a nic device.
238 * negative error value otherwise.
240 int hinic_get_default_mac(void *hwdev, u8 *mac_addr)
242 struct hinic_port_mac_set mac_info;
243 u16 out_size = sizeof(mac_info);
246 if (!hwdev || !mac_addr) {
247 PMD_DRV_LOG(ERR, "Hwdev or mac_addr is NULL");
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);
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);
264 memmove(mac_addr, mac_info.mac, ETH_ALEN);
270 * hinic_update_mac - Update mac address to hardware.
273 * The hardware interface of a nic device.
279 * Set 0 for mac_vlan table initialization.
281 * Global function id of NIC.
285 * negative error value otherwise.
287 int hinic_update_mac(void *hwdev, u8 *old_mac, u8 *new_mac, u16 vlan_id,
290 struct hinic_port_mac_update mac_info;
291 u16 out_size = sizeof(mac_info);
294 if (!hwdev || !old_mac || !new_mac) {
295 PMD_DRV_LOG(ERR, "Hwdev, old_mac or new_mac is NULL\n");
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);
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);
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;
325 * hinic_set_port_mtu - Set MTU to port.
328 * The hardware interface of a nic device.
334 * negative error value otherwise.
336 int hinic_set_port_mtu(void *hwdev, u32 new_mtu)
338 struct hinic_mtu mtu_info;
339 u16 out_size = sizeof(mtu_info);
343 PMD_DRV_LOG(ERR, "Hwdev is NULL");
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;
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);
365 * hinic_add_remove_vlan - Add or remove vlan id to vlan elb table.
368 * The hardware interface of a nic device.
372 * Global function id of NIC.
374 * Add or remove operation.
378 * negative error value otherwise.
380 int hinic_add_remove_vlan(void *hwdev, u16 vlan_id, u16 func_id, bool add)
382 struct hinic_vlan_config vlan_info;
383 u16 out_size = sizeof(vlan_info);
388 PMD_DRV_LOG(ERR, "Hwdev is NULL");
392 cmd = add ? HINIC_PORT_CMD_ADD_VLAN : HINIC_PORT_CMD_DEL_VLAN;
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;
399 err = l2nic_msg_to_mgmt_sync(hwdev, cmd, &vlan_info,
400 sizeof(vlan_info), &vlan_info,
402 if (err || !out_size || vlan_info.mgmt_msg_head.status) {
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);
414 * hinic_config_vlan_filter - Enable or Disable vlan filter.
417 * The hardware interface of a nic device.
418 * @param vlan_filter_ctrl
423 * negative error value otherwise.
425 int hinic_config_vlan_filter(void *hwdev, u32 vlan_filter_ctrl)
427 struct hinic_hwdev *nic_hwdev = (struct hinic_hwdev *)hwdev;
428 struct hinic_vlan_filter vlan_filter;
429 u16 out_size = sizeof(vlan_filter);
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;
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) {
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);
460 * hinic_set_rx_vlan_offload - Enable or Disable vlan offload.
463 * The hardware interface of a nic device.
469 * negative error value otherwise.
471 int hinic_set_rx_vlan_offload(void *hwdev, u8 en)
473 struct hinic_vlan_offload vlan_cfg;
474 u16 out_size = sizeof(vlan_cfg);
478 PMD_DRV_LOG(ERR, "Hwdev is NULL");
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;
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) {
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);
501 * hinic_get_link_status - Get link status from hardware.
504 * The hardware interface of a nic device.
510 * negative error value otherwise.
512 int hinic_get_link_status(void *hwdev, u8 *link_state)
514 struct hinic_get_link get_link;
515 u16 out_size = sizeof(get_link);
518 if (!hwdev || !link_state) {
519 PMD_DRV_LOG(ERR, "Hwdev or link_state is NULL");
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);
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);
536 *link_state = get_link.link_status;
542 * hinic_set_vport_enable - Notify firmware that driver is ready or not.
545 * The hardware interface of a nic device.
547 * 1: driver is ready; 0: driver is not ok.
551 * negative error value otherwise.
553 int hinic_set_vport_enable(void *hwdev, bool enable)
555 struct hinic_vport_state en_state;
556 u16 out_size = sizeof(en_state);
560 PMD_DRV_LOG(ERR, "Hwdev is NULL");
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);
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);
582 * hinic_set_port_enable - Open MAG to receive packets.
585 * The hardware interface of a nic device.
587 * 1: open MAG; 0: close MAG.
591 * negative error value otherwise.
593 int hinic_set_port_enable(void *hwdev, bool enable)
595 struct hinic_port_state en_state;
596 u16 out_size = sizeof(en_state);
600 PMD_DRV_LOG(ERR, "Hwdev is NULL");
604 if (HINIC_IS_VF((struct hinic_hwdev *)hwdev))
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);
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);
623 int hinic_get_port_info(void *hwdev, struct nic_port_info *port_info)
625 struct hinic_port_info port_msg;
626 u16 out_size = sizeof(port_msg);
629 if (!hwdev || !port_info) {
630 PMD_DRV_LOG(ERR, "Hwdev or port_info is NULL");
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);
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) {
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);
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;
657 int hinic_set_pause_config(void *hwdev, struct nic_pause_config nic_pause)
659 struct hinic_pause_config pause_info;
660 u16 out_size = sizeof(pause_info);
664 PMD_DRV_LOG(ERR, "Hwdev is NULL");
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;
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);
687 int hinic_dcb_set_ets(void *hwdev, u8 *up_tc, u8 *pg_bw,
688 u8 *pgid, u8 *up_bw, u8 *prio)
690 struct hinic_up_ets_cfg ets;
691 u16 out_size = sizeof(ets);
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");
701 for (i = 0; i < HINIC_DCB_TC_MAX; i++) {
702 up_bw_t += *(up_bw + i);
703 pg_bw_t += *(pg_bw + i);
705 if (*(up_tc + i) > HINIC_DCB_TC_MAX) {
707 "Invalid up %d mapping tc: %d", i,
713 if (pg_bw_t != 100 || (up_bw_t % 100) != 0) {
715 "Invalid pg_bw: %d or up_bw: %d", pg_bw_t, up_bw_t);
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);
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) {
732 "Failed to set ets, err: %d, status: 0x%x, out size: 0x%x",
733 err, ets.mgmt_msg_head.status, out_size);
740 int hinic_get_vport_stats(void *hwdev, struct hinic_vport_stats *stats)
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);
747 if (!hwdev || !stats) {
748 PMD_DRV_LOG(ERR, "Hwdev or stats is NULL");
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);
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) {
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);
769 memcpy(stats, &vport_stats_rsp.stats, sizeof(*stats));
774 int hinic_get_phy_port_stats(void *hwdev, struct hinic_phy_port_stats *stats)
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);
781 if (!hwdev || !stats) {
782 PMD_DRV_LOG(ERR, "Hwdev or stats is NULL");
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);
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) {
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);
802 memcpy(stats, &port_stats_rsp.stats, sizeof(*stats));
807 int hinic_set_rss_type(void *hwdev, u32 tmpl_idx, struct nic_rss_type rss_type)
809 struct nic_rss_context_tbl *ctx_tbl;
810 struct hinic_cmd_buf *cmd_buf;
816 PMD_DRV_LOG(ERR, "Hwdev is NULL");
820 cmd_buf = hinic_alloc_cmd_buf(hwdev);
822 PMD_DRV_LOG(ERR, "Failed to allocate cmd buf");
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);
836 cmd_buf->size = sizeof(struct nic_rss_context_tbl);
838 ctx_tbl = (struct nic_rss_context_tbl *)cmd_buf->buf;
839 ctx_tbl->group_index = cpu_to_be32(tmpl_idx);
841 ctx_tbl->size = sizeof(u32);
842 ctx_tbl->size = cpu_to_be32(ctx_tbl->size);
844 ctx_tbl->ctx = cpu_to_be32(ctx);
846 /* cfg the rss context table by command queue */
847 err = hinic_cmdq_direct_resp(hwdev, HINIC_ACK_TYPE_CMDQ,
849 HINIC_UCODE_CMD_SET_RSS_CONTEXT_TABLE,
850 cmd_buf, &out_param, 0);
852 hinic_free_cmd_buf(hwdev, cmd_buf);
854 if (err || out_param != 0) {
855 PMD_DRV_LOG(ERR, "Failed to set rss context table");
862 int hinic_get_rss_type(void *hwdev, u32 tmpl_idx, struct nic_rss_type *rss_type)
864 struct hinic_rss_context_table ctx_tbl;
865 u16 out_size = sizeof(ctx_tbl);
868 if (!hwdev || !rss_type) {
869 PMD_DRV_LOG(ERR, "Hwdev or rss_type is NULL");
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;
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) {
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);
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);
900 int hinic_rss_set_template_tbl(void *hwdev, u32 tmpl_idx, u8 *temp)
902 struct hinic_rss_template_key temp_key;
903 u16 out_size = sizeof(temp_key);
906 if (!hwdev || !temp) {
907 PMD_DRV_LOG(ERR, "Hwdev or temp is NULL");
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);
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) {
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);
930 int hinic_rss_get_template_tbl(void *hwdev, u32 tmpl_idx, u8 *temp)
932 struct hinic_rss_template_key temp_key;
933 u16 out_size = sizeof(temp_key);
936 if (!hwdev || !temp) {
937 PMD_DRV_LOG(ERR, "Hwdev or temp is NULL");
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;
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);
955 memcpy(temp, temp_key.key, HINIC_RSS_KEY_SIZE);
961 * hinic_rss_set_hash_engine - Init rss hash function.
964 * The hardware interface of a nic device.
966 * Index of rss template from NIC.
968 * Hash function, such as Toeplitz or XOR.
972 * negative error value otherwise.
974 int hinic_rss_set_hash_engine(void *hwdev, u8 tmpl_idx, u8 type)
976 struct hinic_rss_engine_type hash_type;
977 u16 out_size = sizeof(hash_type);
981 PMD_DRV_LOG(ERR, "Hwdev is NULL");
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;
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);
1003 int hinic_rss_set_indir_tbl(void *hwdev, u32 tmpl_idx, u32 *indir_table)
1005 struct nic_rss_indirect_tbl *indir_tbl;
1006 struct hinic_cmd_buf *cmd_buf;
1013 if (!hwdev || !indir_table) {
1014 PMD_DRV_LOG(ERR, "Hwdev or indir_table is NULL");
1018 cmd_buf = hinic_alloc_cmd_buf(hwdev);
1020 PMD_DRV_LOG(ERR, "Failed to allocate cmd buf");
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);
1028 for (i = 0; i < HINIC_RSS_INDIR_SIZE; i++) {
1029 indir_tbl->entry[i] = (u8)(*(indir_table + i));
1031 if (0x3 == (i & 0x3)) {
1032 temp = (u32 *)&indir_tbl->entry[i - 3];
1033 *temp = cpu_to_be32(*temp);
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);
1042 err = hinic_cmdq_direct_resp(hwdev, HINIC_ACK_TYPE_CMDQ,
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");
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);
1056 err = hinic_cmdq_direct_resp(hwdev, HINIC_ACK_TYPE_CMDQ,
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");
1066 hinic_free_cmd_buf(hwdev, cmd_buf);
1071 int hinic_rss_get_indir_tbl(void *hwdev, u32 tmpl_idx, u32 *indir_table)
1073 struct hinic_rss_indir_table rss_cfg;
1074 u16 out_size = sizeof(rss_cfg);
1077 if (!hwdev || !indir_table) {
1078 PMD_DRV_LOG(ERR, "Hwdev or indir_table is NULL");
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;
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,
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);
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];
1104 int hinic_rss_cfg(void *hwdev, u8 rss_en, u8 tmpl_idx, u8 tc_num, u8 *prio_tc)
1106 struct hinic_rss_config rss_cfg;
1107 u16 out_size = sizeof(rss_cfg);
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",
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;
1124 memcpy(rss_cfg.prio_tc, prio_tc, HINIC_DCB_UP_MAX);
1126 err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_RSS_CFG,
1127 &rss_cfg, sizeof(rss_cfg), &rss_cfg,
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);
1139 * hinic_rss_template_alloc - Get rss template id from the chip,
1140 * all functions share 96 templates.
1143 * The hardware interface of a nic device.
1145 * Index of rss template from chip.
1149 * negative error value otherwise.
1151 int hinic_rss_template_alloc(void *hwdev, u8 *tmpl_idx)
1153 struct hinic_rss_template_mgmt template_mgmt;
1154 u16 out_size = sizeof(template_mgmt);
1157 if (!hwdev || !tmpl_idx) {
1158 PMD_DRV_LOG(ERR, "Hwdev or tmpl_idx is NULL");
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;
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);
1176 *tmpl_idx = template_mgmt.template_id;
1182 * hinic_rss_template_free - Free rss template id to the chip.
1185 * The hardware interface of a nic device.
1187 * Index of rss template from chip.
1191 * negative error value otherwise.
1193 int hinic_rss_template_free(void *hwdev, u8 tmpl_idx)
1195 struct hinic_rss_template_mgmt template_mgmt;
1196 u16 out_size = sizeof(template_mgmt);
1200 PMD_DRV_LOG(ERR, "Hwdev is NULL");
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;
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);
1223 * hinic_set_rx_vhd_mode - Change rx buffer size after initialization.
1226 * The hardware interface of a nic device.
1230 * receive buffer size.
1234 * negative error value otherwise.
1236 int hinic_set_rx_vhd_mode(void *hwdev, u16 vhd_mode, u16 rx_buf_sz)
1238 struct hinic_set_vhd_mode vhd_mode_cfg;
1239 u16 out_size = sizeof(vhd_mode_cfg);
1243 PMD_DRV_LOG(ERR, "Hwdev is NULL");
1247 memset(&vhd_mode_cfg, 0, sizeof(vhd_mode_cfg));
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;
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) {
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);
1268 int hinic_set_rx_mode(void *hwdev, u32 enable)
1270 struct hinic_rx_mode_config rx_mode_cfg;
1271 u16 out_size = sizeof(rx_mode_cfg);
1275 PMD_DRV_LOG(ERR, "Hwdev is NULL");
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;
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);
1297 * hinic_get_mgmt_version - Get mgmt module version from chip.
1300 * The hardware interface of a nic device.
1306 * negative error value otherwise.
1308 int hinic_get_mgmt_version(void *hwdev, char *fw)
1310 struct hinic_version_info fw_ver;
1311 u16 out_size = sizeof(fw_ver);
1314 if (!hwdev || !fw) {
1315 PMD_DRV_LOG(ERR, "Hwdev or fw is NULL");
1319 memset(&fw_ver, 0, sizeof(fw_ver));
1320 fw_ver.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1322 err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_GET_MGMT_VERSION,
1323 &fw_ver, sizeof(fw_ver), &fw_ver,
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);
1331 snprintf(fw, HINIC_MGMT_VERSION_MAX_LEN, "%s", fw_ver.ver);
1336 int hinic_set_rx_csum_offload(void *hwdev, u32 en)
1338 struct hinic_checksum_offload rx_csum_cfg;
1339 u16 out_size = sizeof(rx_csum_cfg);
1343 PMD_DRV_LOG(ERR, "Hwdev is NULL");
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;
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) {
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);
1365 int hinic_set_rx_lro(void *hwdev, u8 ipv4_en, u8 ipv6_en, u8 max_wqe_num)
1367 struct hinic_lro_config lro_cfg;
1368 u16 out_size = sizeof(lro_cfg);
1372 PMD_DRV_LOG(ERR, "Hwdev is NULL");
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;
1383 err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_LRO,
1384 &lro_cfg, sizeof(lro_cfg), &lro_cfg,
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);
1395 int hinic_set_anti_attack(void *hwdev, bool enable)
1397 struct hinic_port_anti_attack_rate rate;
1398 u16 out_size = sizeof(rate);
1402 PMD_DRV_LOG(ERR, "Hwdev is NULL");
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;
1415 err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_SET_ANTI_ATTACK_RATE,
1416 &rate, sizeof(rate), &rate,
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);
1428 /* Set autoneg status and restart port link status */
1429 int hinic_reset_port_link_cfg(void *hwdev)
1431 struct hinic_reset_link_cfg reset_cfg;
1432 u16 out_size = sizeof(reset_cfg);
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);
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);
1452 * hinic_vf_func_init - Register VF to PF.
1455 * The hardware interface of a nic device.
1459 * negative error value otherwise.
1461 int hinic_vf_func_init(struct hinic_hwdev *hwdev)
1465 if (!HINIC_IS_VF(hwdev))
1468 err = hinic_mbox_to_pf(hwdev, HINIC_MOD_L2NIC,
1469 HINIC_PORT_CMD_VF_REGISTER, &state, sizeof(state),
1472 PMD_DRV_LOG(ERR, "Fail to register vf");
1480 * hinic_vf_func_free - Unregister VF from PF.
1483 * The hardware interface of a nic device.
1485 void hinic_vf_func_free(struct hinic_hwdev *hwdev)
1489 if (hinic_func_type(hwdev) != TYPE_VF)
1492 err = hinic_mbox_to_pf(hwdev, HINIC_MOD_L2NIC,
1493 HINIC_PORT_CMD_VF_UNREGISTER, &err, sizeof(err),
1496 PMD_DRV_LOG(ERR, "Fail to unregister VF, err: %d", err);
1499 int hinic_set_fast_recycle_mode(void *hwdev, u8 mode)
1501 struct hinic_fast_recycled_mode fast_recycled_mode;
1502 u16 out_size = sizeof(fast_recycled_mode);
1506 PMD_DRV_LOG(ERR, "Hwdev is NULL");
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;
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) {
1522 "Failed to set recycle mode, ret = %d",
1523 fast_recycled_mode.mgmt_msg_head.status);
1530 int hinic_clear_vport_stats(struct hinic_hwdev *hwdev)
1532 struct hinic_clear_vport_stats clear_vport_stats;
1533 u16 out_size = sizeof(clear_vport_stats);
1537 PMD_DRV_LOG(ERR, "Hwdev is NULL");
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);
1545 err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_CLEAN_VPORT_STAT,
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);
1558 int hinic_clear_phy_port_stats(struct hinic_hwdev *hwdev)
1560 struct hinic_clear_port_stats clear_phy_port_stats;
1561 u16 out_size = sizeof(clear_phy_port_stats);
1565 PMD_DRV_LOG(ERR, "Hwdev is NULL");
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);
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,
1588 int hinic_set_link_status_follow(void *hwdev,
1589 enum hinic_link_follow_status status)
1591 struct hinic_set_link_follow follow;
1592 u16 out_size = sizeof(follow);
1598 if (HINIC_IS_VF((struct hinic_hwdev *)hwdev))
1601 if (status >= HINIC_LINK_FOLLOW_STATUS_MAX) {
1603 "Invalid link follow status: %d", status);
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;
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) {
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);
1623 return follow.mgmt_msg_head.status;
1626 int hinic_get_link_mode(void *hwdev, u32 *supported, u32 *advertised)
1628 struct hinic_link_mode_cmd link_mode;
1629 u16 out_size = sizeof(link_mode);
1632 if (!hwdev || !supported || !advertised)
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);
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) {
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);
1649 *supported = link_mode.supported;
1650 *advertised = link_mode.advertised;
1656 * hinic_set_xsfp_tx_status - Enable or disable the fiber in
1657 * tx direction when set link up or down.
1660 * The hardware interface of a nic device.
1662 * Enable or Disable.
1666 * negative error value otherwise.
1668 int hinic_set_xsfp_tx_status(void *hwdev, bool enable)
1670 struct hinic_set_xsfp_status xsfp_status;
1671 u16 out_size = sizeof(struct hinic_set_xsfp_status);
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);
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) {
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);
1694 * hinic_flush_qp_res - Flush tx && rx chip resources in case of set vport
1695 * fake failed when device start.
1698 * The hardware interface of a nic device.
1702 * negative error value otherwise.
1704 int hinic_flush_qp_res(void *hwdev)
1706 struct hinic_clear_qp_resource qp_res;
1707 u16 out_size = sizeof(qp_res);
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);
1714 err = l2nic_msg_to_mgmt_sync(hwdev, HINIC_PORT_CMD_CLEAR_QP_RES,
1715 &qp_res, sizeof(qp_res), &qp_res,
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);
1727 * hinic_vf_get_default_cos - Get default cos of VF.
1730 * The hardware interface of a nic device.
1736 * negative error value otherwise.
1738 int hinic_vf_get_default_cos(struct hinic_hwdev *hwdev, u8 *cos_id)
1740 struct hinic_vf_default_cos vf_cos;
1741 u16 out_size = sizeof(vf_cos);
1744 memset(&vf_cos, 0, sizeof(vf_cos));
1745 vf_cos.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
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,
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);
1756 *cos_id = vf_cos.state.default_cos;
1762 * hinic_set_fdir_filter - Set fdir filter for control path
1763 * packet to notify firmware.
1766 * The hardware interface of a nic device.
1767 * @param filter_type
1768 * Packet type to filter.
1771 * @param type_enable
1772 * The status of pkt type filter.
1774 * Fdir function Enable or Disable.
1777 * negative error value otherwise.
1779 int hinic_set_fdir_filter(void *hwdev, u8 filter_type, u8 qid, u8 type_enable,
1782 struct hinic_port_qfilter_info port_filer_cmd;
1783 u16 out_size = sizeof(port_filer_cmd);
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;
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);
1813 * hinic_set_normal_filter - Set fdir filter for IO path packet.
1816 * The hardware interface of a nic device.
1819 * @param normal_type_enable
1820 * IO path packet function Enable or Disable
1822 * IO path packet filter key value, such as DIP from pkt.
1824 * Fdir function Enable or Disable.
1826 * Filter flag, such as dip or others.
1829 * negative error value otherwise.
1831 int hinic_set_normal_filter(void *hwdev, u8 qid, u8 normal_type_enable,
1832 u32 key, bool enable, u8 flag)
1834 struct hinic_port_qfilter_info port_filer_cmd;
1835 u16 out_size = sizeof(port_filer_cmd);
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;
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);
1865 * hinic_set_fdir_tcam - Set fdir filter for control packet
1866 * by tcam table to notify hardware.
1869 * The hardware interface of a nic device.
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.
1878 * negative error value otherwise.
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)
1884 struct hinic_fdir_tcam_info port_tcam_cmd;
1885 u16 out_size = sizeof(port_tcam_cmd);
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));
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);
1913 * hinic_clear_fdir_tcam - Clear fdir filter TCAM table for control packet.
1916 * The hardware interface of a nic device.
1921 * negative error value otherwise.
1923 int hinic_clear_fdir_tcam(void *hwdev, u16 type_mask)
1925 struct hinic_fdir_tcam_info port_tcam_cmd;
1926 u16 out_size = sizeof(port_tcam_cmd);
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;
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);